/** START DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/src/labplugin.js **/
jupyter.define('nglview-js-widgets@0.5.4-dev.2/src/labplugin.js', function (module, exports, __jupyter_require__) {
	var nglview = __jupyter_require__('nglview-js-widgets@0.5.4-dev.2/src/index.js');
	
	var jupyterlab_widgets = __jupyter_require__('@jupyterlab/nbwidgets@^0.6.15/lib/index.js');
	
	/**
	 * The widget manager provider.
	 */
	module.exports = {
	  id: 'jupyter.extensions.nglview',
	  requires: [jupyterlab_widgets.INBWidgetExtension],
	  activate: function(app, widgets) {
	      widgets.registerWidget({
	          name: 'nglview-js-widgets',
	          version: nglview.version,
	          exports: nglview
	      });
	    },
	  autoStart: true
	};
	
})
/** END DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/src/labplugin.js **/


/** START DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/src/index.js **/
jupyter.define('nglview-js-widgets@0.5.4-dev.2/src/index.js', function (module, exports, __jupyter_require__) {
	module.exports = {};
	
	var loadedModules = [
	    __jupyter_require__('nglview-js-widgets@0.5.4-dev.2/src/widget_ngl.js'),
	    //require("./ngl.js"),
	]
	
	for (var i in loadedModules) {
	    if (loadedModules.hasOwnProperty(i)) {
	        var loadedModule = loadedModules[i];
	        for (var target_name in loadedModule) {
	            if (loadedModule.hasOwnProperty(target_name)) {
	                module.exports[target_name] = loadedModule[target_name];
	            }
	        }
	    }
	}
	
	module.exports['version'] = __jupyter_require__('nglview-js-widgets@0.5.4-dev.2/package.json').version;
	
})
/** END DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/src/index.js **/


/** START DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/src/widget_ngl.js **/
jupyter.define('nglview-js-widgets@0.5.4-dev.2/src/widget_ngl.js', function (module, exports, __jupyter_require__) {
	var widgets = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/index.js');
	var NGL = __jupyter_require__('ngl@0.10.3/dist/ngl.js');
	var $ = __jupyter_require__('jquery@^2.1.4/dist/jquery.js');
	__jupyter_require__('jquery-ui@^1.12.1/ui/widgets/draggable.js');
	__jupyter_require__('jquery-ui@^1.12.1/ui/widgets/slider.js');
	__jupyter_require__('jquery-ui@^1.12.1/ui/widgets/dialog.js');
	
	var Jupyter;
	if (typeof window !== 'undefined') {
	  Jupyter = window['Jupyter'] = window['Jupyter'] || {};
	} else {
	  Jupyter = Jupyter || {};
	}
	
	var NGLView = widgets.DOMWidgetView.extend({
	
	    render: function() {
	
	        // init representations handling
	        this.model.on("change:_init_representations", this.representationsChanged, this);
	
	        // init setting of frame
	        this.model.on("change:frame", this.frameChanged, this);
	
	        // init setting of frame
	        this.model.on("change:count", this.countChanged, this);
	
	        // init _parameters handling
	        this.model.on("change:_parameters", this.parametersChanged, this);
	
	        // init orientation handling
	        this.model.on("change:orientation", this.orientationChanged, this);
	
	        // for player
	        this.delay = 100;
	        this.sync_frame = false;
	        this.sync_camera = false;
	
	        // get message from Python
	        this.model.on("msg:custom", function(msg) {
	            this.on_msg(msg);
	        }, this);
	
	        if (this.model.comm) {
	            // for embeding in website
	            this.model.comm.on_msg(function(msg) {
	                var buffers = msg.buffers;
	                var content = msg.content.data.content;
	                if (buffers.length && content) {
	                    content.buffers = buffers;
	                }
	                this.model._handle_comm_msg.call(this.model, msg);
	            }.bind(this));
	        }
	
	        // init NGL stage
	        NGL.useWorker = false;
	        this.stage = new NGL.Stage(undefined, {
	            backgroundColor: "white"
	        });
	        this.structureComponent = undefined;
	        this.$container = $(this.stage.viewer.container);
	        this.$el.append(this.$container);
	        this.$container.resizable({
	            resize: function(event, ui) {
	                this.setSize(ui.size.width + "px", ui.size.height + "px");
	            }.bind(this)
	        });
	        this.displayed.then(function() {
	            var width = this.$el.parent().width() + "px";
	            var height = "300px";
	
	            this.setSize(width, height);
	            this.$container.resizable(
	                "option", "maxWidth", this.$el.parent().width()
	            );
	            this.requestUpdateStageParameters();
	        }.bind(this));
	
	        this.stage.viewerControls.signals.changed.add(function() {
	            if (this.sync_camera) {
	                this.model.set('_scene_position', this.stage.viewerControls.position)
	                this.model.set('_scene_rotation', this.stage.viewerControls.rotation)
	                this.touch();
	            }
	        }.bind(this));
	
	        // init toggle fullscreen
	        $(this.stage.viewer.container).dblclick(function() {
	            this.stage.toggleFullscreen();
	        }.bind(this));
	
	        // init picking handling
	        this.$pickingInfo = $("<div></div>")
	            .css("position", "absolute")
	            .css("top", "5%")
	            .css("left", "3%")
	            .css("background-color", "white")
	            .css("padding", "2px 5px 2px 5px")
	            .css("opacity", "0.7")
	            .appendTo(this.$container);
	
	        var $inputNotebookCommand = $('<input id="input_notebook_command" type="text"></input>');
	        var that = this;
	
	        $inputNotebookCommand.keypress(function(e) {
	            var command = $("#input_notebook_command").val();
	            if (e.which == 13) {
	                $("#input_notebook_command").val("")
	                Jupyter.notebook.kernel.execute(command);
	            }
	        });
	
	        this.$notebook_text = $("<div></div>")
	            .css("position", "absolute")
	            .css("bottom", "5%")
	            .css("left", "3%")
	            .css("padding", "2px 5px 2px 5px")
	            .css("opacity", "0.7")
	            .append($inputNotebookCommand)
	            .appendTo(this.$container);
	        this.$notebook_text.hide();
	
	        this.stage.signals.clicked.add(function(pd) {
	            if (pd) {
	                var pd2 = {};
	                if (pd.atom) pd2.atom = pd.atom.toObject();
	                if (pd.bond) pd2.bond = pd.bond.toObject();
	                if (pd.instance) pd2.instance = pd.instance;
	                this.model.set("picked", pd2);
	                this.touch();
	                var pickingText = "";
	                if (pd.atom) {
	                    pickingText = "Atom: " + pd.atom.qualifiedName();
	                } else if (pd.bond) {
	                    pickingText = "Bond: " + pd.bond.atom1.qualifiedName() + " - " + pd.bond.atom2.qualifiedName();
	                }
	                this.$pickingInfo.text(pickingText);
	            }
	        }, this);
	
	        this.initPlayer();
	
	        var container = this.stage.viewer.container;
	        that = this;
	        container.addEventListener('dragover', function(e) {
	            e.stopPropagation();
	            e.preventDefault();
	            e.dataTransfer.dropEffect = 'copy';
	        }, false);
	
	        container.addEventListener('drop', function(e) {
	            e.stopPropagation();
	            e.preventDefault();
	            var file = e.dataTransfer.files[0];
	
	            that.stage.loadFile(file).then(function(o){
	                that.makeDefaultRepr(o);
	                that._handle_loading_file_finished();
	            });
	            var numDroppedFiles = that.model.get("_n_dragged_files");
	            that.model.set("_n_dragged_files", numDroppedFiles + 1);
	            that.touch();
	        }, false);
	
	        that = this;
	        this.stage.signals.componentAdded.add(function() {
	            var len = this.stage.compList.length;
	            this.model.set("n_components", len);
	            this.touch();
	            var comp = this.stage.compList[len - 1];
	            comp.signals.representationRemoved.add(function() {
	                that.requestReprDict();
	            });
	            comp.signals.representationAdded.add(function() {
	                that.requestReprDict();
	            });
	        }, this);
	
	        this.stage.signals.componentRemoved.add(function() {
	            this.model.set("n_components", this.stage.compList.length);
	            this.touch();
	        }, this);
	
	        // for callbacks from Python
	        // must be after initializing NGL.Stage
	        this.send({
	            'type': 'request_loaded',
	            'data': true
	        })
	        var state_params = this.stage.getParameters();
	        this.model.set('_original_stage_parameters', state_params);
	        this.touch();
	    },
	
	    setSelector: function(selector_id) {
	        // id is uuid that will be set from Python
	        var selector = "<div class='" + selector_id + "'></div>";
	        this.$ngl_selector = $(selector)
	            .css("position", "absolute")
	            .css("bottom", "5%")
	            .css("left", "3%")
	            .css("padding", "2px 5px 2px 5px")
	            .css("opacity", "0.7")
	            .appendTo(this.$container);
	    },
	
	    setIPythonLikeCell: function() {
	        var cell = Jupyter.notebook.insert_cell_at_bottom();
	
	        var handler = function(event) {
	            var selected_cell = Jupyter.notebook.get_selected_cell();
	            if (selected_cell.cell_id === cell.cell_id) {
	                selected_cell.execute();
	                selected_cell.set_text('');
	            }
	            event; // to pass eslint
	            return false;
	        };
	
	        var action = {
	            help: 'run cell',
	            help_index: 'zz',
	            handler: handler
	        };
	
	        Jupyter.keyboard_manager.edit_shortcuts.add_shortcut('enter', action);
	    },
	
	    hideNotebookCommandBox: function() {
	        this.$notebook_text.hide();
	    },
	
	    showNotebookCommandBox: function() {
	        this.$notebook_text.show();
	    },
	
	    requestFrame: function() {
	        this.send({
	            'type': 'request_frame',
	            'data': 'frame'
	        });
	    },
	
	    requestUpdateStageParameters: function() {
	        var updated_params = this.stage.getParameters();
	        this.model.set('_full_stage_parameters', updated_params);
	        this.touch();
	    },
	
	    requestReprParameters: function(component_index, repr_index) {
	        var comp = this.stage.compList[component_index];
	        var repr = comp.reprList[repr_index];
	        var msg = repr.repr.getParameters();
	
	        if (msg) {
	            msg['name'] = repr.name;
	            this.send({
	                'type': 'repr_parameters',
	                'data': msg
	            });
	        }
	    },
	
	    requestReprDict: function() {
	        var n_components = this.stage.compList.length;
	        var msg = {};
	
	        for (var i = 0; i < n_components; i++) {
	            var comp = this.stage.compList[i];
	            msg['c' + i] = {};
	            var msgi = msg['c' + i];
	            for (var j = 0; j < comp.reprList.length; j++) {
	                var repr = comp.reprList[j];
	                msgi[j] = {};
	                msgi[j]['type'] = repr.name;
	                msgi[j]['params'] = repr.repr.getParameters();
	            }
	        }
	        this.send({
	            'type': 'repr_dict',
	            'data': msg
	        });
	    },
	
	    // setDraggable: function(params) {
	    //     if (params) {
	    //         this.$container.draggable(params);
	    //     } else {
	    //         this.$container.draggable();
	    //     }
	    // },
	    setDelay: function(delay) {
	        this.delay = delay;
	    },
	
	    setSyncFrame: function() {
	        this.sync_frame = true;
	    },
	
	    setUnSyncFrame: function() {
	        this.sync_frame = false;
	    },
	
	    setSyncCamera: function() {
	        this.sync_camera = true;
	    },
	
	    setUnSyncCamera: function() {
	        this.sync_camera = false;
	    },
	
	    viewXZPlane: function() {
	        var m = new NGL.Matrix4().makeRotationX( Math.PI / 2 );
	        var q = new NGL.Quaternion().setFromRotationMatrix( m );
	        this.stage.viewerControls.rotate( q );
	    },
	
	    makeDefaultRepr: function(o) {
	        var reprDefList = this.model.get("_init_representations");
	        reprDefList.forEach(function(reprDef) {
	            o.addRepresentation(reprDef.type, reprDef.params);
	        });
	
	        if (this.stage.compList.length < 2) {
	            o.autoView(100);
	        }
	    },
	
	
	    initPlayer: function() {
	        // init player
	        if (this.model.get("count")) {
	            var play = function() {
	                this.$playerButton.text("pause");
	                this.playerInterval = setInterval(function() {
	                    var frame = this.model.get("frame") + 1;
	                    var count = this.model.get("count");
	                    if (frame >= count) frame = 0;
	
	                    if (this.sync_frame) {
	                        this.model.set("frame", frame);
	                        this.touch();
	                    } else {
	                        this.requestFrame();
	                    }
	                }.bind(this), this.delay);
	            }.bind(this);
	            var pause = function() {
	                this.$playerButton.text("play");
	                if (this.playerInterval !== undefined) {
	                    clearInterval(this.playerInterval);
	                }
	            }.bind(this);
	            this.$playerButton = $("<button>play</button>")
	                .css("float", "left")
	                .css("width", "55px")
	                .css("opacity", "0.7")
	                .click(function(event) {
	                    if (this.$playerButton.text() === "play") {
	                        play();
	                    } else if (this.$playerButton.text() === "pause") {
	                        pause();
	                    }
	                    event; // to pass eslint
	                }.bind(this));
	            this.$playerSlider = $("<div></div>")
	                .css("margin-left", "70px")
	                .css("position", "relative")
	                .css("bottom", "-7px")
	                .slider({
	                    min: 0,
	                    max: this.model.get("count") - 1,
	                    slide: function(event, ui) {
	                        pause();
	                        this.model.set("frame", ui.value);
	                        this.touch();
	                    }.bind(this)
	                });
	            this.$player = $("<div></div>")
	                .css("position", "absolute")
	                .css("bottom", "5%")
	                .css("width", "94%")
	                .css("margin-left", "3%")
	                .css("opacity", "0.7")
	                .append(this.$playerButton)
	                .append(this.$playerSlider)
	                .appendTo(this.$container);
	            this.model.on("change:frame", function() {
	                this.$playerSlider.slider("value", this.model.get("frame"));
	            }, this);
	
	            if (this.model.get("count") < 2) {
	                this.$player.hide()
	            }
	        }
	    },
	
	    countChanged: function() {
	        var count = this.model.get("count");
	        this.$playerSlider.slider({
	            max: count - 1
	        });
	        if (this.model.get("count") > 1) {
	            this.$player.show()
	        }
	    },
	
	    representationsChanged: function() {
	        var representations = this.model.get("_init_representations");
	        var component;
	
	        for (var i = 0; i < this.stage.compList.length; i++) {
	            component = this.stage.compList[i];
	            if (representations && component) {
	                component.clearRepresentations();
	                representations.forEach(function(repr) {
	                    component.addRepresentation(repr.type, repr.params);
	                });
	            }
	        }
	    },
	
	    setVisibilityForRepr: function(component_index, repr_index, value) {
	        // value = True/False
	        var component = this.stage.compList[component_index];
	        var repr = component.reprList[repr_index];
	
	        if (repr) {
	            repr.setVisibility(value);
	        }
	    },
	
	    removeRepresentation: function(component_index, repr_index) {
	        var component = this.stage.compList[component_index];
	        var repr = component.reprList[repr_index]
	
	        if (repr) {
	            component.removeRepresentation(repr);
	            repr.dispose();
	        }
	    },
	
	    removeRepresentationsByName: function(repr_name, component_index) {
	        var component = this.stage.compList[component_index];
	
	        if (component) {
	            component.reprList.forEach(function(repr) {
	                if (repr.name == repr_name) {
	                    component.removeRepresentation(repr);
	                    repr.dispose();
	                }
	            })
	        }
	    },
	
	    updateRepresentationForComponent: function(repr_index, component_index, params) {
	        var component = this.stage.compList[component_index];
	        var repr = component.reprList[repr_index];
	        if (repr) {
	            repr.setParameters(params);
	        }
	    },
	
	    updateRepresentationsByName: function(repr_name, component_index, params) {
	        var component = this.stage.compList[component_index];
	
	        if (component) {
	            component.reprList.forEach(function(repr) {
	                if (repr.name == repr_name) {
	                    repr.setParameters(params);
	                }
	            })
	        }
	    },
	
	    setRepresentation: function(name, params, component_index, repr_index) {
	        var component = this.stage.compList[component_index];
	        var repr = component.reprList[repr_index];
	
	        if (repr) {
	            params['useWorker'] = false;
	            var new_repr = NGL.makeRepresentation(name, component.structure,
	                this.stage.viewer, params);
	            if (new_repr) {
	                repr.setRepresentation(new_repr);
	                repr.name = name;
	                component.reprList[repr_index] = repr;
	                this.requestReprDict();
	            }
	        }
	    },
	
	    setColorByResidue: function(colors, component_index, repr_index){
	        var repr = this.stage.compList[component_index].reprList[repr_index];
	        var schemeId = NGL.ColorMakerRegistry.addScheme(function(params){
	            this.atomColor = function(atom){
	                 var color = colors[atom.residueIndex];
	                 return color
	            };
	            params; // to pass eslint; ack;
	        });
	        repr.setColor(schemeId);
	    },
	
	    addShape: function(name, shapes) {
	        // shapes: List[Tuple[str, ...]]
	        // e.g: [('sphere', ...), ('cone', ...)]
	        var shape = new NGL.Shape(name);
	        var shape_dict = {
	            'sphere': shape.addSphere,
	            'ellipsoid': shape.addEllipsoid,
	            'cylinder': shape.addCylinder,
	            'cone': shape.addCone,
	            'mesh': shape.addMesh,
	            'arrow': shape.addArrow,
	            'label': shape.addLabel
	        };
	        for (var i = 0; i < shapes.length; i++) {
	            var shapes_i = shapes[i]
	            var shape_type = shapes_i[0];
	            var params = shapes_i.slice(1, shapes_i.length);
	            // e.g params = ('sphere', [ 0, 0, 9 ], [ 1, 0, 0 ], 1.5)
	
	            var func = shape_dict[shape_type];
	            console.log('func', func);
	            func.apply(shape, params);
	            // shape.func(params);
	        }
	        var shapeComp = this.stage.addComponentFromObject(shape);
	        shapeComp.addRepresentation("buffer");
	    },
	
	    replaceStructure: function(structure){
	         var blob = new Blob([structure.data], {type: "text/plain"});
	         var params = structure.params || {};
	         params.ext = structure.ext;
	         params.defaultRepresentation = false;
	         var comp = this.stage.compList[0];
	         var representations = comp.reprList.slice();
	         var old_orientation = this.stage.viewerControls.getOrientation();
	         var that = this;
	         this.stage.loadFile(blob, params).then(function(component) {
	             that.stage.viewerControls.orient(old_orientation);
	             representations.forEach(function(repr) {
	                 var repr_name = repr.name;
	                 var repr_params = repr.repr.getParameters();
	                 // Note: not using repr.repr.type, repr.repr.params
	                 // since seems to me that repr.repr.params won't return correct "sele"
	                 component.addRepresentation(repr_name, repr_params);
	             });
	             that.stage.removeComponent(comp);
	             that._handle_loading_file_finished();
	         });
	    },
	
	    superpose: function(cindex0, cindex1, align, sele0, sele1) {
	        // superpose two components with given params
	        var component0 = this.stage.compList[cindex0];
	        var component1 = this.stage.compList[cindex1];
	        component1.superpose(component0, align, sele0, sele1);
	    },
	
	    decode_base64: function(base64) {
	        // lightly adapted from Niklas
	
	        /*
	         * base64-arraybuffer
	         * https://github.com/niklasvh/base64-arraybuffer
	         *
	         * Copyright (c) 2012 Niklas von Hertzen
	         * Licensed under the MIT license.
	         */
	        var chars =
	            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	        var bufferLength = base64.length * 0.75,
	            len = base64.length,
	            i, p = 0,
	            encoded1, encoded2, encoded3, encoded4;
	
	        if (base64[base64.length - 1] === "=") {
	            bufferLength--;
	            if (base64[base64.length - 2] === "=") {
	                bufferLength--;
	            }
	        }
	
	        var arraybuffer = new ArrayBuffer(bufferLength),
	            bytes = new Uint8Array(arraybuffer);
	
	        for (i = 0; i < len; i += 4) {
	            encoded1 = chars.indexOf(base64[i]);
	            encoded2 = chars.indexOf(base64[i + 1]);
	            encoded3 = chars.indexOf(base64[i + 2]);
	            encoded4 = chars.indexOf(base64[i + 3]);
	
	            bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
	            bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
	            bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
	        }
	
	        return arraybuffer;
	    },
	
	    updateCoordinates: function(coordinates, model) {
	        // coordinates must be ArrayBuffer (use this.decode_base64)
	        var component = this.stage.compList[model];
	        if (coordinates && component) {
	            var coords = new Float32Array(coordinates);
	            component.structure.updatePosition(coords);
	            component.updateRepresentations({
	                "position": true
	            });
	        }
	    },
	
	    handleResize: function() {
	        this.$container.resizable({
	            resize: function(event, ui) {
	                this.setSize(ui.size.width + "px", ui.size.height + "px");
	            }.bind(this)
	        })
	    },
	
	    setSize: function(width, height) {
	        this.stage.viewer.container.style.width = width;
	        this.stage.viewer.container.style.height = height;
	        this.stage.handleResize();
	    },
	
	    openNotebookCommandDialog: function() {
	        var that = this;
	        var dialog = this.$notebook_text.dialog({
	            draggable: true,
	            resizable: true,
	            modal: false,
	            show: {
	                effect: "blind",
	                duration: 150
	            },
	            close: function(event, ui) {
	                that.$container.append(that.$notebook_text);
	                that.$notebook_text.dialog('destroy');
	                event; ui; // to pass eslint; ack;
	            },
	        });
	        dialog.css({
	            overflow: 'hidden'
	        });
	        dialog.prev('.ui-dialog-titlebar')
	            .css({
	                'background': 'transparent',
	                'border': 'none'
	            });
	        Jupyter.keyboard_manager.register_events(dialog);
	    },
	
	    setDialog: function() {
	        var $nb_container = Jupyter.notebook.container;
	        var that = this;
	        var dialog = this.$container.dialog({
	            title: "NGLView",
	            draggable: true,
	            resizable: true,
	            modal: false,
	            width: window.innerWidth - $nb_container.width() - $nb_container.offset().left - 50,
	            height: 'auto',
	            position: {
	                my: 'right',
	                at: 'right',
	                of: window
	            },
	            show: {
	                effect: "blind",
	                duration: 150
	            },
	            close: function(event, ui) {
	                that.$el.append(that.$container);
	                that.$container.dialog('destroy');
	                that.handleResize();
	                event; ui; // to pass eslint; ack;
	            },
	            resize: function(event, ui) {
	                that.stage.handleResize();
	                that.setSize(ui.size.width + "px", ui.size.height + "px");
	            }.bind(that),
	        });
	        dialog.css({
	            overflow: 'hidden'
	        });
	        dialog.prev('.ui-dialog-titlebar')
	            .css({
	                'background': 'transparent',
	                'border': 'none'
	            });
	    },
	
	    resizeNotebook: function(width) {
	        var $nb_container = Jupyter.notebook.container;
	        $nb_container.width(width);
	
	        if (this.$container.dialog) {
	            this.$container.dialog({
	                width: $nb_container.offset().left
	            });
	        }
	    },
	
	    parametersChanged: function() {
	        var _parameters = this.model.get("_parameters");
	        this.setParameters(_parameters);
	    },
	
	    setParameters: function(parameters) {
	        this.stage.setParameters(parameters);
	
	        // do not set _full_stage_parameters here
	        // or parameters will be never updated (not sure why) 
	        // use observe in python side
	        var updated_params = this.stage.getParameters();
	        this.send({
	            'type': 'stage_parameters',
	            'data': updated_params
	        })
	    },
	
	    orientationChanged: function() {
	        var orientation_list = this.model.get("orientation");
	        var mat4 = this.stage.viewerControls.getOrientation();
	        mat4.set(orientation_list);
	        this.stage.viewerControls.orient(mat4);
	    },
	
	    _downloadImage: function(filename, params) {
	        this.stage.makeImage(params).then(function(blob) {
	            NGL.download(blob, filename);
	        })
	    },
	
	    _exportImage: function(params) {
	        this.stage.makeImage(params).then(function(blob) {
	            var reader = new FileReader();
	            var arr_str;
	            reader.onload = function() {
	                arr_str = reader.result.replace("data:image/png;base64,", "");
	                this.model.set("_image_data", arr_str);
	                this.touch();
	            }.bind(this);
	            reader.readAsDataURL(blob);
	        }.bind(this));
	    },
	
	    cleanOutput: function() {
	
	        var cells = Jupyter.notebook.get_cells();
	
	        for (var i = 0; i < cells.length; i++) {
	            var cell = cells[i];
	            if (cell.output_area.outputs.length > 0) {
	                var out = cell.output_area.outputs[0];
	                if (out.output_type == 'display_data') {
	                    cell.clear_output();
	                }
	            }
	        }
	    },
	
	    _handle_loading_file_finished: function() {
	        this.send({'type': 'async_message', 'data': 'ok'});
	    },
	    
	    _handle_stage_loadFile: function(msg){
	            // args = [{'type': ..., 'data': ...}]
	         var args0 = msg.args[0];
	         var that = this;
	         if (args0.type == 'blob') {
	             var blob;
	             if (args0.binary) {
	                 var decoded_data = this.decode_base64(args0.data);
	                 blob = new Blob([decoded_data], {
	                     type: "application/octet-binary"
	                 });
	             } else {
	                 blob = new Blob([args0.data], {
	                     type: "text/plain"
	                 });
	             }
	             this.stage.loadFile(blob, msg.kwargs).then(function(o){
	                  that._handle_loading_file_finished();
	                  o; // to pass eslint; ack;
	             });
	         } else {
	             this.stage.loadFile(msg.args[0].data, msg.kwargs).then(function(o){
	                  that._handle_loading_file_finished();
	                  o; // to pass eslint; ack;
	             });
	         }
	    },
	
	    on_msg: function(msg) {
	        // TODO: re-organize
	        if (msg.type == 'call_method') {
	            var index, component, func, stage;
	            var new_args = msg.args.slice();
	            new_args.push(msg.kwargs);
	
	            switch (msg.target) {
	                case 'Stage':
	                    var stage_func = this.stage[msg.methodName];
	                    stage = this.stage;
	                    if (msg.methodName == 'screenshot') {
	                        NGL.screenshot(this.stage.viewer, msg.kwargs);
	                    } else if (msg.methodName == 'removeComponent') {
	                        index = msg.args[0];
	                        component = this.stage.compList[index];
	                        this.stage.removeComponent(component);
	                    } else if (msg.methodName == 'loadFile') {
	                        this._handle_stage_loadFile(msg);
	                    } else {
	                            stage_func.apply(stage, new_args);
	                    }
	                    break;
	                case 'Viewer':
	                    var viewer = this.stage.viewer;
	                    func = this.stage.viewer[msg.methodName];
	                    func.apply(viewer, new_args);
	                    break;
	                case 'viewerControls':
	                    var controls = this.stage.viewerControls;
	                    func = controls[msg.methodName];
	                    func.apply(controls, new_args);
	                    break;
	                case 'compList':
	                    index = msg['component_index'];
	                    component = this.stage.compList[index];
	                    func = component[msg.methodName];
	                    func.apply(component, new_args);
	                    break;
	                case 'StructureComponent':
	                    component = this.structureComponent;
	                    func = component[msg.methodName];
	                    func.apply(component, new_args);
	                    break;
	                case 'Widget':
	                    func = this[msg.methodName];
	                    if (func) {
	                        func.apply(this, new_args);
	                    } else {
	                        // send error message to Python?
	                        console.log('can not create func for ' + msg.methodName);
	                    }
	                    break;
	                case 'player':
	                    func = this.$player[msg.methodName];
	                    if (func) {
	                        func.apply(this.$player, new_args);
	                    } else {
	                        // send error message to Python?
	                        console.log('can not create func for ' + msg.methodName);
	                    }
	                    break;
	                case 'Representation':
	                    var component_index = msg['component_index'];
	                    var repr_index = msg['repr_index'];
	                    var repr = component.reprList[repr_index];
	                    component = this.stage.compList[component_index];
	                    func = repr[msg.methodName];
	                    if (repr && func) {
	                        func.apply(repr, new_args);
	                    }
	                    break;
	                default:
	                    console.log('there is no method for ' + msg.target);
	                    break;
	            }
	        } else if (msg.type == 'base64_single') {
	            var coordinatesDict = msg.data;
	            var keys = Object.keys(coordinatesDict);
	
	            for (var i = 0; i < keys.length; i++) {
	                var traj_index = keys[i];
	                var coordinates = this.decode_base64(coordinatesDict[traj_index]);
	                if (coordinates.byteLength > 0) {
	                    this.updateCoordinates(coordinates, traj_index);
	                }
	            }
	        } else if (msg.type == 'binary_single') {
	            var coordinateMeta = msg.data;
	            keys = Object.keys(coordinateMeta);
	
	            for (i = 0; i < keys.length; i++) {
	                traj_index = keys[i];
	                coordinates = new Float32Array(msg.buffers[i].buffer);
	                if (coordinates.byteLength > 0) {
	                    this.updateCoordinates(coordinates, traj_index);
	                }
	            }
	        } else if (msg.type == 'get') {
	            if (msg.data == 'camera') {
	                this.send(JSON.stringify(this.stage.viewer.camera));
	            } else if (msg.data == 'parameters') {
	                this.send(JSON.stringify(this.stage.parameters));
	            } else {
	                for (i = 0; i < this.stage.compList.length; i++) {
	                    console.log(this.stage.compList[i]);
	                }
	            }
	        }
	    },
	});
	
	var NGLBox = widgets.BoxView.extend({
	    initialize: function(parameters) {
	        widgets.BoxView.prototype.initialize.call(this, parameters);
	        this.$dialog = undefined;
	    },
	
	    render: function() {
	        this.model.on('change:_dialog', this.dialogCommandChanged, this);
	        this.model.on('change:_ngl_command', this.commandChanged, this);
	        widgets.BoxView.prototype.render.call(this);
	    },
	
	    dialogCommandChanged: function() {
	        var _dialog = this.model.get('_dialog');
	        if (_dialog == 'on') {
	            this.setDialog();
	        }
	    },
	
	    merge: function() {
	        // TODO: rename and add doc
	        console.log('calling merge');
	        var v0 = this.children_views.views[0];
	        var v1 = this.children_views.views[1];
	
	        v0.then(function(v00) {
	            v1.then(function(v11) {
	                v11.$el.appendTo(v00.$container)
	                    .css("position", "absolute")
	                    .css("bottom", "5%")
	                    .css("left", "3%")
	                    .css("padding", "2px 5px 2px 5px")
	            });
	        });
	    },
	
	    commandChanged: function() {
	        var cm = this.model.get('_ngl_command');
	        if (cm == 'merge') {
	            this.merge();
	        } else {
	            console.log("place holder");
	        }
	    },
	
	    setDialog: function() {
	        //var $node = $(this.$el.parent()[0]);
	        var $node = $(this.$el);
	        $node.addClass('jupyter-widgets');
	        $node.addClass('widget-container');
	        $node.addClass('widget-box');
	        var dialog = $node.dialog({
	            draggable: true,
	            resizable: true,
	            modal: false,
	            height: 'auto',
	            show: {
	                effect: "blind",
	                duration: 150
	            },
	        });
	        dialog.css({
	            overflow: 'hidden'
	        });
	        dialog.prev('.ui-dialog-titlebar')
	            .css({
	                'background': 'transparent',
	                'border': 'none'
	            });
	    },
	});
	
	module.exports = {
	    'NGLView': NGLView,
	    'NGL': NGL,
	    'NGLBox': NGLBox
	};
	
})
/** END DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/src/widget_ngl.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/index.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/manager-base.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_layout.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_style.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_link.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_bool.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_button.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_box.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_image.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_color.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_date.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/services-shim.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_int.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_float.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_controller.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selection.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selectioncontainer.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_string.js'));
	exports.version = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/package.json').version;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/index.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/manager-base.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/manager-base.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js');
	var widget_string_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_string.js');
	exports.PROTOCOL_VERSION = '2.0.0';
	/**
	 * Manager abstract base class
	 */
	var ManagerBase = (function () {
	    function ManagerBase() {
	        /**
	         * The comm target name to register
	         */
	        this.comm_target_name = 'jupyter.widget';
	        /**
	         * Dictionary of model ids and model instance promises
	         */
	        this._models = Object.create(null);
	    }
	    /**
	     * Display a view for a particular model.
	     */
	    ManagerBase.prototype.display_model = function (msg, model, options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        return this.create_view(model, options).then(function (view) { return _this.display_view(msg, view, options); }).catch(utils.reject('Could not create view', true));
	    };
	    ;
	    /**
	     * Modifies view options. Generally overloaded in custom widget manager
	     * implementations.
	     */
	    ManagerBase.prototype.setViewOptions = function (options) {
	        if (options === void 0) { options = {}; }
	        return options;
	    };
	    ;
	    /**
	     * Creates a promise for a view of a given model
	     *
	     * Make sure the view creation is not out of order with
	     * any state updates.
	     */
	    ManagerBase.prototype.create_view = function (model, options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        model.state_change = model.state_change.then(function () {
	            return _this.loadClass(model.get('_view_name'), model.get('_view_module'), model.get('_view_module_version')).then(function (ViewType) {
	                var view = new ViewType({
	                    model: model,
	                    options: _this.setViewOptions(options)
	                });
	                view.listenTo(model, 'destroy', view.remove);
	                return Promise.resolve(view.render()).then(function () { return view; });
	            }).catch(utils.reject('Could not create a view for model id ' + model.id, true));
	        });
	        var id = utils.uuid();
	        model.views[id] = model.state_change;
	        model.state_change.then(function (view) {
	            view.once('remove', function () { delete view.model.views[id]; }, _this);
	        });
	        return model.state_change;
	    };
	    ;
	    /**
	     * callback handlers specific to a view
	     */
	    ManagerBase.prototype.callbacks = function (view) {
	        return {};
	    };
	    ;
	    /**
	     * Get a promise for a model by model id.
	     */
	    ManagerBase.prototype.get_model = function (model_id) {
	        // TODO: Perhaps we should return a Promise.reject if the model is not
	        // found. Right now this isn't a true async function because it doesn't
	        // always return a promise.
	        return this._models[model_id];
	    };
	    ;
	    /**
	     * Handle when a comm is opened.
	     */
	    ManagerBase.prototype.handle_comm_open = function (comm, msg) {
	        var data = msg.content.data;
	        var buffer_paths = data.buffer_paths || [];
	        // Make sure the buffers are DataViews
	        var buffers = (msg.buffers || []).map(function (b) {
	            if (b instanceof DataView) {
	                return b;
	            }
	            else {
	                return new DataView(b instanceof ArrayBuffer ? b : b.buffer);
	            }
	        });
	        utils.put_buffers(data.state, buffer_paths, buffers);
	        return this.new_model({
	            model_name: data.state['_model_name'],
	            model_module: data.state['_model_module'],
	            model_module_version: data.state['_model_module_version'],
	            comm: comm
	        }, data.state).catch(utils.reject('Could not create a model.', true));
	    };
	    ;
	    /**
	     * Create a comm and new widget model.
	     * @param  options - same options as new_model but comm is not
	     *                          required and additional options are available.
	     * @param  serialized_state - serialized model attributes.
	     */
	    ManagerBase.prototype.new_widget = function (options, serialized_state) {
	        var _this = this;
	        if (serialized_state === void 0) { serialized_state = {}; }
	        var commPromise;
	        // If no comm is provided, a new comm is opened for the jupyter.widget
	        // target.
	        if (options.comm) {
	            commPromise = Promise.resolve(options.comm);
	        }
	        else {
	            commPromise = this._create_comm(this.comm_target_name, options.model_id, {
	                state: {
	                    _model_module: options.model_module,
	                    _model_module_version: options.model_module_version,
	                    _model_name: options.model_name,
	                    _view_module: options.view_module,
	                    _view_module_version: options.view_module_version,
	                    _view_name: options.view_name
	                },
	            });
	        }
	        // The options dictionary is copied since data will be added to it.
	        var options_clone = _.clone(options);
	        // Create the model. In the case where the comm promise is rejected a
	        // comm-less model is still created with the required model id.
	        return commPromise.then(function (comm) {
	            // Comm Promise Resolved.
	            options_clone.comm = comm;
	            var widget_model = _this.new_model(options_clone, serialized_state);
	            return widget_model.then(function (model) {
	                model.sync('create', model);
	                return model;
	            });
	        }, function () {
	            // Comm Promise Rejected.
	            if (!options_clone.model_id) {
	                options_clone.model_id = utils.uuid();
	            }
	            return _this.new_model(options_clone, serialized_state);
	        });
	    };
	    ;
	    /**
	     * Create and return a promise for a new widget model
	     *
	     * @param options - the options for creating the model.
	     * @param serialized_state - attribute values for the model.
	     *
	     * @example
	     * widget_manager.new_model({
	     *      model_name: 'IntSlider',
	     *      model_module: 'jupyter-js-widgets',
	     *      model_module_version: '3.0.0',
	     *      model_id: 'u-u-i-d'
	     * }).then((model) => { console.log('Create success!', model); },
	     *  (err) => {console.error(err)});
	     *
	     */
	    ManagerBase.prototype.new_model = function (options, serialized_state) {
	        if (serialized_state === void 0) { serialized_state = {}; }
	        var that = this;
	        var model_id;
	        if (options.model_id) {
	            model_id = options.model_id;
	        }
	        else if (options.comm) {
	            model_id = options.comm.comm_id;
	        }
	        else {
	            throw new Error('Neither comm nor model_id provided in options object. At least one must exist.');
	        }
	        var error_handler = function (error) {
	            var modelOptions = {
	                widget_manager: that,
	                model_id: model_id,
	                comm: options.comm,
	            };
	            var widget_model = new widget_string_1.HTMLModel({}, modelOptions);
	            widget_model.once('comm:close', function () {
	                delete that._models[model_id];
	            });
	            var placeholder = "<table style=\"width:100%\">\n                <thead>\n                    <tr>\n                        <th colspan=\"2\">\n                        Could not create model:\n                        </th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td>Model name</td>\n                        <td> " + options.model_name + " </td>\n                    </tr>\n                    <tr>\n                        <td>Model module</td>\n                        <td> " + options.model_module + " </td>\n                    </tr>\n                    <tr>\n                        <td>Model module version</td>\n                        <td> " + options.model_module_version + " </td>\n                    </tr>\n                <tbody>\n                <tfoot>\n                    <tr>\n                        <th colspan=\"2\">\n                        " + error.message + "\n                        </th>\n                    </tr>\n                </tfoot>\n                </table>";
	            widget_model.set('value', placeholder);
	            return widget_model;
	        };
	        var model_promise = this.loadClass(options.model_name, options.model_module, options.model_module_version).then(function (ModelType) {
	            try {
	                return ModelType._deserialize_state(serialized_state || {}, that)
	                    .then(function (attributes) {
	                    var modelOptions = {
	                        widget_manager: that,
	                        model_id: model_id,
	                        comm: options.comm,
	                    };
	                    var widget_model = new ModelType(attributes, modelOptions);
	                    widget_model.once('comm:close', function () {
	                        delete that._models[model_id];
	                    });
	                    widget_model.name = options.model_name;
	                    widget_model.module = options.model_module;
	                    return widget_model;
	                });
	            }
	            catch (error) {
	                error_handler(error); // error handler call if ModelType is undefined.
	            }
	        }, error_handler); // error handler call if module cannot be loaded.
	        this._models[model_id] = model_promise;
	        return model_promise;
	    };
	    ;
	    /**
	     * Close all widgets and empty the widget state.
	     * @return Promise that resolves when the widget state is cleared.
	     */
	    ManagerBase.prototype.clear_state = function () {
	        var _this = this;
	        return utils.resolvePromisesDict(this._models).then(function (models) {
	            Object.keys(models).forEach(function (id) { return models[id].close(); });
	            _this._models = {};
	        });
	    };
	    ;
	    /**
	     * Asynchronously get the state of the widget manager.
	     *
	     * This includes all of the widget models, and follows the format given in
	     * the jupyter-widgets-schema package.
	     *
	     * @param options - The options for what state to return.
	     * @returns Promise for a state dictionary
	     */
	    ManagerBase.prototype.get_state = function (options) {
	        if (options === void 0) { options = {}; }
	        return utils.resolvePromisesDict(this._models).then(function (models) {
	            var state = {};
	            Object.keys(models).forEach(function (model_id) {
	                var model = models[model_id];
	                var split = utils.remove_buffers(model.serialize(model.get_state(options.drop_defaults)));
	                var buffers = split.buffers.map(function (buffer, index) {
	                    return { data: utils.bufferToBase64(buffer), path: split.buffer_paths[index], encoding: 'base64' };
	                });
	                state[model_id] = {
	                    model_name: model.name,
	                    model_module: model.module,
	                    model_module_version: model.get('_model_module_version'),
	                    state: split.state
	                };
	                // To save space, only include the buffer key if we have buffers
	                if (buffers.length > 0) {
	                    state[model_id].buffers = buffers;
	                }
	            });
	            return { version_major: 2, version_minor: 0, state: state };
	        });
	    };
	    ;
	    /**
	     * Set the widget manager state.
	     *
	     * @param state - a Javascript object conforming to the application/vnd.jupyter.widget-state+json spec.
	     *
	     * Reconstructs all of the widget models in the state, merges that with the
	     * current manager state, and then attempts to redisplay the widgets in the
	     * state.
	     */
	    ManagerBase.prototype.set_state = function (state) {
	        var _this = this;
	        // Check to make sure that it's the same version we are parsing.
	        if (!(state.version_major && state.version_major <= 2)) {
	            throw "Unsupported widget state format";
	        }
	        var models = state.state;
	        // Recreate all the widget models for the given widget manager state.
	        var all_models = this._get_comm_info().then(function (live_comms) {
	            return Promise.all(Object.keys(models).map(function (model_id) {
	                // First put back the binary buffers
	                var decode = { 'base64': utils.base64ToBuffer, 'hex': utils.hexToBuffer };
	                var model = models[model_id];
	                var modelState = model.state;
	                if (model.buffers) {
	                    var bufferPaths = model.buffers.map(function (b) { return b.path; });
	                    // put_buffers expects buffers to be DataViews
	                    var buffers = model.buffers.map(function (b) { return new DataView(decode[b.encoding](b.data)); });
	                    utils.put_buffers(model.state, bufferPaths, buffers);
	                }
	                // If the model has already been created, set its state and then
	                // return it.
	                if (_this._models[model_id]) {
	                    return _this._models[model_id].then(function (model) {
	                        // deserialize state
	                        return model.constructor._deserialize_state(modelState || {}, _this).then(function (attributes) {
	                            model.set_state(attributes);
	                            return model;
	                        });
	                    });
	                }
	                var modelCreate = {
	                    model_id: model_id,
	                    model_name: model.model_name,
	                    model_module: model.model_module,
	                    model_module_version: model.model_module_version
	                };
	                if (live_comms.hasOwnProperty(model_id)) {
	                    return _this._create_comm(_this.comm_target_name, model_id).then(function (comm) {
	                        modelCreate.comm = comm;
	                        return _this.new_model(modelCreate);
	                    });
	                }
	                else {
	                    return _this.new_model(modelCreate, modelState);
	                }
	            }));
	        });
	        return all_models;
	    };
	    ;
	    return ManagerBase;
	}());
	exports.ManagerBase = ManagerBase;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/manager-base.js **/


/** START DEFINE BLOCK for underscore@1.8.3/underscore.js **/
jupyter.define('underscore@1.8.3/underscore.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;//     Underscore.js 1.8.3
	//     http://underscorejs.org
	//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	//     Underscore may be freely distributed under the MIT license.
	
	(function() {
	
	  // Baseline setup
	  // --------------
	
	  // Establish the root object, `window` in the browser, or `exports` on the server.
	  var root = this;
	
	  // Save the previous value of the `_` variable.
	  var previousUnderscore = root._;
	
	  // Save bytes in the minified (but not gzipped) version:
	  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
	
	  // Create quick reference variables for speed access to core prototypes.
	  var
	    push             = ArrayProto.push,
	    slice            = ArrayProto.slice,
	    toString         = ObjProto.toString,
	    hasOwnProperty   = ObjProto.hasOwnProperty;
	
	  // All **ECMAScript 5** native function implementations that we hope to use
	  // are declared here.
	  var
	    nativeIsArray      = Array.isArray,
	    nativeKeys         = Object.keys,
	    nativeBind         = FuncProto.bind,
	    nativeCreate       = Object.create;
	
	  // Naked function reference for surrogate-prototype-swapping.
	  var Ctor = function(){};
	
	  // Create a safe reference to the Underscore object for use below.
	  var _ = function(obj) {
	    if (obj instanceof _) return obj;
	    if (!(this instanceof _)) return new _(obj);
	    this._wrapped = obj;
	  };
	
	  // Export the Underscore object for **Node.js**, with
	  // backwards-compatibility for the old `require()` API. If we're in
	  // the browser, add `_` as a global object.
	  if (true) {
	    if (typeof module !== 'undefined' && module.exports) {
	      exports = module.exports = _;
	    }
	    exports._ = _;
	  } else {
	    root._ = _;
	  }
	
	  // Current version.
	  _.VERSION = '1.8.3';
	
	  // Internal function that returns an efficient (for current engines) version
	  // of the passed-in callback, to be repeatedly applied in other Underscore
	  // functions.
	  var optimizeCb = function(func, context, argCount) {
	    if (context === void 0) return func;
	    switch (argCount == null ? 3 : argCount) {
	      case 1: return function(value) {
	        return func.call(context, value);
	      };
	      case 2: return function(value, other) {
	        return func.call(context, value, other);
	      };
	      case 3: return function(value, index, collection) {
	        return func.call(context, value, index, collection);
	      };
	      case 4: return function(accumulator, value, index, collection) {
	        return func.call(context, accumulator, value, index, collection);
	      };
	    }
	    return function() {
	      return func.apply(context, arguments);
	    };
	  };
	
	  // A mostly-internal function to generate callbacks that can be applied
	  // to each element in a collection, returning the desired result — either
	  // identity, an arbitrary callback, a property matcher, or a property accessor.
	  var cb = function(value, context, argCount) {
	    if (value == null) return _.identity;
	    if (_.isFunction(value)) return optimizeCb(value, context, argCount);
	    if (_.isObject(value)) return _.matcher(value);
	    return _.property(value);
	  };
	  _.iteratee = function(value, context) {
	    return cb(value, context, Infinity);
	  };
	
	  // An internal function for creating assigner functions.
	  var createAssigner = function(keysFunc, undefinedOnly) {
	    return function(obj) {
	      var length = arguments.length;
	      if (length < 2 || obj == null) return obj;
	      for (var index = 1; index < length; index++) {
	        var source = arguments[index],
	            keys = keysFunc(source),
	            l = keys.length;
	        for (var i = 0; i < l; i++) {
	          var key = keys[i];
	          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
	        }
	      }
	      return obj;
	    };
	  };
	
	  // An internal function for creating a new object that inherits from another.
	  var baseCreate = function(prototype) {
	    if (!_.isObject(prototype)) return {};
	    if (nativeCreate) return nativeCreate(prototype);
	    Ctor.prototype = prototype;
	    var result = new Ctor;
	    Ctor.prototype = null;
	    return result;
	  };
	
	  var property = function(key) {
	    return function(obj) {
	      return obj == null ? void 0 : obj[key];
	    };
	  };
	
	  // Helper for collection methods to determine whether a collection
	  // should be iterated as an array or as an object
	  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
	  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
	  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
	  var getLength = property('length');
	  var isArrayLike = function(collection) {
	    var length = getLength(collection);
	    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
	  };
	
	  // Collection Functions
	  // --------------------
	
	  // The cornerstone, an `each` implementation, aka `forEach`.
	  // Handles raw objects in addition to array-likes. Treats all
	  // sparse array-likes as if they were dense.
	  _.each = _.forEach = function(obj, iteratee, context) {
	    iteratee = optimizeCb(iteratee, context);
	    var i, length;
	    if (isArrayLike(obj)) {
	      for (i = 0, length = obj.length; i < length; i++) {
	        iteratee(obj[i], i, obj);
	      }
	    } else {
	      var keys = _.keys(obj);
	      for (i = 0, length = keys.length; i < length; i++) {
	        iteratee(obj[keys[i]], keys[i], obj);
	      }
	    }
	    return obj;
	  };
	
	  // Return the results of applying the iteratee to each element.
	  _.map = _.collect = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length,
	        results = Array(length);
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      results[index] = iteratee(obj[currentKey], currentKey, obj);
	    }
	    return results;
	  };
	
	  // Create a reducing function iterating left or right.
	  function createReduce(dir) {
	    // Optimized iterator function as using arguments.length
	    // in the main function will deoptimize the, see #1991.
	    function iterator(obj, iteratee, memo, keys, index, length) {
	      for (; index >= 0 && index < length; index += dir) {
	        var currentKey = keys ? keys[index] : index;
	        memo = iteratee(memo, obj[currentKey], currentKey, obj);
	      }
	      return memo;
	    }
	
	    return function(obj, iteratee, memo, context) {
	      iteratee = optimizeCb(iteratee, context, 4);
	      var keys = !isArrayLike(obj) && _.keys(obj),
	          length = (keys || obj).length,
	          index = dir > 0 ? 0 : length - 1;
	      // Determine the initial value if none is provided.
	      if (arguments.length < 3) {
	        memo = obj[keys ? keys[index] : index];
	        index += dir;
	      }
	      return iterator(obj, iteratee, memo, keys, index, length);
	    };
	  }
	
	  // **Reduce** builds up a single result from a list of values, aka `inject`,
	  // or `foldl`.
	  _.reduce = _.foldl = _.inject = createReduce(1);
	
	  // The right-associative version of reduce, also known as `foldr`.
	  _.reduceRight = _.foldr = createReduce(-1);
	
	  // Return the first value which passes a truth test. Aliased as `detect`.
	  _.find = _.detect = function(obj, predicate, context) {
	    var key;
	    if (isArrayLike(obj)) {
	      key = _.findIndex(obj, predicate, context);
	    } else {
	      key = _.findKey(obj, predicate, context);
	    }
	    if (key !== void 0 && key !== -1) return obj[key];
	  };
	
	  // Return all the elements that pass a truth test.
	  // Aliased as `select`.
	  _.filter = _.select = function(obj, predicate, context) {
	    var results = [];
	    predicate = cb(predicate, context);
	    _.each(obj, function(value, index, list) {
	      if (predicate(value, index, list)) results.push(value);
	    });
	    return results;
	  };
	
	  // Return all the elements for which a truth test fails.
	  _.reject = function(obj, predicate, context) {
	    return _.filter(obj, _.negate(cb(predicate)), context);
	  };
	
	  // Determine whether all of the elements match a truth test.
	  // Aliased as `all`.
	  _.every = _.all = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (!predicate(obj[currentKey], currentKey, obj)) return false;
	    }
	    return true;
	  };
	
	  // Determine if at least one element in the object matches a truth test.
	  // Aliased as `any`.
	  _.some = _.any = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = !isArrayLike(obj) && _.keys(obj),
	        length = (keys || obj).length;
	    for (var index = 0; index < length; index++) {
	      var currentKey = keys ? keys[index] : index;
	      if (predicate(obj[currentKey], currentKey, obj)) return true;
	    }
	    return false;
	  };
	
	  // Determine if the array or object contains a given item (using `===`).
	  // Aliased as `includes` and `include`.
	  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
	    if (!isArrayLike(obj)) obj = _.values(obj);
	    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
	    return _.indexOf(obj, item, fromIndex) >= 0;
	  };
	
	  // Invoke a method (with arguments) on every item in a collection.
	  _.invoke = function(obj, method) {
	    var args = slice.call(arguments, 2);
	    var isFunc = _.isFunction(method);
	    return _.map(obj, function(value) {
	      var func = isFunc ? method : value[method];
	      return func == null ? func : func.apply(value, args);
	    });
	  };
	
	  // Convenience version of a common use case of `map`: fetching a property.
	  _.pluck = function(obj, key) {
	    return _.map(obj, _.property(key));
	  };
	
	  // Convenience version of a common use case of `filter`: selecting only objects
	  // containing specific `key:value` pairs.
	  _.where = function(obj, attrs) {
	    return _.filter(obj, _.matcher(attrs));
	  };
	
	  // Convenience version of a common use case of `find`: getting the first object
	  // containing specific `key:value` pairs.
	  _.findWhere = function(obj, attrs) {
	    return _.find(obj, _.matcher(attrs));
	  };
	
	  // Return the maximum element (or element-based computation).
	  _.max = function(obj, iteratee, context) {
	    var result = -Infinity, lastComputed = -Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value > result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };
	
	  // Return the minimum element (or element-based computation).
	  _.min = function(obj, iteratee, context) {
	    var result = Infinity, lastComputed = Infinity,
	        value, computed;
	    if (iteratee == null && obj != null) {
	      obj = isArrayLike(obj) ? obj : _.values(obj);
	      for (var i = 0, length = obj.length; i < length; i++) {
	        value = obj[i];
	        if (value < result) {
	          result = value;
	        }
	      }
	    } else {
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index, list) {
	        computed = iteratee(value, index, list);
	        if (computed < lastComputed || computed === Infinity && result === Infinity) {
	          result = value;
	          lastComputed = computed;
	        }
	      });
	    }
	    return result;
	  };
	
	  // Shuffle a collection, using the modern version of the
	  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
	  _.shuffle = function(obj) {
	    var set = isArrayLike(obj) ? obj : _.values(obj);
	    var length = set.length;
	    var shuffled = Array(length);
	    for (var index = 0, rand; index < length; index++) {
	      rand = _.random(0, index);
	      if (rand !== index) shuffled[index] = shuffled[rand];
	      shuffled[rand] = set[index];
	    }
	    return shuffled;
	  };
	
	  // Sample **n** random values from a collection.
	  // If **n** is not specified, returns a single random element.
	  // The internal `guard` argument allows it to work with `map`.
	  _.sample = function(obj, n, guard) {
	    if (n == null || guard) {
	      if (!isArrayLike(obj)) obj = _.values(obj);
	      return obj[_.random(obj.length - 1)];
	    }
	    return _.shuffle(obj).slice(0, Math.max(0, n));
	  };
	
	  // Sort the object's values by a criterion produced by an iteratee.
	  _.sortBy = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    return _.pluck(_.map(obj, function(value, index, list) {
	      return {
	        value: value,
	        index: index,
	        criteria: iteratee(value, index, list)
	      };
	    }).sort(function(left, right) {
	      var a = left.criteria;
	      var b = right.criteria;
	      if (a !== b) {
	        if (a > b || a === void 0) return 1;
	        if (a < b || b === void 0) return -1;
	      }
	      return left.index - right.index;
	    }), 'value');
	  };
	
	  // An internal function used for aggregate "group by" operations.
	  var group = function(behavior) {
	    return function(obj, iteratee, context) {
	      var result = {};
	      iteratee = cb(iteratee, context);
	      _.each(obj, function(value, index) {
	        var key = iteratee(value, index, obj);
	        behavior(result, value, key);
	      });
	      return result;
	    };
	  };
	
	  // Groups the object's values by a criterion. Pass either a string attribute
	  // to group by, or a function that returns the criterion.
	  _.groupBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key].push(value); else result[key] = [value];
	  });
	
	  // Indexes the object's values by a criterion, similar to `groupBy`, but for
	  // when you know that your index values will be unique.
	  _.indexBy = group(function(result, value, key) {
	    result[key] = value;
	  });
	
	  // Counts instances of an object that group by a certain criterion. Pass
	  // either a string attribute to count by, or a function that returns the
	  // criterion.
	  _.countBy = group(function(result, value, key) {
	    if (_.has(result, key)) result[key]++; else result[key] = 1;
	  });
	
	  // Safely create a real, live array from anything iterable.
	  _.toArray = function(obj) {
	    if (!obj) return [];
	    if (_.isArray(obj)) return slice.call(obj);
	    if (isArrayLike(obj)) return _.map(obj, _.identity);
	    return _.values(obj);
	  };
	
	  // Return the number of elements in an object.
	  _.size = function(obj) {
	    if (obj == null) return 0;
	    return isArrayLike(obj) ? obj.length : _.keys(obj).length;
	  };
	
	  // Split a collection into two arrays: one whose elements all satisfy the given
	  // predicate, and one whose elements all do not satisfy the predicate.
	  _.partition = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var pass = [], fail = [];
	    _.each(obj, function(value, key, obj) {
	      (predicate(value, key, obj) ? pass : fail).push(value);
	    });
	    return [pass, fail];
	  };
	
	  // Array Functions
	  // ---------------
	
	  // Get the first element of an array. Passing **n** will return the first N
	  // values in the array. Aliased as `head` and `take`. The **guard** check
	  // allows it to work with `_.map`.
	  _.first = _.head = _.take = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[0];
	    return _.initial(array, array.length - n);
	  };
	
	  // Returns everything but the last entry of the array. Especially useful on
	  // the arguments object. Passing **n** will return all the values in
	  // the array, excluding the last N.
	  _.initial = function(array, n, guard) {
	    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
	  };
	
	  // Get the last element of an array. Passing **n** will return the last N
	  // values in the array.
	  _.last = function(array, n, guard) {
	    if (array == null) return void 0;
	    if (n == null || guard) return array[array.length - 1];
	    return _.rest(array, Math.max(0, array.length - n));
	  };
	
	  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
	  // Especially useful on the arguments object. Passing an **n** will return
	  // the rest N values in the array.
	  _.rest = _.tail = _.drop = function(array, n, guard) {
	    return slice.call(array, n == null || guard ? 1 : n);
	  };
	
	  // Trim out all falsy values from an array.
	  _.compact = function(array) {
	    return _.filter(array, _.identity);
	  };
	
	  // Internal implementation of a recursive `flatten` function.
	  var flatten = function(input, shallow, strict, startIndex) {
	    var output = [], idx = 0;
	    for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
	      var value = input[i];
	      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
	        //flatten current level of array or arguments object
	        if (!shallow) value = flatten(value, shallow, strict);
	        var j = 0, len = value.length;
	        output.length += len;
	        while (j < len) {
	          output[idx++] = value[j++];
	        }
	      } else if (!strict) {
	        output[idx++] = value;
	      }
	    }
	    return output;
	  };
	
	  // Flatten out an array, either recursively (by default), or just one level.
	  _.flatten = function(array, shallow) {
	    return flatten(array, shallow, false);
	  };
	
	  // Return a version of the array that does not contain the specified value(s).
	  _.without = function(array) {
	    return _.difference(array, slice.call(arguments, 1));
	  };
	
	  // Produce a duplicate-free version of the array. If the array has already
	  // been sorted, you have the option of using a faster algorithm.
	  // Aliased as `unique`.
	  _.uniq = _.unique = function(array, isSorted, iteratee, context) {
	    if (!_.isBoolean(isSorted)) {
	      context = iteratee;
	      iteratee = isSorted;
	      isSorted = false;
	    }
	    if (iteratee != null) iteratee = cb(iteratee, context);
	    var result = [];
	    var seen = [];
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var value = array[i],
	          computed = iteratee ? iteratee(value, i, array) : value;
	      if (isSorted) {
	        if (!i || seen !== computed) result.push(value);
	        seen = computed;
	      } else if (iteratee) {
	        if (!_.contains(seen, computed)) {
	          seen.push(computed);
	          result.push(value);
	        }
	      } else if (!_.contains(result, value)) {
	        result.push(value);
	      }
	    }
	    return result;
	  };
	
	  // Produce an array that contains the union: each distinct element from all of
	  // the passed-in arrays.
	  _.union = function() {
	    return _.uniq(flatten(arguments, true, true));
	  };
	
	  // Produce an array that contains every item shared between all the
	  // passed-in arrays.
	  _.intersection = function(array) {
	    var result = [];
	    var argsLength = arguments.length;
	    for (var i = 0, length = getLength(array); i < length; i++) {
	      var item = array[i];
	      if (_.contains(result, item)) continue;
	      for (var j = 1; j < argsLength; j++) {
	        if (!_.contains(arguments[j], item)) break;
	      }
	      if (j === argsLength) result.push(item);
	    }
	    return result;
	  };
	
	  // Take the difference between one array and a number of other arrays.
	  // Only the elements present in just the first array will remain.
	  _.difference = function(array) {
	    var rest = flatten(arguments, true, true, 1);
	    return _.filter(array, function(value){
	      return !_.contains(rest, value);
	    });
	  };
	
	  // Zip together multiple lists into a single array -- elements that share
	  // an index go together.
	  _.zip = function() {
	    return _.unzip(arguments);
	  };
	
	  // Complement of _.zip. Unzip accepts an array of arrays and groups
	  // each array's elements on shared indices
	  _.unzip = function(array) {
	    var length = array && _.max(array, getLength).length || 0;
	    var result = Array(length);
	
	    for (var index = 0; index < length; index++) {
	      result[index] = _.pluck(array, index);
	    }
	    return result;
	  };
	
	  // Converts lists into objects. Pass either a single array of `[key, value]`
	  // pairs, or two parallel arrays of the same length -- one of keys, and one of
	  // the corresponding values.
	  _.object = function(list, values) {
	    var result = {};
	    for (var i = 0, length = getLength(list); i < length; i++) {
	      if (values) {
	        result[list[i]] = values[i];
	      } else {
	        result[list[i][0]] = list[i][1];
	      }
	    }
	    return result;
	  };
	
	  // Generator function to create the findIndex and findLastIndex functions
	  function createPredicateIndexFinder(dir) {
	    return function(array, predicate, context) {
	      predicate = cb(predicate, context);
	      var length = getLength(array);
	      var index = dir > 0 ? 0 : length - 1;
	      for (; index >= 0 && index < length; index += dir) {
	        if (predicate(array[index], index, array)) return index;
	      }
	      return -1;
	    };
	  }
	
	  // Returns the first index on an array-like that passes a predicate test
	  _.findIndex = createPredicateIndexFinder(1);
	  _.findLastIndex = createPredicateIndexFinder(-1);
	
	  // Use a comparator function to figure out the smallest index at which
	  // an object should be inserted so as to maintain order. Uses binary search.
	  _.sortedIndex = function(array, obj, iteratee, context) {
	    iteratee = cb(iteratee, context, 1);
	    var value = iteratee(obj);
	    var low = 0, high = getLength(array);
	    while (low < high) {
	      var mid = Math.floor((low + high) / 2);
	      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
	    }
	    return low;
	  };
	
	  // Generator function to create the indexOf and lastIndexOf functions
	  function createIndexFinder(dir, predicateFind, sortedIndex) {
	    return function(array, item, idx) {
	      var i = 0, length = getLength(array);
	      if (typeof idx == 'number') {
	        if (dir > 0) {
	            i = idx >= 0 ? idx : Math.max(idx + length, i);
	        } else {
	            length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
	        }
	      } else if (sortedIndex && idx && length) {
	        idx = sortedIndex(array, item);
	        return array[idx] === item ? idx : -1;
	      }
	      if (item !== item) {
	        idx = predicateFind(slice.call(array, i, length), _.isNaN);
	        return idx >= 0 ? idx + i : -1;
	      }
	      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
	        if (array[idx] === item) return idx;
	      }
	      return -1;
	    };
	  }
	
	  // Return the position of the first occurrence of an item in an array,
	  // or -1 if the item is not included in the array.
	  // If the array is large and already in sort order, pass `true`
	  // for **isSorted** to use binary search.
	  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
	  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
	
	  // Generate an integer Array containing an arithmetic progression. A port of
	  // the native Python `range()` function. See
	  // [the Python documentation](http://docs.python.org/library/functions.html#range).
	  _.range = function(start, stop, step) {
	    if (stop == null) {
	      stop = start || 0;
	      start = 0;
	    }
	    step = step || 1;
	
	    var length = Math.max(Math.ceil((stop - start) / step), 0);
	    var range = Array(length);
	
	    for (var idx = 0; idx < length; idx++, start += step) {
	      range[idx] = start;
	    }
	
	    return range;
	  };
	
	  // Function (ahem) Functions
	  // ------------------
	
	  // Determines whether to execute a function as a constructor
	  // or a normal function with the provided arguments
	  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
	    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
	    var self = baseCreate(sourceFunc.prototype);
	    var result = sourceFunc.apply(self, args);
	    if (_.isObject(result)) return result;
	    return self;
	  };
	
	  // Create a function bound to a given object (assigning `this`, and arguments,
	  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
	  // available.
	  _.bind = function(func, context) {
	    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
	    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
	    var args = slice.call(arguments, 2);
	    var bound = function() {
	      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
	    };
	    return bound;
	  };
	
	  // Partially apply a function by creating a version that has had some of its
	  // arguments pre-filled, without changing its dynamic `this` context. _ acts
	  // as a placeholder, allowing any combination of arguments to be pre-filled.
	  _.partial = function(func) {
	    var boundArgs = slice.call(arguments, 1);
	    var bound = function() {
	      var position = 0, length = boundArgs.length;
	      var args = Array(length);
	      for (var i = 0; i < length; i++) {
	        args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
	      }
	      while (position < arguments.length) args.push(arguments[position++]);
	      return executeBound(func, bound, this, this, args);
	    };
	    return bound;
	  };
	
	  // Bind a number of an object's methods to that object. Remaining arguments
	  // are the method names to be bound. Useful for ensuring that all callbacks
	  // defined on an object belong to it.
	  _.bindAll = function(obj) {
	    var i, length = arguments.length, key;
	    if (length <= 1) throw new Error('bindAll must be passed function names');
	    for (i = 1; i < length; i++) {
	      key = arguments[i];
	      obj[key] = _.bind(obj[key], obj);
	    }
	    return obj;
	  };
	
	  // Memoize an expensive function by storing its results.
	  _.memoize = function(func, hasher) {
	    var memoize = function(key) {
	      var cache = memoize.cache;
	      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
	      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
	      return cache[address];
	    };
	    memoize.cache = {};
	    return memoize;
	  };
	
	  // Delays a function for the given number of milliseconds, and then calls
	  // it with the arguments supplied.
	  _.delay = function(func, wait) {
	    var args = slice.call(arguments, 2);
	    return setTimeout(function(){
	      return func.apply(null, args);
	    }, wait);
	  };
	
	  // Defers a function, scheduling it to run after the current call stack has
	  // cleared.
	  _.defer = _.partial(_.delay, _, 1);
	
	  // Returns a function, that, when invoked, will only be triggered at most once
	  // during a given window of time. Normally, the throttled function will run
	  // as much as it can, without ever going more than once per `wait` duration;
	  // but if you'd like to disable the execution on the leading edge, pass
	  // `{leading: false}`. To disable execution on the trailing edge, ditto.
	  _.throttle = function(func, wait, options) {
	    var context, args, result;
	    var timeout = null;
	    var previous = 0;
	    if (!options) options = {};
	    var later = function() {
	      previous = options.leading === false ? 0 : _.now();
	      timeout = null;
	      result = func.apply(context, args);
	      if (!timeout) context = args = null;
	    };
	    return function() {
	      var now = _.now();
	      if (!previous && options.leading === false) previous = now;
	      var remaining = wait - (now - previous);
	      context = this;
	      args = arguments;
	      if (remaining <= 0 || remaining > wait) {
	        if (timeout) {
	          clearTimeout(timeout);
	          timeout = null;
	        }
	        previous = now;
	        result = func.apply(context, args);
	        if (!timeout) context = args = null;
	      } else if (!timeout && options.trailing !== false) {
	        timeout = setTimeout(later, remaining);
	      }
	      return result;
	    };
	  };
	
	  // Returns a function, that, as long as it continues to be invoked, will not
	  // be triggered. The function will be called after it stops being called for
	  // N milliseconds. If `immediate` is passed, trigger the function on the
	  // leading edge, instead of the trailing.
	  _.debounce = function(func, wait, immediate) {
	    var timeout, args, context, timestamp, result;
	
	    var later = function() {
	      var last = _.now() - timestamp;
	
	      if (last < wait && last >= 0) {
	        timeout = setTimeout(later, wait - last);
	      } else {
	        timeout = null;
	        if (!immediate) {
	          result = func.apply(context, args);
	          if (!timeout) context = args = null;
	        }
	      }
	    };
	
	    return function() {
	      context = this;
	      args = arguments;
	      timestamp = _.now();
	      var callNow = immediate && !timeout;
	      if (!timeout) timeout = setTimeout(later, wait);
	      if (callNow) {
	        result = func.apply(context, args);
	        context = args = null;
	      }
	
	      return result;
	    };
	  };
	
	  // Returns the first function passed as an argument to the second,
	  // allowing you to adjust arguments, run code before and after, and
	  // conditionally execute the original function.
	  _.wrap = function(func, wrapper) {
	    return _.partial(wrapper, func);
	  };
	
	  // Returns a negated version of the passed-in predicate.
	  _.negate = function(predicate) {
	    return function() {
	      return !predicate.apply(this, arguments);
	    };
	  };
	
	  // Returns a function that is the composition of a list of functions, each
	  // consuming the return value of the function that follows.
	  _.compose = function() {
	    var args = arguments;
	    var start = args.length - 1;
	    return function() {
	      var i = start;
	      var result = args[start].apply(this, arguments);
	      while (i--) result = args[i].call(this, result);
	      return result;
	    };
	  };
	
	  // Returns a function that will only be executed on and after the Nth call.
	  _.after = function(times, func) {
	    return function() {
	      if (--times < 1) {
	        return func.apply(this, arguments);
	      }
	    };
	  };
	
	  // Returns a function that will only be executed up to (but not including) the Nth call.
	  _.before = function(times, func) {
	    var memo;
	    return function() {
	      if (--times > 0) {
	        memo = func.apply(this, arguments);
	      }
	      if (times <= 1) func = null;
	      return memo;
	    };
	  };
	
	  // Returns a function that will be executed at most one time, no matter how
	  // often you call it. Useful for lazy initialization.
	  _.once = _.partial(_.before, 2);
	
	  // Object Functions
	  // ----------------
	
	  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
	  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
	  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
	                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
	
	  function collectNonEnumProps(obj, keys) {
	    var nonEnumIdx = nonEnumerableProps.length;
	    var constructor = obj.constructor;
	    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
	
	    // Constructor is a special case.
	    var prop = 'constructor';
	    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
	
	    while (nonEnumIdx--) {
	      prop = nonEnumerableProps[nonEnumIdx];
	      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
	        keys.push(prop);
	      }
	    }
	  }
	
	  // Retrieve the names of an object's own properties.
	  // Delegates to **ECMAScript 5**'s native `Object.keys`
	  _.keys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    if (nativeKeys) return nativeKeys(obj);
	    var keys = [];
	    for (var key in obj) if (_.has(obj, key)) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };
	
	  // Retrieve all the property names of an object.
	  _.allKeys = function(obj) {
	    if (!_.isObject(obj)) return [];
	    var keys = [];
	    for (var key in obj) keys.push(key);
	    // Ahem, IE < 9.
	    if (hasEnumBug) collectNonEnumProps(obj, keys);
	    return keys;
	  };
	
	  // Retrieve the values of an object's properties.
	  _.values = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var values = Array(length);
	    for (var i = 0; i < length; i++) {
	      values[i] = obj[keys[i]];
	    }
	    return values;
	  };
	
	  // Returns the results of applying the iteratee to each element of the object
	  // In contrast to _.map it returns an object
	  _.mapObject = function(obj, iteratee, context) {
	    iteratee = cb(iteratee, context);
	    var keys =  _.keys(obj),
	          length = keys.length,
	          results = {},
	          currentKey;
	      for (var index = 0; index < length; index++) {
	        currentKey = keys[index];
	        results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
	      }
	      return results;
	  };
	
	  // Convert an object into a list of `[key, value]` pairs.
	  _.pairs = function(obj) {
	    var keys = _.keys(obj);
	    var length = keys.length;
	    var pairs = Array(length);
	    for (var i = 0; i < length; i++) {
	      pairs[i] = [keys[i], obj[keys[i]]];
	    }
	    return pairs;
	  };
	
	  // Invert the keys and values of an object. The values must be serializable.
	  _.invert = function(obj) {
	    var result = {};
	    var keys = _.keys(obj);
	    for (var i = 0, length = keys.length; i < length; i++) {
	      result[obj[keys[i]]] = keys[i];
	    }
	    return result;
	  };
	
	  // Return a sorted list of the function names available on the object.
	  // Aliased as `methods`
	  _.functions = _.methods = function(obj) {
	    var names = [];
	    for (var key in obj) {
	      if (_.isFunction(obj[key])) names.push(key);
	    }
	    return names.sort();
	  };
	
	  // Extend a given object with all the properties in passed-in object(s).
	  _.extend = createAssigner(_.allKeys);
	
	  // Assigns a given object with all the own properties in the passed-in object(s)
	  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
	  _.extendOwn = _.assign = createAssigner(_.keys);
	
	  // Returns the first key on an object that passes a predicate test
	  _.findKey = function(obj, predicate, context) {
	    predicate = cb(predicate, context);
	    var keys = _.keys(obj), key;
	    for (var i = 0, length = keys.length; i < length; i++) {
	      key = keys[i];
	      if (predicate(obj[key], key, obj)) return key;
	    }
	  };
	
	  // Return a copy of the object only containing the whitelisted properties.
	  _.pick = function(object, oiteratee, context) {
	    var result = {}, obj = object, iteratee, keys;
	    if (obj == null) return result;
	    if (_.isFunction(oiteratee)) {
	      keys = _.allKeys(obj);
	      iteratee = optimizeCb(oiteratee, context);
	    } else {
	      keys = flatten(arguments, false, false, 1);
	      iteratee = function(value, key, obj) { return key in obj; };
	      obj = Object(obj);
	    }
	    for (var i = 0, length = keys.length; i < length; i++) {
	      var key = keys[i];
	      var value = obj[key];
	      if (iteratee(value, key, obj)) result[key] = value;
	    }
	    return result;
	  };
	
	   // Return a copy of the object without the blacklisted properties.
	  _.omit = function(obj, iteratee, context) {
	    if (_.isFunction(iteratee)) {
	      iteratee = _.negate(iteratee);
	    } else {
	      var keys = _.map(flatten(arguments, false, false, 1), String);
	      iteratee = function(value, key) {
	        return !_.contains(keys, key);
	      };
	    }
	    return _.pick(obj, iteratee, context);
	  };
	
	  // Fill in a given object with default properties.
	  _.defaults = createAssigner(_.allKeys, true);
	
	  // Creates an object that inherits from the given prototype object.
	  // If additional properties are provided then they will be added to the
	  // created object.
	  _.create = function(prototype, props) {
	    var result = baseCreate(prototype);
	    if (props) _.extendOwn(result, props);
	    return result;
	  };
	
	  // Create a (shallow-cloned) duplicate of an object.
	  _.clone = function(obj) {
	    if (!_.isObject(obj)) return obj;
	    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
	  };
	
	  // Invokes interceptor with the obj, and then returns obj.
	  // The primary purpose of this method is to "tap into" a method chain, in
	  // order to perform operations on intermediate results within the chain.
	  _.tap = function(obj, interceptor) {
	    interceptor(obj);
	    return obj;
	  };
	
	  // Returns whether an object has a given set of `key:value` pairs.
	  _.isMatch = function(object, attrs) {
	    var keys = _.keys(attrs), length = keys.length;
	    if (object == null) return !length;
	    var obj = Object(object);
	    for (var i = 0; i < length; i++) {
	      var key = keys[i];
	      if (attrs[key] !== obj[key] || !(key in obj)) return false;
	    }
	    return true;
	  };
	
	
	  // Internal recursive comparison function for `isEqual`.
	  var eq = function(a, b, aStack, bStack) {
	    // Identical objects are equal. `0 === -0`, but they aren't identical.
	    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
	    if (a === b) return a !== 0 || 1 / a === 1 / b;
	    // A strict comparison is necessary because `null == undefined`.
	    if (a == null || b == null) return a === b;
	    // Unwrap any wrapped objects.
	    if (a instanceof _) a = a._wrapped;
	    if (b instanceof _) b = b._wrapped;
	    // Compare `[[Class]]` names.
	    var className = toString.call(a);
	    if (className !== toString.call(b)) return false;
	    switch (className) {
	      // Strings, numbers, regular expressions, dates, and booleans are compared by value.
	      case '[object RegExp]':
	      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
	      case '[object String]':
	        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
	        // equivalent to `new String("5")`.
	        return '' + a === '' + b;
	      case '[object Number]':
	        // `NaN`s are equivalent, but non-reflexive.
	        // Object(NaN) is equivalent to NaN
	        if (+a !== +a) return +b !== +b;
	        // An `egal` comparison is performed for other numeric values.
	        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
	      case '[object Date]':
	      case '[object Boolean]':
	        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
	        // millisecond representations. Note that invalid dates with millisecond representations
	        // of `NaN` are not equivalent.
	        return +a === +b;
	    }
	
	    var areArrays = className === '[object Array]';
	    if (!areArrays) {
	      if (typeof a != 'object' || typeof b != 'object') return false;
	
	      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
	      // from different frames are.
	      var aCtor = a.constructor, bCtor = b.constructor;
	      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
	                               _.isFunction(bCtor) && bCtor instanceof bCtor)
	                          && ('constructor' in a && 'constructor' in b)) {
	        return false;
	      }
	    }
	    // Assume equality for cyclic structures. The algorithm for detecting cyclic
	    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
	
	    // Initializing stack of traversed objects.
	    // It's done here since we only need them for objects and arrays comparison.
	    aStack = aStack || [];
	    bStack = bStack || [];
	    var length = aStack.length;
	    while (length--) {
	      // Linear search. Performance is inversely proportional to the number of
	      // unique nested structures.
	      if (aStack[length] === a) return bStack[length] === b;
	    }
	
	    // Add the first object to the stack of traversed objects.
	    aStack.push(a);
	    bStack.push(b);
	
	    // Recursively compare objects and arrays.
	    if (areArrays) {
	      // Compare array lengths to determine if a deep comparison is necessary.
	      length = a.length;
	      if (length !== b.length) return false;
	      // Deep compare the contents, ignoring non-numeric properties.
	      while (length--) {
	        if (!eq(a[length], b[length], aStack, bStack)) return false;
	      }
	    } else {
	      // Deep compare objects.
	      var keys = _.keys(a), key;
	      length = keys.length;
	      // Ensure that both objects contain the same number of properties before comparing deep equality.
	      if (_.keys(b).length !== length) return false;
	      while (length--) {
	        // Deep compare each member
	        key = keys[length];
	        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
	      }
	    }
	    // Remove the first object from the stack of traversed objects.
	    aStack.pop();
	    bStack.pop();
	    return true;
	  };
	
	  // Perform a deep comparison to check if two objects are equal.
	  _.isEqual = function(a, b) {
	    return eq(a, b);
	  };
	
	  // Is a given array, string, or object empty?
	  // An "empty" object has no enumerable own-properties.
	  _.isEmpty = function(obj) {
	    if (obj == null) return true;
	    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
	    return _.keys(obj).length === 0;
	  };
	
	  // Is a given value a DOM element?
	  _.isElement = function(obj) {
	    return !!(obj && obj.nodeType === 1);
	  };
	
	  // Is a given value an array?
	  // Delegates to ECMA5's native Array.isArray
	  _.isArray = nativeIsArray || function(obj) {
	    return toString.call(obj) === '[object Array]';
	  };
	
	  // Is a given variable an object?
	  _.isObject = function(obj) {
	    var type = typeof obj;
	    return type === 'function' || type === 'object' && !!obj;
	  };
	
	  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
	  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
	    _['is' + name] = function(obj) {
	      return toString.call(obj) === '[object ' + name + ']';
	    };
	  });
	
	  // Define a fallback version of the method in browsers (ahem, IE < 9), where
	  // there isn't any inspectable "Arguments" type.
	  if (!_.isArguments(arguments)) {
	    _.isArguments = function(obj) {
	      return _.has(obj, 'callee');
	    };
	  }
	
	  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
	  // IE 11 (#1621), and in Safari 8 (#1929).
	  if (typeof /./ != 'function' && typeof Int8Array != 'object') {
	    _.isFunction = function(obj) {
	      return typeof obj == 'function' || false;
	    };
	  }
	
	  // Is a given object a finite number?
	  _.isFinite = function(obj) {
	    return isFinite(obj) && !isNaN(parseFloat(obj));
	  };
	
	  // Is the given value `NaN`? (NaN is the only number which does not equal itself).
	  _.isNaN = function(obj) {
	    return _.isNumber(obj) && obj !== +obj;
	  };
	
	  // Is a given value a boolean?
	  _.isBoolean = function(obj) {
	    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
	  };
	
	  // Is a given value equal to null?
	  _.isNull = function(obj) {
	    return obj === null;
	  };
	
	  // Is a given variable undefined?
	  _.isUndefined = function(obj) {
	    return obj === void 0;
	  };
	
	  // Shortcut function for checking if an object has a given property directly
	  // on itself (in other words, not on a prototype).
	  _.has = function(obj, key) {
	    return obj != null && hasOwnProperty.call(obj, key);
	  };
	
	  // Utility Functions
	  // -----------------
	
	  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
	  // previous owner. Returns a reference to the Underscore object.
	  _.noConflict = function() {
	    root._ = previousUnderscore;
	    return this;
	  };
	
	  // Keep the identity function around for default iteratees.
	  _.identity = function(value) {
	    return value;
	  };
	
	  // Predicate-generating functions. Often useful outside of Underscore.
	  _.constant = function(value) {
	    return function() {
	      return value;
	    };
	  };
	
	  _.noop = function(){};
	
	  _.property = property;
	
	  // Generates a function for a given object that returns a given property.
	  _.propertyOf = function(obj) {
	    return obj == null ? function(){} : function(key) {
	      return obj[key];
	    };
	  };
	
	  // Returns a predicate for checking whether an object has a given set of
	  // `key:value` pairs.
	  _.matcher = _.matches = function(attrs) {
	    attrs = _.extendOwn({}, attrs);
	    return function(obj) {
	      return _.isMatch(obj, attrs);
	    };
	  };
	
	  // Run a function **n** times.
	  _.times = function(n, iteratee, context) {
	    var accum = Array(Math.max(0, n));
	    iteratee = optimizeCb(iteratee, context, 1);
	    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
	    return accum;
	  };
	
	  // Return a random integer between min and max (inclusive).
	  _.random = function(min, max) {
	    if (max == null) {
	      max = min;
	      min = 0;
	    }
	    return min + Math.floor(Math.random() * (max - min + 1));
	  };
	
	  // A (possibly faster) way to get the current timestamp as an integer.
	  _.now = Date.now || function() {
	    return new Date().getTime();
	  };
	
	   // List of HTML entities for escaping.
	  var escapeMap = {
	    '&': '&amp;',
	    '<': '&lt;',
	    '>': '&gt;',
	    '"': '&quot;',
	    "'": '&#x27;',
	    '`': '&#x60;'
	  };
	  var unescapeMap = _.invert(escapeMap);
	
	  // Functions for escaping and unescaping strings to/from HTML interpolation.
	  var createEscaper = function(map) {
	    var escaper = function(match) {
	      return map[match];
	    };
	    // Regexes for identifying a key that needs to be escaped
	    var source = '(?:' + _.keys(map).join('|') + ')';
	    var testRegexp = RegExp(source);
	    var replaceRegexp = RegExp(source, 'g');
	    return function(string) {
	      string = string == null ? '' : '' + string;
	      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
	    };
	  };
	  _.escape = createEscaper(escapeMap);
	  _.unescape = createEscaper(unescapeMap);
	
	  // If the value of the named `property` is a function then invoke it with the
	  // `object` as context; otherwise, return it.
	  _.result = function(object, property, fallback) {
	    var value = object == null ? void 0 : object[property];
	    if (value === void 0) {
	      value = fallback;
	    }
	    return _.isFunction(value) ? value.call(object) : value;
	  };
	
	  // Generate a unique integer id (unique within the entire client session).
	  // Useful for temporary DOM ids.
	  var idCounter = 0;
	  _.uniqueId = function(prefix) {
	    var id = ++idCounter + '';
	    return prefix ? prefix + id : id;
	  };
	
	  // By default, Underscore uses ERB-style template delimiters, change the
	  // following template settings to use alternative delimiters.
	  _.templateSettings = {
	    evaluate    : /<%([\s\S]+?)%>/g,
	    interpolate : /<%=([\s\S]+?)%>/g,
	    escape      : /<%-([\s\S]+?)%>/g
	  };
	
	  // When customizing `templateSettings`, if you don't want to define an
	  // interpolation, evaluation or escaping regex, we need one that is
	  // guaranteed not to match.
	  var noMatch = /(.)^/;
	
	  // Certain characters need to be escaped so that they can be put into a
	  // string literal.
	  var escapes = {
	    "'":      "'",
	    '\\':     '\\',
	    '\r':     'r',
	    '\n':     'n',
	    '\u2028': 'u2028',
	    '\u2029': 'u2029'
	  };
	
	  var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
	
	  var escapeChar = function(match) {
	    return '\\' + escapes[match];
	  };
	
	  // JavaScript micro-templating, similar to John Resig's implementation.
	  // Underscore templating handles arbitrary delimiters, preserves whitespace,
	  // and correctly escapes quotes within interpolated code.
	  // NB: `oldSettings` only exists for backwards compatibility.
	  _.template = function(text, settings, oldSettings) {
	    if (!settings && oldSettings) settings = oldSettings;
	    settings = _.defaults({}, settings, _.templateSettings);
	
	    // Combine delimiters into one regular expression via alternation.
	    var matcher = RegExp([
	      (settings.escape || noMatch).source,
	      (settings.interpolate || noMatch).source,
	      (settings.evaluate || noMatch).source
	    ].join('|') + '|$', 'g');
	
	    // Compile the template source, escaping string literals appropriately.
	    var index = 0;
	    var source = "__p+='";
	    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
	      source += text.slice(index, offset).replace(escaper, escapeChar);
	      index = offset + match.length;
	
	      if (escape) {
	        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
	      } else if (interpolate) {
	        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
	      } else if (evaluate) {
	        source += "';\n" + evaluate + "\n__p+='";
	      }
	
	      // Adobe VMs need the match returned to produce the correct offest.
	      return match;
	    });
	    source += "';\n";
	
	    // If a variable is not specified, place data values in local scope.
	    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
	
	    source = "var __t,__p='',__j=Array.prototype.join," +
	      "print=function(){__p+=__j.call(arguments,'');};\n" +
	      source + 'return __p;\n';
	
	    try {
	      var render = new Function(settings.variable || 'obj', '_', source);
	    } catch (e) {
	      e.source = source;
	      throw e;
	    }
	
	    var template = function(data) {
	      return render.call(this, data, _);
	    };
	
	    // Provide the compiled source as a convenience for precompilation.
	    var argument = settings.variable || 'obj';
	    template.source = 'function(' + argument + '){\n' + source + '}';
	
	    return template;
	  };
	
	  // Add a "chain" function. Start chaining a wrapped Underscore object.
	  _.chain = function(obj) {
	    var instance = _(obj);
	    instance._chain = true;
	    return instance;
	  };
	
	  // OOP
	  // ---------------
	  // If Underscore is called as a function, it returns a wrapped object that
	  // can be used OO-style. This wrapper holds altered versions of all the
	  // underscore functions. Wrapped objects may be chained.
	
	  // Helper function to continue chaining intermediate results.
	  var result = function(instance, obj) {
	    return instance._chain ? _(obj).chain() : obj;
	  };
	
	  // Add your own custom functions to the Underscore object.
	  _.mixin = function(obj) {
	    _.each(_.functions(obj), function(name) {
	      var func = _[name] = obj[name];
	      _.prototype[name] = function() {
	        var args = [this._wrapped];
	        push.apply(args, arguments);
	        return result(this, func.apply(_, args));
	      };
	    });
	  };
	
	  // Add all of the Underscore functions to the wrapper object.
	  _.mixin(_);
	
	  // Add all mutator Array functions to the wrapper.
	  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      var obj = this._wrapped;
	      method.apply(obj, arguments);
	      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
	      return result(this, obj);
	    };
	  });
	
	  // Add all accessor Array functions to the wrapper.
	  _.each(['concat', 'join', 'slice'], function(name) {
	    var method = ArrayProto[name];
	    _.prototype[name] = function() {
	      return result(this, method.apply(this._wrapped, arguments));
	    };
	  });
	
	  // Extracts the result from a wrapped and chained object.
	  _.prototype.value = function() {
	    return this._wrapped;
	  };
	
	  // Provide unwrapping proxy for some methods used in engine operations
	  // such as arithmetic and JSON stringification.
	  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
	
	  _.prototype.toString = function() {
	    return '' + this._wrapped;
	  };
	
	  // AMD registration happens at the end for compatibility with AMD loaders
	  // that may not enforce next-turn semantics on modules. Even though general
	  // practice for AMD registration is to be anonymous, underscore registers
	  // as a named module because, like jQuery, it is a base library that is
	  // popular enough to be bundled in a third party lib, but not be part of
	  // an AMD load request. Those cases could generate an error when an
	  // anonymous define() is called outside of a loader request.
	  if (true) {
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
	      return _;
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
	}.call(this));
	
})
/** END DEFINE BLOCK for underscore@1.8.3/underscore.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var base64_js_1 = __jupyter_require__('base64-js@1.2.0/index.js');
	/**
	 * http://www.ietf.org/rfc/rfc4122.txt
	 */
	function uuid() {
	    var s = [];
	    var hexDigits = '0123456789ABCDEF';
	    for (var i = 0; i < 32; i++) {
	        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
	    }
	    s[12] = '4'; // bits 12-15 of the time_hi_and_version field to 0010
	    s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
	    return s.join('');
	}
	exports.uuid = uuid;
	/**
	 * Wrappable Error class
	 *
	 * The Error class doesn't actually act on `this`.  Instead it always
	 * returns a new instance of Error.  Here we capture that instance so we
	 * can apply it's properties to `this`.
	 */
	var WrappedError = (function (_super) {
	    __extends(WrappedError, _super);
	    function WrappedError(message, error) {
	        var _this = _super.call(this, message) || this;
	        // Keep a stack of the original error messages.
	        if (error instanceof WrappedError) {
	            _this.error_stack = error.error_stack;
	        }
	        else {
	            _this.error_stack = [error];
	        }
	        _this.error_stack.push(_this);
	        return _this;
	    }
	    return WrappedError;
	}(Error));
	exports.WrappedError = WrappedError;
	/**
	 * Resolve a promiseful dictionary.
	 * Returns a single Promise.
	 */
	function resolvePromisesDict(d) {
	    var keys = Object.keys(d);
	    var values = [];
	    keys.forEach(function (key) {
	        values.push(d[key]);
	    });
	    return Promise.all(values).then(function (v) {
	        d = {};
	        for (var i = 0; i < keys.length; i++) {
	            d[keys[i]] = v[i];
	        }
	        return d;
	    });
	}
	exports.resolvePromisesDict = resolvePromisesDict;
	/**
	 * Creates a wrappable Promise rejection function.
	 *
	 * Creates a function that returns a Promise.reject with a new WrappedError
	 * that has the provided message and wraps the original error that
	 * caused the promise to reject.
	 */
	function reject(message, log) {
	    return function promiseRejection(error) {
	        var wrapped_error = new WrappedError(message, error);
	        if (log)
	            console.error(wrapped_error);
	        return Promise.reject(wrapped_error);
	    };
	}
	exports.reject = reject;
	/**
	 * Apply MathJax rendering to an element, and optionally set its text.
	 *
	 * If MathJax is not available, make no changes.
	 *
	 * Parameters
	 * ----------
	 * element: Node
	 * text: optional string
	 */
	function typeset(element, text) {
	    if (text !== void 0) {
	        element.textContent = text;
	    }
	    if (window.MathJax !== void 0) {
	        MathJax.Hub.Queue(['Typeset', MathJax.Hub, element]);
	    }
	}
	exports.typeset = typeset;
	/**
	 * escape text to HTML
	 */
	function escape_html(text) {
	    var esc = document.createElement('div');
	    esc.textContent = text;
	    return esc.innerHTML;
	}
	exports.escape_html = escape_html;
	;
	/**
	 * Takes an object 'state' and fills in buffer[i] at 'path' buffer_paths[i]
	 * where buffer_paths[i] is a list indicating where in the object buffer[i] should
	 * be placed
	 * Example: state = {a: 1, b: {}, c: [0, null]}
	 * buffers = [array1, array2]
	 * buffer_paths = [['b', 'data'], ['c', 1]]
	 * Will lead to {a: 1, b: {data: array1}, c: [0, array2]}
	 */
	function put_buffers(state, buffer_paths, buffers) {
	    for (var i = 0; i < buffer_paths.length; i++) {
	        var buffer_path = buffer_paths[i];
	        // say we want to set state[x][y][z] = buffers[i]
	        var obj = state;
	        // we first get obj = state[x][y]
	        for (var j = 0; j < buffer_path.length - 1; j++)
	            obj = obj[buffer_path[j]];
	        // and then set: obj[z] = buffers[i]
	        obj[buffer_path[buffer_path.length - 1]] = buffers[i];
	    }
	}
	exports.put_buffers = put_buffers;
	/**
	 * The inverse of put_buffers, return an objects with the new state where all buffers(ArrayBuffer)
	 * are removed. If a buffer is a member of an object, that object is cloned, and the key removed. If a buffer
	 * is an element of an array, that array is cloned, and the element is set to null.
	 * See put_buffers for the meaning of buffer_paths
	 * Returns an object with the new state (.state) an array with paths to the buffers (.buffer_paths),
	 * and the buffers associated to those paths (.buffers).
	 */
	function remove_buffers(state) {
	    var buffers = [];
	    var buffer_paths = [];
	    // if we need to remove an object from a list, we need to clone that list, otherwise we may modify
	    // the internal state of the widget model
	    // however, we do not want to clone everything, for performance
	    function remove(obj, path) {
	        if (obj.toJSON) {
	            // We need to get the JSON form of the object before recursing.
	            // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior
	            obj = obj.toJSON();
	        }
	        if (Array.isArray(obj)) {
	            var is_cloned = false;
	            for (var i = 0; i < obj.length; i++) {
	                var value = obj[i];
	                if (value) {
	                    if (value.buffer instanceof ArrayBuffer || value instanceof ArrayBuffer) {
	                        if (!is_cloned) {
	                            obj = _.clone(obj);
	                            is_cloned = true;
	                        }
	                        buffers.push(value instanceof ArrayBuffer ? value : value.buffer);
	                        buffer_paths.push(path.concat([i]));
	                        // easier to just keep the array, but clear the entry, otherwise we have to think
	                        // about array length, much easier this way
	                        obj[i] = null;
	                    }
	                    else {
	                        var new_value = remove(value, path.concat([i]));
	                        // only assigned when the value changes, we may serialize objects that don't support assignment
	                        if (new_value !== value) {
	                            if (!is_cloned) {
	                                obj = _.clone(obj);
	                                is_cloned = true;
	                            }
	                            obj[i] = new_value;
	                        }
	                    }
	                }
	            }
	        }
	        else if (_.isObject(obj)) {
	            for (var key in obj) {
	                var is_cloned = false;
	                if (obj.hasOwnProperty(key)) {
	                    var value = obj[key];
	                    if (value) {
	                        if (value.buffer instanceof ArrayBuffer || value instanceof ArrayBuffer) {
	                            if (!is_cloned) {
	                                obj = _.clone(obj);
	                                is_cloned = true;
	                            }
	                            buffers.push(value instanceof ArrayBuffer ? value : value.buffer);
	                            buffer_paths.push(path.concat([key]));
	                            delete obj[key]; // for objects/dicts we just delete them
	                        }
	                        else {
	                            var new_value = remove(value, path.concat([key]));
	                            // only assigned when the value changes, we may serialize objects that don't support assignment
	                            if (new_value !== value) {
	                                if (!is_cloned) {
	                                    obj = _.clone(obj);
	                                    is_cloned = true;
	                                }
	                                obj[key] = new_value;
	                            }
	                        }
	                    }
	                }
	            }
	        }
	        return obj;
	    }
	    var new_state = remove(state, []);
	    return { state: new_state, buffers: buffers, buffer_paths: buffer_paths };
	}
	exports.remove_buffers = remove_buffers;
	var hexTable = [
	    '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0A', '0B', '0C', '0D', '0E', '0F',
	    '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1A', '1B', '1C', '1D', '1E', '1F',
	    '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2A', '2B', '2C', '2D', '2E', '2F',
	    '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3A', '3B', '3C', '3D', '3E', '3F',
	    '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4A', '4B', '4C', '4D', '4E', '4F',
	    '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5A', '5B', '5C', '5D', '5E', '5F',
	    '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6A', '6B', '6C', '6D', '6E', '6F',
	    '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7A', '7B', '7C', '7D', '7E', '7F',
	    '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8A', '8B', '8C', '8D', '8E', '8F',
	    '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9A', '9B', '9C', '9D', '9E', '9F',
	    'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF',
	    'B0', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'BA', 'BB', 'BC', 'BD', 'BE', 'BF',
	    'C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'CA', 'CB', 'CC', 'CD', 'CE', 'CF',
	    'D0', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'DA', 'DB', 'DC', 'DD', 'DE', 'DF',
	    'E0', 'E1', 'E2', 'E3', 'E4', 'E5', 'E6', 'E7', 'E8', 'E9', 'EA', 'EB', 'EC', 'ED', 'EE', 'EF',
	    'F0', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'FA', 'FB', 'FC', 'FD', 'FE', 'FF'
	];
	/**
	 * Convert an ArrayBuffer to a hex string.
	 */
	function bufferToHex(buffer) {
	    var x = new Uint8Array(buffer);
	    var s = [];
	    for (var i = 0; i < x.length; i++) {
	        s.push(hexTable[x[i]]);
	    }
	    return s.join('');
	}
	exports.bufferToHex = bufferToHex;
	/**
	 * Convert a hex string to an ArrayBuffer.
	 */
	function hexToBuffer(hex) {
	    var x = new Uint8Array(hex.length / 2);
	    for (var i = 0; i < hex.length; i += 2) {
	        x[i / 2] = parseInt(hex.slice(i, i + 2), 16);
	    }
	    return x.buffer;
	}
	exports.hexToBuffer = hexToBuffer;
	/**
	 * Convert an ArrayBuffer to a base64 string.
	 */
	function bufferToBase64(buffer) {
	    return base64_js_1.fromByteArray(new Uint8Array(buffer));
	}
	exports.bufferToBase64 = bufferToBase64;
	/**
	 * Convert a base64 string to an ArrayBuffer.
	 */
	function base64ToBuffer(base64) {
	    return base64_js_1.toByteArray(base64).buffer;
	}
	exports.base64ToBuffer = base64ToBuffer;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js **/


/** START DEFINE BLOCK for base64-js@1.2.0/index.js **/
jupyter.define('base64-js@1.2.0/index.js', function (module, exports, __jupyter_require__) {
	'use strict'
	
	exports.byteLength = byteLength
	exports.toByteArray = toByteArray
	exports.fromByteArray = fromByteArray
	
	var lookup = []
	var revLookup = []
	var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
	
	var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
	for (var i = 0, len = code.length; i < len; ++i) {
	  lookup[i] = code[i]
	  revLookup[code.charCodeAt(i)] = i
	}
	
	revLookup['-'.charCodeAt(0)] = 62
	revLookup['_'.charCodeAt(0)] = 63
	
	function placeHoldersCount (b64) {
	  var len = b64.length
	  if (len % 4 > 0) {
	    throw new Error('Invalid string. Length must be a multiple of 4')
	  }
	
	  // the number of equal signs (place holders)
	  // if there are two placeholders, than the two characters before it
	  // represent one byte
	  // if there is only one, then the three characters before it represent 2 bytes
	  // this is just a cheap hack to not do indexOf twice
	  return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
	}
	
	function byteLength (b64) {
	  // base64 is 4/3 + up to two characters of the original data
	  return b64.length * 3 / 4 - placeHoldersCount(b64)
	}
	
	function toByteArray (b64) {
	  var i, j, l, tmp, placeHolders, arr
	  var len = b64.length
	  placeHolders = placeHoldersCount(b64)
	
	  arr = new Arr(len * 3 / 4 - placeHolders)
	
	  // if there are placeholders, only get up to the last complete 4 chars
	  l = placeHolders > 0 ? len - 4 : len
	
	  var L = 0
	
	  for (i = 0, j = 0; i < l; i += 4, j += 3) {
	    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
	    arr[L++] = (tmp >> 16) & 0xFF
	    arr[L++] = (tmp >> 8) & 0xFF
	    arr[L++] = tmp & 0xFF
	  }
	
	  if (placeHolders === 2) {
	    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
	    arr[L++] = tmp & 0xFF
	  } else if (placeHolders === 1) {
	    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
	    arr[L++] = (tmp >> 8) & 0xFF
	    arr[L++] = tmp & 0xFF
	  }
	
	  return arr
	}
	
	function tripletToBase64 (num) {
	  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
	}
	
	function encodeChunk (uint8, start, end) {
	  var tmp
	  var output = []
	  for (var i = start; i < end; i += 3) {
	    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
	    output.push(tripletToBase64(tmp))
	  }
	  return output.join('')
	}
	
	function fromByteArray (uint8) {
	  var tmp
	  var len = uint8.length
	  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
	  var output = ''
	  var parts = []
	  var maxChunkLength = 16383 // must be multiple of 3
	
	  // go through the array every three bytes, we'll deal with trailing stuff later
	  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
	    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
	  }
	
	  // pad the end with zeros, but make sure to not forget the extra bytes
	  if (extraBytes === 1) {
	    tmp = uint8[len - 1]
	    output += lookup[tmp >> 2]
	    output += lookup[(tmp << 4) & 0x3F]
	    output += '=='
	  } else if (extraBytes === 2) {
	    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
	    output += lookup[tmp >> 10]
	    output += lookup[(tmp >> 4) & 0x3F]
	    output += lookup[(tmp << 2) & 0x3F]
	    output += '='
	  }
	
	  parts.push(output)
	
	  return parts.join('')
	}
	
})
/** END DEFINE BLOCK for base64-js@1.2.0/index.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_string.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_string.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var StringModel = (function (_super) {
	    __extends(StringModel, _super);
	    function StringModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    StringModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: '',
	            disabled: false,
	            placeholder: '\u200b',
	            _model_name: 'StringModel'
	        });
	    };
	    return StringModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.StringModel = StringModel;
	var HTMLModel = (function (_super) {
	    __extends(HTMLModel, _super);
	    function HTMLModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    HTMLModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'HTMLView',
	            _model_name: 'HTMLModel'
	        });
	    };
	    return HTMLModel;
	}(StringModel));
	exports.HTMLModel = HTMLModel;
	var HTMLView = (function (_super) {
	    __extends(HTMLView, _super);
	    function HTMLView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    HTMLView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-html');
	        this.content = document.createElement('div');
	        this.content.classList.add('widget-html-content');
	        this.el.appendChild(this.content);
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    HTMLView.prototype.update = function () {
	        this.content.innerHTML = this.model.get('value');
	        return _super.prototype.update.call(this);
	    };
	    return HTMLView;
	}(widget_1.LabeledDOMWidgetView));
	exports.HTMLView = HTMLView;
	var HTMLMathModel = (function (_super) {
	    __extends(HTMLMathModel, _super);
	    function HTMLMathModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    HTMLMathModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'HTMLMathView',
	            _model_name: 'HTMLMathModel'
	        });
	    };
	    return HTMLMathModel;
	}(StringModel));
	exports.HTMLMathModel = HTMLMathModel;
	var HTMLMathView = (function (_super) {
	    __extends(HTMLMathView, _super);
	    function HTMLMathView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    HTMLMathView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-htmlmath');
	        this.content = document.createElement('div');
	        this.content.classList.add('widget-htmlmath-content');
	        this.el.appendChild(this.content);
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     */
	    HTMLMathView.prototype.update = function () {
	        this.content.innerHTML = this.model.get('value');
	        this.typeset(this.content);
	        return _super.prototype.update.call(this);
	    };
	    return HTMLMathView;
	}(widget_1.LabeledDOMWidgetView));
	exports.HTMLMathView = HTMLMathView;
	var LabelModel = (function (_super) {
	    __extends(LabelModel, _super);
	    function LabelModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LabelModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'LabelView',
	            _model_name: 'LabelModel'
	        });
	    };
	    return LabelModel;
	}(StringModel));
	exports.LabelModel = LabelModel;
	var LabelView = (function (_super) {
	    __extends(LabelView, _super);
	    function LabelView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    LabelView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-label');
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    LabelView.prototype.update = function () {
	        this.typeset(this.el, this.model.get('value'));
	        return _super.prototype.update.call(this);
	    };
	    return LabelView;
	}(widget_1.LabeledDOMWidgetView));
	exports.LabelView = LabelView;
	var TextareaModel = (function (_super) {
	    __extends(TextareaModel, _super);
	    function TextareaModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    TextareaModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'TextareaView',
	            _model_name: 'TextareaModel',
	            rows: null
	        });
	    };
	    return TextareaModel;
	}(StringModel));
	exports.TextareaModel = TextareaModel;
	var TextareaView = (function (_super) {
	    __extends(TextareaView, _super);
	    function TextareaView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    TextareaView.prototype.render = function () {
	        var _this = this;
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-textarea');
	        this.textbox = document.createElement('textarea');
	        this.textbox.setAttribute('rows', '5');
	        this.el.appendChild(this.textbox);
	        this.update(); // Set defaults.
	        this.listenTo(this.model, 'msg:custom', function (content) {
	            _this._handle_textarea_msg(content);
	        });
	        this.listenTo(this.model, 'change:placeholder', function (model, value, options) {
	            this.update_placeholder(value);
	        });
	        this.update_placeholder();
	    };
	    /**
	     * Handle when a custom msg is recieved from the back-end.
	     */
	    TextareaView.prototype._handle_textarea_msg = function (content) {
	        if (content.method == 'scroll_to_bottom') {
	            this.scroll_to_bottom();
	        }
	    };
	    TextareaView.prototype.update_placeholder = function (value) {
	        value = value || this.model.get('placeholder');
	        this.textbox.setAttribute('placeholder', value.toString());
	    };
	    /**
	     * Scroll the text-area view to the bottom.
	     */
	    TextareaView.prototype.scroll_to_bottom = function () {
	        //this.$textbox.scrollTop(this.$textbox[0].scrollHeight); // DW TODO
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    TextareaView.prototype.update = function (options) {
	        if (options === undefined || options.updated_view != this) {
	            this.textbox.value = this.model.get('value');
	            this.textbox.rows = this.model.get('rows');
	            var disabled = this.model.get('disabled');
	            this.textbox.disabled = disabled;
	        }
	        return _super.prototype.update.call(this);
	    };
	    TextareaView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'keydown textarea': 'handleKeyDown',
	            'keypress textarea': 'handleKeypress',
	            'keyup textarea': 'handleChanging',
	            'paste textarea': 'handleChanging',
	            'cut textarea': 'handleChanging'
	        };
	    };
	    /**
	     * Handle key down
	     *
	     * Stop propagation so the event isn't sent to the application.
	     */
	    TextareaView.prototype.handleKeyDown = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles key press
	     *
	     * Stop propagation so the keypress isn't sent to the application.
	     */
	    TextareaView.prototype.handleKeypress = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles and validates user input.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    TextareaView.prototype.handleChanging = function (e) {
	        this.model.set('value', e.target.value, { updated_view: this });
	        this.touch();
	    };
	    return TextareaView;
	}(widget_1.LabeledDOMWidgetView));
	exports.TextareaView = TextareaView;
	var TextModel = (function (_super) {
	    __extends(TextModel, _super);
	    function TextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    TextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'TextView',
	            _model_name: 'TextModel'
	        });
	    };
	    return TextModel;
	}(StringModel));
	exports.TextModel = TextModel;
	var TextView = (function (_super) {
	    __extends(TextView, _super);
	    function TextView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this.inputType = 'text';
	        return _this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    TextView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-text');
	        this.textbox = document.createElement('input');
	        this.textbox.setAttribute('type', this.inputType);
	        this.el.appendChild(this.textbox);
	        this.update(); // Set defaults.
	        this.listenTo(this.model, 'change:placeholder', function (model, value, options) {
	            this.update_placeholder(value);
	        });
	        this.update_placeholder();
	    };
	    TextView.prototype.update_placeholder = function (value) {
	        if (!value) {
	            value = this.model.get('placeholder');
	        }
	        this.textbox.setAttribute('placeholder', value);
	    };
	    TextView.prototype.update = function (options) {
	        /**
	         * Update the contents of this view
	         *
	         * Called when the model is changed.  The model may have been
	         * changed by another view or by a state update from the back-end.
	         */
	        if (options === undefined || options.updated_view != this) {
	            if (this.textbox.value != this.model.get('value')) {
	                this.textbox.value = this.model.get('value');
	            }
	            var disabled = this.model.get('disabled');
	            this.textbox.disabled = disabled;
	        }
	        return _super.prototype.update.call(this);
	    };
	    TextView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'keydown input': 'handleKeyDown',
	            'keypress input': 'handleKeypress',
	            'keyup input': 'handleChanging',
	            'paste input': 'handleChanging',
	            'cut input': 'handleChanging',
	            'blur input': 'handleBlur',
	            'focusout input': 'handleFocusOut'
	        };
	    };
	    /**
	     * Handle key down
	     *
	     * Stop propagation so the keypress isn't sent to the application.
	     */
	    TextView.prototype.handleKeyDown = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles text submission
	     */
	    TextView.prototype.handleKeypress = function (e) {
	        e.stopPropagation();
	        if (e.keyCode == 13) {
	            this.send({ event: 'submit' });
	            e.preventDefault();
	        }
	    };
	    /**
	     * Handles user input.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    TextView.prototype.handleChanging = function (e) {
	        e.stopPropagation();
	        this.model.set('value', e.target.value, { updated_view: this });
	        this.touch();
	    };
	    /**
	     * Prevent a blur from firing if the blur was not user intended.
	     * This is a workaround for the return-key focus loss bug.
	     * TODO: Is the original bug actually a fault of the keyboard
	     * manager?
	     */
	    TextView.prototype.handleBlur = function (e) {
	        if (e.relatedTarget === null) {
	            e.stopPropagation();
	            e.preventDefault();
	        }
	    };
	    /**
	     * Prevent a blur from firing if the blur was not user intended.
	     * This is a workaround for the return-key focus loss bug.
	     */
	    TextView.prototype.handleFocusOut = function (e) {
	        if (e.relatedTarget === null) {
	            e.stopPropagation();
	            e.preventDefault();
	        }
	    };
	    return TextView;
	}(widget_1.LabeledDOMWidgetView));
	exports.TextView = TextView;
	var PasswordModel = (function (_super) {
	    __extends(PasswordModel, _super);
	    function PasswordModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    PasswordModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'PasswordView',
	            _model_name: 'PasswordModel'
	        });
	    };
	    return PasswordModel;
	}(TextModel));
	exports.PasswordModel = PasswordModel;
	var PasswordView = (function (_super) {
	    __extends(PasswordView, _super);
	    function PasswordView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this.inputType = 'password';
	        return _this;
	    }
	    return PasswordView;
	}(TextView));
	exports.PasswordView = PasswordView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_string.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var Backbone = __jupyter_require__('backbone@1.2.0/backbone.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	var nativeview_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/nativeview.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.2.0/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.0/lib/index.js');
	exports.JUPYTER_WIDGETS_VERSION = '3.0.0';
	/**
	 * Replace model ids with models recursively.
	 */
	function unpack_models(value, manager) {
	    var unpacked;
	    if (_.isArray(value)) {
	        unpacked = [];
	        _.each(value, function (sub_value, key) {
	            unpacked.push(unpack_models(sub_value, manager));
	        });
	        return Promise.all(unpacked);
	    }
	    else if (value instanceof Object) {
	        unpacked = {};
	        _.each(value, function (sub_value, key) {
	            unpacked[key] = unpack_models(sub_value, manager);
	        });
	        return utils.resolvePromisesDict(unpacked);
	    }
	    else if (typeof value === 'string' && value.slice(0, 10) === 'IPY_MODEL_') {
	        // get_model returns a promise already
	        return manager.get_model(value.slice(10, value.length));
	    }
	    else {
	        return Promise.resolve(value);
	    }
	}
	exports.unpack_models = unpack_models;
	;
	var WidgetModel = (function (_super) {
	    __extends(WidgetModel, _super);
	    function WidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * The default attributes.
	     */
	    WidgetModel.prototype.defaults = function () {
	        return {
	            _model_module: "jupyter-js-widgets",
	            _model_name: "WidgetModel",
	            _model_module_version: exports.JUPYTER_WIDGETS_VERSION,
	            _view_module: "jupyter-js-widgets",
	            _view_name: null,
	            _view_module_version: exports.JUPYTER_WIDGETS_VERSION,
	            _view_count: null,
	            msg_throttle: 1,
	        };
	    };
	    /**
	     * Test to see if the model has been synced with the server.
	     *
	     * #### Notes
	     * As of backbone 1.1, backbone ignores `patch` if it thinks the
	     * model has never been pushed.
	     */
	    WidgetModel.prototype.isNew = function () {
	        return false;
	    };
	    /**
	     * Constructor
	     *
	     * Creates a WidgetModel instance.
	     *
	     * Parameters
	     * ----------
	     * widget_manager : WidgetManager instance
	     * model_id : string
	     *      An ID unique to this model.
	     * comm : Comm instance (optional)
	     */
	    WidgetModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.widget_manager = options.widget_manager;
	        this.id = options.model_id;
	        var comm = options.comm;
	        this.state_change = Promise.resolve();
	        this.pending_msgs = 0;
	        this.msg_buffer = null;
	        this.state_lock = null;
	        this._buffered_state_diff = {};
	        this.views = {};
	        if (comm) {
	            // Remember comm associated with the model.
	            this.comm = comm;
	            comm.model = this;
	            // Hook comm messages up to model.
	            comm.on_close(_.bind(this._handle_comm_closed, this));
	            comm.on_msg(_.bind(this._handle_comm_msg, this));
	            this.comm_live = true;
	        }
	        else {
	            this.comm_live = false;
	        }
	    };
	    /**
	     * Send a custom msg over the comm.
	     *
	     * Any custom callbacks must include calls to the model callbacks returned
	     * from model.callbacks()
	     */
	    WidgetModel.prototype.send = function (content, callbacks, buffers) {
	        if (this.comm !== undefined) {
	            var data = { method: 'custom', content: content };
	            this.comm.send(data, callbacks, {}, buffers);
	            this.pending_msgs++;
	        }
	    };
	    /**
	     * Close model
	     */
	    WidgetModel.prototype.close = function (comm_closed) {
	        if (this.comm && !comm_closed) {
	            this.comm.close();
	        }
	        this.stopListening();
	        this.trigger('destroy', this);
	        if (this.comm) {
	            delete this.comm.model; // Delete ref so GC will collect widget model.
	            delete this.comm;
	        }
	        delete this.model_id; // Delete id from model so widget manager cleans up.
	        _.each(this.views, function (v, id, views) {
	            v.then(function (view) {
	                view.remove();
	                delete views[id];
	            });
	        });
	    };
	    /**
	     * Handle when a widget is closed.
	     */
	    WidgetModel.prototype._handle_comm_closed = function (msg) {
	        this.trigger('comm:close');
	        this.close(true);
	    };
	    /**
	     * Handle incoming comm msg.
	     */
	    WidgetModel.prototype._handle_comm_msg = function (msg) {
	        var _this = this;
	        var method = msg.content.data.method;
	        switch (method) {
	            case 'update':
	                this.state_change = this.state_change
	                    .then(function () {
	                    // see Widget.open/_split_state_buffers about why we need state_with_buffers
	                    var state = msg.content.data.state;
	                    var buffer_paths = msg.content.data.buffer_paths || [];
	                    // Make sure the buffers are DataViews
	                    var buffers = (msg.buffers || []).map(function (b) {
	                        if (b instanceof DataView) {
	                            return b;
	                        }
	                        else {
	                            return new DataView(b instanceof ArrayBuffer ? b : b.buffer);
	                        }
	                    });
	                    utils.put_buffers(state, buffer_paths, buffers);
	                    return _this.constructor._deserialize_state(state, _this.widget_manager);
	                }).then(function (state) {
	                    _this.set_state(state);
	                }).catch(utils.reject('Could not process update msg for model id: ' + String(this.id), true));
	                return this.state_change;
	            case 'custom':
	                this.trigger('msg:custom', msg.content.data.content, msg.buffers);
	                return Promise.resolve();
	            case 'display':
	                if (this.widget_manager.displayWithOutput) {
	                    return;
	                }
	                this.state_change = this.state_change.then(function () {
	                    _this.widget_manager.display_model(msg, _this);
	                }).catch(utils.reject('Could not process display view msg', true));
	                return this.state_change;
	        }
	    };
	    /**
	     * Handle when a widget is updated from the backend.
	     */
	    WidgetModel.prototype.set_state = function (state) {
	        this.state_lock = state;
	        try {
	            this.set(state);
	        }
	        catch (e) {
	            console.error('Error setting state:', e.message);
	        }
	        finally {
	            this.state_lock = null;
	        }
	    };
	    /**
	     * Get the serializable state of the model.
	     *
	     * If drop_default is thruthy, attributes that are equal to their default
	     * values are dropped.
	     */
	    WidgetModel.prototype.get_state = function (drop_defaults) {
	        var state = this.attributes;
	        if (drop_defaults) {
	            var defaults = _.result(this, 'defaults');
	            return Object.keys(state).reduce(function (obj, key) {
	                if (!_.isEqual(state[key], defaults[key])) {
	                    obj[key] = state[key];
	                }
	                return obj;
	            }, {});
	        }
	        else {
	            return _.clone(state);
	        }
	    };
	    /**
	     * Handle status msgs.
	     *
	     * execution_state : ('busy', 'idle', 'starting')
	     */
	    WidgetModel.prototype._handle_status = function (msg, callbacks) {
	        if (this.comm !== undefined) {
	            if (msg.content.execution_state === 'idle') {
	                this.pending_msgs--;
	                // Send buffer if one is waiting and we are below the throttle.
	                if (this.msg_buffer !== null
	                    && this.pending_msgs < (this.get('msg_throttle') || 1)) {
	                    this.send_sync_message(this.msg_buffer, this.msg_buffer_callbacks);
	                    this.msg_buffer = null;
	                    this.msg_buffer_callbacks = null;
	                }
	            }
	        }
	    };
	    /**
	     * Create msg callbacks for a comm msg.
	     */
	    WidgetModel.prototype.callbacks = function (view) {
	        var _this = this;
	        var callbacks = this.widget_manager.callbacks(view);
	        if (callbacks.iopub === undefined) {
	            callbacks.iopub = {};
	        }
	        callbacks.iopub.status = function (msg) {
	            _this._handle_status(msg, callbacks);
	        };
	        return callbacks;
	    };
	    /**
	     * Set a value.
	     *
	     * We just call the super method, in which val and options are optional
	     */
	    WidgetModel.prototype.set = function (key, val, options) {
	        var return_value = _super.prototype.set.call(this, key, val, options);
	        // Backbone only remembers the diff of the most recent set()
	        // operation.  Calling set multiple times in a row results in a
	        // loss of change information.  Here we keep our own running diff.
	        //
	        // We don't buffer the state set in the constructor (including
	        // defaults), so we first check to see if we've initialized _buffered_state_diff.
	        // which happens after the constructor sets attributes at creation.
	        if (this._buffered_state_diff !== void 0) {
	            var attrs = this.changedAttributes() || {};
	            // The state_lock lists attributes that are currently being changed
	            // right now from a kernel message. We don't want to send these
	            // non-changes back to the kernel, so we delete them out of attrs if
	            // they haven't changed from their state_lock value
	            if (this.state_lock !== null) {
	                for (var _i = 0, _a = Object.keys(this.state_lock); _i < _a.length; _i++) {
	                    var key_1 = _a[_i];
	                    if (attrs[key_1] === this.state_lock[key_1]) {
	                        delete attrs[key_1];
	                    }
	                }
	            }
	            this._buffered_state_diff = _.extend(this._buffered_state_diff, attrs);
	        }
	        return return_value;
	    };
	    /**
	     * Handle sync to the back-end.  Called when a model.save() is called.
	     *
	     * Make sure a comm exists.
	     *
	     * Parameters
	     * ----------
	     * method : create, update, patch, delete, read
	     *   create/update always send the full attribute set
	     *   patch - only send attributes listed in options.attrs, and if we
	     *   are queuing up messages, combine with previous messages that have
	     *   not been sent yet
	     * model : the model we are syncing
	     *   will normally be the same as `this`
	     * options : dict
	     *   the `attrs` key, if it exists, gives an {attr: value} dict that
	     *   should be synced, otherwise, sync all attributes.
	     *
	     */
	    WidgetModel.prototype.sync = function (method, model, options) {
	        if (options === void 0) { options = {}; }
	        // the typing is to return `any` since the super.sync method returns a JqXHR, but we just return false if there is an error.
	        if (this.comm === undefined) {
	            throw 'Syncing error: no comm channel defined';
	        }
	        var attrs = (method === 'patch') ? options.attrs : model.get_state(options.drop_defaults);
	        // The state_lock lists attributes that are currently being changed
	        // right now from a kernel message. We don't want to send these
	        // non-changes back to the kernel, so we delete them out of attrs if
	        // they haven't changed from their state_lock value
	        if (this.state_lock !== null) {
	            for (var _i = 0, _a = Object.keys(this.state_lock); _i < _a.length; _i++) {
	                var key = _a[_i];
	                if (attrs[key] === this.state_lock[key]) {
	                    delete attrs[key];
	                }
	            }
	        }
	        var msgState = this.serialize(attrs);
	        if (Object.keys(msgState).length > 0) {
	            // If this message was sent via backbone itself, it will not
	            // have any callbacks.  It's important that we create callbacks
	            // so we can listen for status messages, etc...
	            var callbacks = options.callbacks || this.callbacks();
	            // Check throttle.
	            if (this.pending_msgs >= (this.get('msg_throttle') || 1)) {
	                // The throttle has been exceeded, buffer the current msg so
	                // it can be sent once the kernel has finished processing
	                // some of the existing messages.
	                // Combine updates if it is a 'patch' sync, otherwise replace updates
	                switch (method) {
	                    case 'patch':
	                        this.msg_buffer = _.extend(this.msg_buffer || {}, msgState);
	                        break;
	                    case 'update':
	                    case 'create':
	                        this.msg_buffer = msgState;
	                        break;
	                    default:
	                        throw 'unrecognized syncing method';
	                }
	                this.msg_buffer_callbacks = callbacks;
	            }
	            else {
	                // We haven't exceeded the throttle, send the message like
	                // normal.
	                this.send_sync_message(attrs, callbacks);
	                // Since the comm is a one-way communication, assume the message
	                // arrived and was processed successfully.
	                // Don't call options.success since we don't have a model back from
	                // the server. Note that this means we don't have the Backbone
	                // 'sync' event.
	            }
	        }
	    };
	    /**
	     * Serialize widget state.
	     *
	     * A serializer is a function which takes in a state attribute and a widget,
	     * and synchronously returns a JSONable object. The returned object will
	     * have toJSON called if possible, and the final result should be a
	     * primitive object that is a snapshot of the widget state that may have
	     * binary array buffers.
	     */
	    WidgetModel.prototype.serialize = function (state) {
	        var serializers = this.constructor.serializers || {};
	        for (var _i = 0, _a = Object.keys(state); _i < _a.length; _i++) {
	            var k = _a[_i];
	            try {
	                if (serializers[k] && serializers[k].serialize) {
	                    state[k] = (serializers[k].serialize)(state[k], this);
	                }
	                else {
	                    // the default serializer just deep-copies the object
	                    state[k] = JSON.parse(JSON.stringify(state[k]));
	                }
	                if (state[k] && state[k].toJSON) {
	                    state[k] = state[k].toJSON();
	                }
	            }
	            catch (e) {
	                console.error("Error serializing widget state attribute: ", k);
	                throw e;
	            }
	        }
	        return state;
	    };
	    WidgetModel.prototype.send_sync_message = function (state, callbacks) {
	        try {
	            // split out the binary buffers
	            var split = utils.remove_buffers(state);
	            this.comm.send({
	                method: 'update',
	                state: split.state,
	                buffer_paths: split.buffer_paths
	            }, callbacks, {}, split.buffers);
	            this.pending_msgs++;
	        }
	        catch (e) {
	            console.error('Could not send widget sync message', e);
	        }
	    };
	    /**
	     * Push this model's state to the back-end
	     *
	     * This invokes a Backbone.Sync.
	     */
	    WidgetModel.prototype.save_changes = function (callbacks) {
	        if (this.comm_live) {
	            var options = { patch: true };
	            if (callbacks) {
	                options.callbacks = callbacks;
	            }
	            this.save(this._buffered_state_diff, options);
	            this._buffered_state_diff = {};
	        }
	    };
	    /**
	     * on_some_change(['key1', 'key2'], foo, context) differs from
	     * on('change:key1 change:key2', foo, context).
	     * If the widget attributes key1 and key2 are both modified,
	     * the second form will result in foo being called twice
	     * while the first will call foo only once.
	     */
	    WidgetModel.prototype.on_some_change = function (keys, callback, context) {
	        this.on('change', function () {
	            if (keys.some(this.hasChanged, this)) {
	                callback.apply(context, arguments);
	            }
	        }, this);
	    };
	    /**
	     * Serialize the model.  See the deserialization function at the top of this file
	     * and the kernel-side serializer/deserializer.
	     */
	    WidgetModel.prototype.toJSON = function (options) {
	        return "IPY_MODEL_" + this.id;
	    };
	    /**
	     * Returns a promise for the deserialized state. The second argument
	     * is an instance of widget manager, which is required for the
	     * deserialization of widget models.
	     */
	    WidgetModel._deserialize_state = function (state, manager) {
	        var serializers = this.serializers;
	        var deserialized;
	        if (serializers) {
	            deserialized = {};
	            for (var k in state) {
	                if (serializers[k] && serializers[k].deserialize) {
	                    deserialized[k] = (serializers[k].deserialize)(state[k], manager);
	                }
	                else {
	                    deserialized[k] = state[k];
	                }
	            }
	        }
	        else {
	            deserialized = state;
	        }
	        return utils.resolvePromisesDict(deserialized);
	    };
	    return WidgetModel;
	}(Backbone.Model));
	exports.WidgetModel = WidgetModel;
	var DOMWidgetModel = (function (_super) {
	    __extends(DOMWidgetModel, _super);
	    function DOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            layout: null,
	            style: null,
	            _dom_classes: []
	        });
	    };
	    return DOMWidgetModel;
	}(WidgetModel));
	DOMWidgetModel.serializers = __assign({}, WidgetModel.serializers, { layout: { deserialize: unpack_models }, style: { deserialize: unpack_models } });
	exports.DOMWidgetModel = DOMWidgetModel;
	/**
	 * - create_view and remove_view are default functions called when adding or removing views
	 * - create_view takes a model and an index and returns a view or a promise for a view for that model
	 * - remove_view takes a view and destroys it (including calling `view.remove()`)
	 * - each time the update() function is called with a new list, the create and remove
	 *   callbacks will be called in an order so that if you append the views created in the
	 *   create callback and remove the views in the remove callback, you will duplicate
	 *   the order of the list.
	 * - the remove callback defaults to just removing the view (e.g., pass in null for the second parameter)
	 * - the context defaults to the created ViewList.  If you pass another context, the create and remove
	 *   will be called in that context.
	 */
	var ViewList = (function () {
	    function ViewList(create_view, remove_view, context) {
	        this.initialize(create_view, remove_view, context);
	    }
	    ViewList.prototype.initialize = function (create_view, remove_view, context) {
	        this._handler_context = context || this;
	        this._models = [];
	        this.views = []; // list of promises for views
	        this._create_view = create_view;
	        this._remove_view = remove_view || function (view) { view.remove(); };
	    };
	    /**
	     * the create_view, remove_view, and context arguments override the defaults
	     * specified when the list is created.
	     * after this function, the .views attribute is a list of promises for views
	     * if you want to perform some action on the list of views, do something like
	     * `Promise.all(myviewlist.views).then(function(views) {...});`
	     */
	    ViewList.prototype.update = function (new_models, create_view, remove_view, context) {
	        var remove = remove_view || this._remove_view;
	        var create = create_view || this._create_view;
	        context = context || this._handler_context;
	        var i = 0;
	        // first, skip past the beginning of the lists if they are identical
	        for (; i < new_models.length; i++) {
	            if (i >= this._models.length || new_models[i] !== this._models[i]) {
	                break;
	            }
	        }
	        var first_removed = i;
	        // Remove the non-matching items from the old list.
	        var removed = this.views.splice(first_removed, this.views.length - first_removed);
	        for (var j = 0; j < removed.length; j++) {
	            removed[j].then(function (view) {
	                remove.call(context, view);
	            });
	        }
	        // Add the rest of the new list items.
	        for (; i < new_models.length; i++) {
	            this.views.push(Promise.resolve(create.call(context, new_models[i], i)));
	        }
	        // make a copy of the input array
	        this._models = new_models.slice();
	        // return a promise that resolves to all of the resolved views
	        return Promise.all(this.views);
	    };
	    /**
	     * removes every view in the list; convenience function for `.update([])`
	     * that should be faster
	     * returns a promise that resolves after this removal is done
	     */
	    ViewList.prototype.remove = function () {
	        var _this = this;
	        return Promise.all(this.views).then(function (views) {
	            views.forEach(function (value) { return _this._remove_view.call(_this._handler_context, value); });
	            _this.views = [];
	            _this._models = [];
	        });
	    };
	    /**
	     * Dispose this viewlist.
	     *
	     * A synchronous function which just deletes references to child views. This
	     * function does not call .remove() on child views because that is
	     * asynchronous. Use this in cases where child views will be removed in
	     * another way.
	     */
	    ViewList.prototype.dispose = function () {
	        this.views = null;
	        this._models = null;
	    };
	    return ViewList;
	}());
	exports.ViewList = ViewList;
	var WidgetView = (function (_super) {
	    __extends(WidgetView, _super);
	    function WidgetView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor.
	     */
	    WidgetView.prototype.initialize = function (parameters) {
	        var _this = this;
	        this.listenTo(this.model, 'change', function () {
	            var changed = Object.keys(_this.model.changedAttributes() || {});
	            if (changed[0] === '_view_count' && changed.length === 1) {
	                // Just the view count was updated
	                return;
	            }
	            _this.update();
	        });
	        this.options = parameters.options;
	        this.once('remove', function () {
	            if (typeof (_this.model.get('_view_count')) === "number") {
	                _this.model.set('_view_count', _this.model.get('_view_count') - 1);
	                _this.model.save_changes();
	            }
	        });
	        this.once('displayed', function () {
	            if (typeof (_this.model.get('_view_count')) === "number") {
	                _this.model.set('_view_count', _this.model.get('_view_count') + 1);
	                _this.model.save_changes();
	            }
	        });
	        this.displayed = new Promise(function (resolve, reject) {
	            _this.once('displayed', resolve);
	        });
	    };
	    /**
	     * Triggered on model change.
	     *
	     * Update view to be consistent with this.model
	     */
	    WidgetView.prototype.update = function (options) {
	    };
	    ;
	    /**
	     * Render a view
	     *
	     * @returns the view or a promise to the view.
	     */
	    WidgetView.prototype.render = function () {
	    };
	    /**
	     * Create and promise that resolves to a child view of a given model
	     */
	    WidgetView.prototype.create_child_view = function (child_model, options) {
	        var that = this;
	        options = _.extend({ parent: this }, options || {});
	        return this.model.widget_manager.create_view(child_model, options)
	            .catch(utils.reject('Could not create child view', true));
	    };
	    /**
	     * Create msg callbacks for a comm msg.
	     */
	    WidgetView.prototype.callbacks = function () {
	        return this.model.callbacks(this);
	    };
	    /**
	     * Send a custom msg associated with this view.
	     */
	    WidgetView.prototype.send = function (content, buffers) {
	        this.model.send(content, this.callbacks(), buffers);
	    };
	    WidgetView.prototype.touch = function () {
	        this.model.save_changes(this.callbacks());
	    };
	    WidgetView.prototype.remove = function () {
	        // Raise a remove event when the view is removed.
	        _super.prototype.remove.call(this);
	        this.trigger('remove');
	        return this;
	    };
	    return WidgetView;
	}(nativeview_1.NativeView));
	exports.WidgetView = WidgetView;
	var JupyterPhosphorWidget = (function (_super) {
	    __extends(JupyterPhosphorWidget, _super);
	    function JupyterPhosphorWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        return _this;
	    }
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    /**
	     * Process the phosphor message.
	     *
	     * Any custom phosphor widget used inside a Jupyter widget should override
	     * the processMessage function like this.
	     */
	    JupyterPhosphorWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        this._view.processPhosphorMessage(msg);
	    };
	    return JupyterPhosphorWidget;
	}(widgets_1.Widget));
	exports.JupyterPhosphorWidget = JupyterPhosphorWidget;
	var DOMWidgetView = (function (_super) {
	    __extends(DOMWidgetView, _super);
	    function DOMWidgetView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    DOMWidgetView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.id = utils.uuid();
	        this.listenTo(this.model, 'change:_dom_classes', function (model, new_classes) {
	            var old_classes = model.previous('_dom_classes');
	            _this.update_classes(old_classes, new_classes);
	        });
	        this.layoutPromise = Promise.resolve();
	        this.listenTo(this.model, 'change:layout', function (model, value) {
	            _this.setLayout(value, model.previous('layout'));
	        });
	        this.stylePromise = Promise.resolve();
	        this.listenTo(this.model, 'change:style', function (model, value) {
	            _this.setStyle(value, model.previous('style'));
	        });
	        this.displayed.then(function () {
	            _this.update_classes([], _this.model.get('_dom_classes'));
	            _this.setLayout(_this.model.get('layout'));
	            _this.setStyle(_this.model.get('style'));
	        });
	    };
	    DOMWidgetView.prototype.setLayout = function (layout, oldLayout) {
	        var _this = this;
	        if (layout) {
	            this.layoutPromise = this.layoutPromise.then(function (oldLayoutView) {
	                if (oldLayoutView) {
	                    oldLayoutView.unlayout();
	                    _this.stopListening(oldLayoutView.model);
	                    oldLayoutView.remove();
	                }
	                return _this.create_child_view(layout).then(function (view) {
	                    // Trigger the displayed event of the child view.
	                    return _this.displayed.then(function () {
	                        view.trigger('displayed');
	                        _this.listenTo(view.model, 'change', function () {
	                            // Post (asynchronous) so layout changes can take
	                            // effect first.
	                            messaging_1.MessageLoop.postMessage(_this.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	                        });
	                        messaging_1.MessageLoop.postMessage(_this.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	                        return view;
	                    });
	                }).catch(utils.reject('Could not add LayoutView to DOMWidgetView', true));
	            });
	        }
	    };
	    DOMWidgetView.prototype.setStyle = function (style, oldStyle) {
	        var _this = this;
	        if (style) {
	            this.stylePromise = this.stylePromise.then(function (oldStyleView) {
	                if (oldStyleView) {
	                    oldStyleView.unstyle();
	                    _this.stopListening(oldStyleView.model);
	                    oldStyleView.remove();
	                }
	                return _this.create_child_view(style).then(function (view) {
	                    // Trigger the displayed event of the child view.
	                    return _this.displayed.then(function () {
	                        view.trigger('displayed');
	                        // Unlike for the layout attribute, style changes don't
	                        // trigger phosphor resize messages.
	                        return view;
	                    });
	                }).catch(utils.reject('Could not add styleView to DOMWidgetView', true));
	            });
	        }
	    };
	    /**
	     * Update the DOM classes applied to an element, default to this.el.
	     */
	    DOMWidgetView.prototype.update_classes = function (old_classes, new_classes, el) {
	        if (el === undefined) {
	            el = this.el;
	        }
	        _.difference(old_classes, new_classes).map(function (c) {
	            if (el.classList) {
	                el.classList.remove(c);
	            }
	            else {
	                el.setAttribute('class', el.getAttribute('class').replace(c, ''));
	            }
	        });
	        _.difference(new_classes, old_classes).map(function (c) {
	            if (el.classList) {
	                el.classList.add(c);
	            }
	            else {
	                el.setAttribute('class', el.getAttribute('class').concat(' ', c));
	            }
	        });
	    };
	    /**
	     * Update the DOM classes applied to the widget based on a single
	     * trait's value.
	     *
	     * Given a trait value classes map, this function automatically
	     * handles applying the appropriate classes to the widget element
	     * and removing classes that are no longer valid.
	     *
	     * Parameters
	     * ----------
	     * class_map: dictionary
	     *  Dictionary of trait values to class lists.
	     *  Example:
	     *      {
	     *          success: ['alert', 'alert-success'],
	     *          info: ['alert', 'alert-info'],
	     *          warning: ['alert', 'alert-warning'],
	     *          danger: ['alert', 'alert-danger']
	     *      };
	     * trait_name: string
	     *  Name of the trait to check the value of.
	     * el: optional DOM element handle, defaults to this.el
	     *  Element that the classes are applied to.
	     */
	    DOMWidgetView.prototype.update_mapped_classes = function (class_map, trait_name, el) {
	        var key = this.model.previous(trait_name);
	        var old_classes = class_map[key] ? class_map[key] : [];
	        key = this.model.get(trait_name);
	        var new_classes = class_map[key] ? class_map[key] : [];
	        this.update_classes(old_classes, new_classes, el || this.el);
	    };
	    DOMWidgetView.prototype.set_mapped_classes = function (class_map, trait_name, el) {
	        var key = this.model.get(trait_name);
	        var new_classes = class_map[key] ? class_map[key] : [];
	        this.update_classes([], new_classes, el || this.el);
	    };
	    DOMWidgetView.prototype.typeset = function (element, text) {
	        this.displayed.then(function () { utils.typeset(element, text); });
	    };
	    DOMWidgetView.prototype._setElement = function (el) {
	        if (this.pWidget) {
	            this.pWidget.dispose();
	        }
	        this.$el = el instanceof $ ? el : $(el);
	        this.el = this.$el[0];
	        this.pWidget = new JupyterPhosphorWidget({
	            node: el,
	            view: this
	        });
	    };
	    DOMWidgetView.prototype.remove = function () {
	        if (this.pWidget) {
	            this.pWidget.dispose();
	        }
	        return _super.prototype.remove.call(this);
	    };
	    DOMWidgetView.prototype.processPhosphorMessage = function (msg) {
	        switch (msg.type) {
	            case 'after-attach':
	                this.trigger('displayed');
	                break;
	        }
	    };
	    return DOMWidgetView;
	}(WidgetView));
	exports.DOMWidgetView = DOMWidgetView;
	var LabeledDOMWidgetModel = (function (_super) {
	    __extends(LabeledDOMWidgetModel, _super);
	    function LabeledDOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LabeledDOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            description: '',
	        });
	    };
	    return LabeledDOMWidgetModel;
	}(DOMWidgetModel));
	exports.LabeledDOMWidgetModel = LabeledDOMWidgetModel;
	var LabeledDOMWidgetView = (function (_super) {
	    __extends(LabeledDOMWidgetView, _super);
	    function LabeledDOMWidgetView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LabeledDOMWidgetView.prototype.render = function () {
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.className = 'widget-label';
	        this.label.style.display = 'none';
	        this.listenTo(this.model, 'change:description', this.updateDescription);
	        this.updateDescription();
	    };
	    LabeledDOMWidgetView.prototype.updateDescription = function () {
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        }
	        else {
	            this.label.innerHTML = description;
	            this.typeset(this.label);
	            this.label.style.display = '';
	        }
	        this.label.title = description;
	    };
	    return LabeledDOMWidgetView;
	}(DOMWidgetView));
	exports.LabeledDOMWidgetView = LabeledDOMWidgetView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js **/


/** START DEFINE BLOCK for backbone@1.2.0/backbone.js **/
jupyter.define('backbone@1.2.0/backbone.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global) {//     Backbone.js 1.2.0
	
	//     (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	//     Backbone may be freely distributed under the MIT license.
	//     For all details and documentation:
	//     http://backbonejs.org
	
	(function(factory) {
	
	  // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
	  // We use `self` instead of `window` for `WebWorker` support.
	  var root = (typeof self == 'object' && self.self == self && self) ||
	            (typeof global == 'object' && global.global == global && global);
	
	  // Set up Backbone appropriately for the environment. Start with AMD.
	  if (true) {
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__jupyter_require__('underscore@>=1.7.0/underscore.js'), __jupyter_require__('jquery@2.2.4/dist/jquery.js'), exports], __WEBPACK_AMD_DEFINE_RESULT__ = function(_, $, exports) {
	      // Export global even in AMD case in case this script is loaded with
	      // others that may still expect a global Backbone.
	      root.Backbone = factory(root, exports, _, $);
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	
	  // Next for Node.js or CommonJS. jQuery may not be needed as a module.
	  } else if (typeof exports !== 'undefined') {
	    var _ = require('underscore'), $;
	    try { $ = require('jquery'); } catch(e) {}
	    factory(root, exports, _, $);
	
	  // Finally, as a browser global.
	  } else {
	    root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
	  }
	
	}(function(root, Backbone, _, $) {
	
	  // Initial Setup
	  // -------------
	
	  // Save the previous value of the `Backbone` variable, so that it can be
	  // restored later on, if `noConflict` is used.
	  var previousBackbone = root.Backbone;
	
	  // Create local references to array methods we'll want to use later.
	  var array = [];
	  var slice = array.slice;
	
	  // Current version of the library. Keep in sync with `package.json`.
	  Backbone.VERSION = '1.2.0';
	
	  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
	  // the `$` variable.
	  Backbone.$ = $;
	
	  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
	  // to its previous owner. Returns a reference to this Backbone object.
	  Backbone.noConflict = function() {
	    root.Backbone = previousBackbone;
	    return this;
	  };
	
	  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
	  // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
	  // set a `X-Http-Method-Override` header.
	  Backbone.emulateHTTP = false;
	
	  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
	  // `application/json` requests ... this will encode the body as
	  // `application/x-www-form-urlencoded` instead and will send the model in a
	  // form param named `model`.
	  Backbone.emulateJSON = false;
	
	  // Backbone.Events
	  // ---------------
	
	  // A module that can be mixed in to *any object* in order to provide it with
	  // custom events. You may bind with `on` or remove with `off` callback
	  // functions to an event; `trigger`-ing an event fires all callbacks in
	  // succession.
	  //
	  //     var object = {};
	  //     _.extend(object, Backbone.Events);
	  //     object.on('expand', function(){ alert('expanded'); });
	  //     object.trigger('expand');
	  //
	  var Events = Backbone.Events = {};
	
	  // Regular expression used to split event strings.
	  var eventSplitter = /\s+/;
	
	  // Iterates over the standard `event, callback` (as well as the fancy multiple
	  // space-separated events `"change blur", callback` and jQuery-style event
	  // maps `{event: callback}`), reducing them by manipulating `memo`.
	  // Passes a normalized single event name and callback, as well as any
	  // optional `opts`.
	  var eventsApi = function(iteratee, memo, name, callback, opts) {
	    var i = 0, names;
	    if (name && typeof name === 'object') {
	      // Handle event maps.
	      for (names = _.keys(name); i < names.length ; i++) {
	        memo = iteratee(memo, names[i], name[names[i]], opts);
	      }
	    } else if (name && eventSplitter.test(name)) {
	      // Handle space separated event names.
	      for (names = name.split(eventSplitter); i < names.length; i++) {
	        memo = iteratee(memo, names[i], callback, opts);
	      }
	    } else {
	      memo = iteratee(memo, name, callback, opts);
	    }
	    return memo;
	  };
	
	  // Bind an event to a `callback` function. Passing `"all"` will bind
	  // the callback to all events fired.
	  Events.on = function(name, callback, context) {
	    return internalOn(this, name, callback, context);
	  };
	
	  // An internal use `on` function, used to guard the `listening` argument from
	  // the public API.
	  var internalOn = function(obj, name, callback, context, listening) {
	    obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
	        context: context,
	        ctx: obj,
	        listening: listening
	    });
	
	    if (listening) {
	      var listeners = obj._listeners || (obj._listeners = {});
	      listeners[listening.id] = listening;
	    }
	
	    return obj;
	  };
	
	  // Inversion-of-control versions of `on`. Tell *this* object to listen to
	  // an event in another object... keeping track of what it's listening to.
	  Events.listenTo =  function(obj, name, callback) {
	    if (!obj) return this;
	    var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
	    var listeningTo = this._listeningTo || (this._listeningTo = {});
	    var listening = listeningTo[id];
	
	    // This object is not listening to any other events on `obj` yet.
	    // Setup the necessary references to track the listening callbacks.
	    if (!listening) {
	      var thisId = this._listenId || (this._listenId = _.uniqueId('l'));
	      listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0};
	    }
	
	    // Bind callbacks on obj, and keep track of them on listening.
	    internalOn(obj, name, callback, this, listening);
	    return this;
	  };
	
	  // The reducing API that adds a callback to the `events` object.
	  var onApi = function(events, name, callback, options) {
	    if (callback) {
	      var handlers = events[name] || (events[name] = []);
	      var context = options.context, ctx = options.ctx, listening = options.listening;
	      if (listening) listening.count++;
	
	      handlers.push({ callback: callback, context: context, ctx: context || ctx, listening: listening });
	    }
	    return events;
	  };
	
	  // Remove one or many callbacks. If `context` is null, removes all
	  // callbacks with that function. If `callback` is null, removes all
	  // callbacks for the event. If `name` is null, removes all bound
	  // callbacks for all events.
	  Events.off =  function(name, callback, context) {
	    if (!this._events) return this;
	    this._events = eventsApi(offApi, this._events, name, callback, {
	        context: context,
	        listeners: this._listeners
	    });
	    return this;
	  };
	
	  // Tell this object to stop listening to either specific events ... or
	  // to every object it's currently listening to.
	  Events.stopListening =  function(obj, name, callback) {
	    var listeningTo = this._listeningTo;
	    if (!listeningTo) return this;
	
	    var ids = obj ? [obj._listenId] : _.keys(listeningTo);
	
	    for (var i = 0; i < ids.length; i++) {
	      var listening = listeningTo[ids[i]];
	
	      // If listening doesn't exist, this object is not currently
	      // listening to obj. Break out early.
	      if (!listening) break;
	
	      listening.obj.off(name, callback, this);
	    }
	    if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
	
	    return this;
	  };
	
	  // The reducing API that removes a callback from the `events` object.
	  var offApi = function(events, name, callback, options) {
	    // No events to consider.
	    if (!events) return;
	
	    var i = 0, length, listening;
	    var context = options.context, listeners = options.listeners;
	
	    // Delete all events listeners and "drop" events.
	    if (!name && !callback && !context) {
	      var ids = _.keys(listeners);
	      for (; i < ids.length; i++) {
	        listening = listeners[ids[i]];
	        delete listeners[listening.id];
	        delete listening.listeningTo[listening.objId];
	      }
	      return;
	    }
	
	    var names = name ? [name] : _.keys(events);
	    for (; i < names.length; i++) {
	      name = names[i];
	      var handlers = events[name];
	
	      // Bail out if there are no events stored.
	      if (!handlers) break;
	
	      // Replace events if there are any remaining.  Otherwise, clean up.
	      var remaining = [];
	      for (var j = 0; j < handlers.length; j++) {
	        var handler = handlers[j];
	        if (
	          callback && callback !== handler.callback &&
	            callback !== handler.callback._callback ||
	              context && context !== handler.context
	        ) {
	          remaining.push(handler);
	        } else {
	          listening = handler.listening;
	          if (listening && --listening.count === 0) {
	            delete listeners[listening.id];
	            delete listening.listeningTo[listening.objId];
	          }
	        }
	      }
	
	      // Update tail event if the list has any events.  Otherwise, clean up.
	      if (remaining.length) {
	        events[name] = remaining;
	      } else {
	        delete events[name];
	      }
	    }
	    if (_.size(events)) return events;
	  };
	
	  // Bind an event to only be triggered a single time. After the first time
	  // the callback is invoked, it will be removed. When multiple events are
	  // passed in using the space-separated syntax, the event will fire once for every
	  // event you passed in, not once for a combination of all events
	  Events.once =  function(name, callback, context) {
	    // Map the event into a `{event: once}` object.
	    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
	    return this.on(events, void 0, context);
	  };
	
	  // Inversion-of-control versions of `once`.
	  Events.listenToOnce =  function(obj, name, callback) {
	    // Map the event into a `{event: once}` object.
	    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
	    return this.listenTo(obj, events);
	  };
	
	  // Reduces the event callbacks into a map of `{event: onceWrapper}`.
	  // `offer` unbinds the `onceWrapper` after it as been called.
	  var onceMap = function(map, name, callback, offer) {
	    if (callback) {
	      var once = map[name] = _.once(function() {
	        offer(name, once);
	        callback.apply(this, arguments);
	      });
	      once._callback = callback;
	    }
	    return map;
	  };
	
	  // Trigger one or many events, firing all bound callbacks. Callbacks are
	  // passed the same arguments as `trigger` is, apart from the event name
	  // (unless you're listening on `"all"`, which will cause your callback to
	  // receive the true name of the event as the first argument).
	  Events.trigger =  function(name) {
	    if (!this._events) return this;
	
	    var length = Math.max(0, arguments.length - 1);
	    var args = Array(length);
	    for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
	
	    eventsApi(triggerApi, this._events, name, void 0, args);
	    return this;
	  };
	
	  // Handles triggering the appropriate event callbacks.
	  var triggerApi = function(objEvents, name, cb, args) {
	    if (objEvents) {
	      var events = objEvents[name];
	      var allEvents = objEvents.all;
	      if (events && allEvents) allEvents = allEvents.slice();
	      if (events) triggerEvents(events, args);
	      if (allEvents) triggerEvents(allEvents, [name].concat(args));
	    }
	    return objEvents;
	  };
	
	  // A difficult-to-believe, but optimized internal dispatch function for
	  // triggering events. Tries to keep the usual cases speedy (most internal
	  // Backbone events have 3 arguments).
	  var triggerEvents = function(events, args) {
	    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
	    switch (args.length) {
	      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
	      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
	      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
	      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
	      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
	    }
	  };
	
	  // Proxy Underscore methods to a Backbone class' prototype using a
	  // particular attribute as the data argument
	  var addMethod = function(length, method, attribute) {
	    switch (length) {
	      case 1: return function() {
	        return _[method](this[attribute]);
	      };
	      case 2: return function(value) {
	        return _[method](this[attribute], value);
	      };
	      case 3: return function(iteratee, context) {
	        return _[method](this[attribute], iteratee, context);
	      };
	      case 4: return function(iteratee, defaultVal, context) {
	        return _[method](this[attribute], iteratee, defaultVal, context);
	      };
	      default: return function() {
	        var args = slice.call(arguments);
	        args.unshift(this[attribute]);
	        return _[method].apply(_, args);
	      };
	    }
	  };
	  var addUnderscoreMethods = function(Class, methods, attribute) {
	    _.each(methods, function(length, method) {
	      if (_[method]) Class.prototype[method] = addMethod(length, method, attribute);
	    });
	  };
	
	  // Aliases for backwards compatibility.
	  Events.bind   = Events.on;
	  Events.unbind = Events.off;
	
	  // Allow the `Backbone` object to serve as a global event bus, for folks who
	  // want global "pubsub" in a convenient place.
	  _.extend(Backbone, Events);
	
	  // Backbone.Model
	  // --------------
	
	  // Backbone **Models** are the basic data object in the framework --
	  // frequently representing a row in a table in a database on your server.
	  // A discrete chunk of data and a bunch of useful, related methods for
	  // performing computations and transformations on that data.
	
	  // Create a new model with the specified attributes. A client id (`cid`)
	  // is automatically generated and assigned for you.
	  var Model = Backbone.Model = function(attributes, options) {
	    var attrs = attributes || {};
	    options || (options = {});
	    this.cid = _.uniqueId(this.cidPrefix);
	    this.attributes = {};
	    if (options.collection) this.collection = options.collection;
	    if (options.parse) attrs = this.parse(attrs, options) || {};
	    attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
	    this.set(attrs, options);
	    this.changed = {};
	    this.initialize.apply(this, arguments);
	  };
	
	  // Attach all inheritable methods to the Model prototype.
	  _.extend(Model.prototype, Events, {
	
	    // A hash of attributes whose current and previous value differ.
	    changed: null,
	
	    // The value returned during the last failed validation.
	    validationError: null,
	
	    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
	    // CouchDB users may want to set this to `"_id"`.
	    idAttribute: 'id',
	
	    // The prefix is used to create the client id which is used to identify models locally.
	    // You may want to override this if you're experiencing name clashes with model ids.
	    cidPrefix: 'c',
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // Return a copy of the model's `attributes` object.
	    toJSON: function(options) {
	      return _.clone(this.attributes);
	    },
	
	    // Proxy `Backbone.sync` by default -- but override this if you need
	    // custom syncing semantics for *this* particular model.
	    sync: function() {
	      return Backbone.sync.apply(this, arguments);
	    },
	
	    // Get the value of an attribute.
	    get: function(attr) {
	      return this.attributes[attr];
	    },
	
	    // Get the HTML-escaped value of an attribute.
	    escape: function(attr) {
	      return _.escape(this.get(attr));
	    },
	
	    // Returns `true` if the attribute contains a value that is not null
	    // or undefined.
	    has: function(attr) {
	      return this.get(attr) != null;
	    },
	
	    // Special-cased proxy to underscore's `_.matches` method.
	    matches: function(attrs) {
	      return !!_.iteratee(attrs, this)(this.attributes);
	    },
	
	    // Set a hash of model attributes on the object, firing `"change"`. This is
	    // the core primitive operation of a model, updating the data and notifying
	    // anyone who needs to know about the change in state. The heart of the beast.
	    set: function(key, val, options) {
	      var attr, attrs, unset, changes, silent, changing, prev, current;
	      if (key == null) return this;
	
	      // Handle both `"key", value` and `{key: value}` -style arguments.
	      if (typeof key === 'object') {
	        attrs = key;
	        options = val;
	      } else {
	        (attrs = {})[key] = val;
	      }
	
	      options || (options = {});
	
	      // Run validation.
	      if (!this._validate(attrs, options)) return false;
	
	      // Extract attributes and options.
	      unset           = options.unset;
	      silent          = options.silent;
	      changes         = [];
	      changing        = this._changing;
	      this._changing  = true;
	
	      if (!changing) {
	        this._previousAttributes = _.clone(this.attributes);
	        this.changed = {};
	      }
	      current = this.attributes, prev = this._previousAttributes;
	
	      // Check for changes of `id`.
	      if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
	
	      // For each `set` attribute, update or delete the current value.
	      for (attr in attrs) {
	        val = attrs[attr];
	        if (!_.isEqual(current[attr], val)) changes.push(attr);
	        if (!_.isEqual(prev[attr], val)) {
	          this.changed[attr] = val;
	        } else {
	          delete this.changed[attr];
	        }
	        unset ? delete current[attr] : current[attr] = val;
	      }
	
	      // Trigger all relevant attribute changes.
	      if (!silent) {
	        if (changes.length) this._pending = options;
	        for (var i = 0; i < changes.length; i++) {
	          this.trigger('change:' + changes[i], this, current[changes[i]], options);
	        }
	      }
	
	      // You might be wondering why there's a `while` loop here. Changes can
	      // be recursively nested within `"change"` events.
	      if (changing) return this;
	      if (!silent) {
	        while (this._pending) {
	          options = this._pending;
	          this._pending = false;
	          this.trigger('change', this, options);
	        }
	      }
	      this._pending = false;
	      this._changing = false;
	      return this;
	    },
	
	    // Remove an attribute from the model, firing `"change"`. `unset` is a noop
	    // if the attribute doesn't exist.
	    unset: function(attr, options) {
	      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
	    },
	
	    // Clear all attributes on the model, firing `"change"`.
	    clear: function(options) {
	      var attrs = {};
	      for (var key in this.attributes) attrs[key] = void 0;
	      return this.set(attrs, _.extend({}, options, {unset: true}));
	    },
	
	    // Determine if the model has changed since the last `"change"` event.
	    // If you specify an attribute name, determine if that attribute has changed.
	    hasChanged: function(attr) {
	      if (attr == null) return !_.isEmpty(this.changed);
	      return _.has(this.changed, attr);
	    },
	
	    // Return an object containing all the attributes that have changed, or
	    // false if there are no changed attributes. Useful for determining what
	    // parts of a view need to be updated and/or what attributes need to be
	    // persisted to the server. Unset attributes will be set to undefined.
	    // You can also pass an attributes object to diff against the model,
	    // determining if there *would be* a change.
	    changedAttributes: function(diff) {
	      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
	      var val, changed = false;
	      var old = this._changing ? this._previousAttributes : this.attributes;
	      for (var attr in diff) {
	        if (_.isEqual(old[attr], (val = diff[attr]))) continue;
	        (changed || (changed = {}))[attr] = val;
	      }
	      return changed;
	    },
	
	    // Get the previous value of an attribute, recorded at the time the last
	    // `"change"` event was fired.
	    previous: function(attr) {
	      if (attr == null || !this._previousAttributes) return null;
	      return this._previousAttributes[attr];
	    },
	
	    // Get all of the attributes of the model at the time of the previous
	    // `"change"` event.
	    previousAttributes: function() {
	      return _.clone(this._previousAttributes);
	    },
	
	    // Fetch the model from the server, merging the response with the model's
	    // local attributes. Any changed attributes will trigger a "change" event.
	    fetch: function(options) {
	      options = options ? _.clone(options) : {};
	      if (options.parse === void 0) options.parse = true;
	      var model = this;
	      var success = options.success;
	      options.success = function(resp) {
	        if (!model.set(model.parse(resp, options), options)) return false;
	        if (success) success.call(options.context, model, resp, options);
	        model.trigger('sync', model, resp, options);
	      };
	      wrapError(this, options);
	      return this.sync('read', this, options);
	    },
	
	    // Set a hash of model attributes, and sync the model to the server.
	    // If the server returns an attributes hash that differs, the model's
	    // state will be `set` again.
	    save: function(key, val, options) {
	      var attrs, method, xhr, attributes = this.attributes, wait;
	
	      // Handle both `"key", value` and `{key: value}` -style arguments.
	      if (key == null || typeof key === 'object') {
	        attrs = key;
	        options = val;
	      } else {
	        (attrs = {})[key] = val;
	      }
	
	      options = _.extend({validate: true}, options);
	      wait = options.wait;
	
	      // If we're not waiting and attributes exist, save acts as
	      // `set(attr).save(null, opts)` with validation. Otherwise, check if
	      // the model will be valid when the attributes, if any, are set.
	      if (attrs && !wait) {
	        if (!this.set(attrs, options)) return false;
	      } else {
	        if (!this._validate(attrs, options)) return false;
	      }
	
	      // Set temporary attributes if `{wait: true}`.
	      if (attrs && wait) {
	        this.attributes = _.extend({}, attributes, attrs);
	      }
	
	      // After a successful server-side save, the client is (optionally)
	      // updated with the server-side state.
	      if (options.parse === void 0) options.parse = true;
	      var model = this;
	      var success = options.success;
	      options.success = function(resp) {
	        // Ensure attributes are restored during synchronous saves.
	        model.attributes = attributes;
	        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
	        if (wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
	        if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
	          return false;
	        }
	        if (success) success.call(options.context, model, resp, options);
	        model.trigger('sync', model, resp, options);
	      };
	      wrapError(this, options);
	
	      method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
	      if (method === 'patch' && !options.attrs) options.attrs = attrs;
	      xhr = this.sync(method, this, options);
	
	      // Restore attributes.
	      if (attrs && wait) this.attributes = attributes;
	
	      return xhr;
	    },
	
	    // Destroy this model on the server if it was already persisted.
	    // Optimistically removes the model from its collection, if it has one.
	    // If `wait: true` is passed, waits for the server to respond before removal.
	    destroy: function(options) {
	      options = options ? _.clone(options) : {};
	      var model = this;
	      var success = options.success;
	      var wait = options.wait;
	
	      var destroy = function() {
	        model.stopListening();
	        model.trigger('destroy', model, model.collection, options);
	      };
	
	      options.success = function(resp) {
	        if (wait) destroy();
	        if (success) success.call(options.context, model, resp, options);
	        if (!model.isNew()) model.trigger('sync', model, resp, options);
	      };
	
	      var xhr = false;
	      if (this.isNew()) {
	        _.defer(options.success);
	      } else {
	        wrapError(this, options);
	        xhr = this.sync('delete', this, options);
	      }
	      if (!wait) destroy();
	      return xhr;
	    },
	
	    // Default URL for the model's representation on the server -- if you're
	    // using Backbone's restful methods, override this to change the endpoint
	    // that will be called.
	    url: function() {
	      var base =
	        _.result(this, 'urlRoot') ||
	        _.result(this.collection, 'url') ||
	        urlError();
	      if (this.isNew()) return base;
	      var id = this.id || this.attributes[this.idAttribute];
	      return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(id);
	    },
	
	    // **parse** converts a response into the hash of attributes to be `set` on
	    // the model. The default implementation is just to pass the response along.
	    parse: function(resp, options) {
	      return resp;
	    },
	
	    // Create a new model with identical attributes to this one.
	    clone: function() {
	      return new this.constructor(this.attributes);
	    },
	
	    // A model is new if it has never been saved to the server, and lacks an id.
	    isNew: function() {
	      return !this.has(this.idAttribute);
	    },
	
	    // Check if the model is currently in a valid state.
	    isValid: function(options) {
	      return this._validate({}, _.extend(options || {}, { validate: true }));
	    },
	
	    // Run validation against the next complete set of model attributes,
	    // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
	    _validate: function(attrs, options) {
	      if (!options.validate || !this.validate) return true;
	      attrs = _.extend({}, this.attributes, attrs);
	      var error = this.validationError = this.validate(attrs, options) || null;
	      if (!error) return true;
	      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
	      return false;
	    }
	
	  });
	
	  // Underscore methods that we want to implement on the Model.
	  var modelMethods = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
	      omit: 0, chain: 1, isEmpty: 1 };
	
	  // Mix in each Underscore method as a proxy to `Model#attributes`.
	  addUnderscoreMethods(Model, modelMethods, 'attributes');
	
	  // Backbone.Collection
	  // -------------------
	
	  // If models tend to represent a single row of data, a Backbone Collection is
	  // more analogous to a table full of data ... or a small slice or page of that
	  // table, or a collection of rows that belong together for a particular reason
	  // -- all of the messages in this particular folder, all of the documents
	  // belonging to this particular author, and so on. Collections maintain
	  // indexes of their models, both in order, and for lookup by `id`.
	
	  // Create a new **Collection**, perhaps to contain a specific type of `model`.
	  // If a `comparator` is specified, the Collection will maintain
	  // its models in sort order, as they're added and removed.
	  var Collection = Backbone.Collection = function(models, options) {
	    options || (options = {});
	    if (options.model) this.model = options.model;
	    if (options.comparator !== void 0) this.comparator = options.comparator;
	    this._reset();
	    this.initialize.apply(this, arguments);
	    if (models) this.reset(models, _.extend({silent: true}, options));
	  };
	
	  // Default options for `Collection#set`.
	  var setOptions = {add: true, remove: true, merge: true};
	  var addOptions = {add: true, remove: false};
	
	  // Define the Collection's inheritable methods.
	  _.extend(Collection.prototype, Events, {
	
	    // The default model for a collection is just a **Backbone.Model**.
	    // This should be overridden in most cases.
	    model: Model,
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // The JSON representation of a Collection is an array of the
	    // models' attributes.
	    toJSON: function(options) {
	      return this.map(function(model){ return model.toJSON(options); });
	    },
	
	    // Proxy `Backbone.sync` by default.
	    sync: function() {
	      return Backbone.sync.apply(this, arguments);
	    },
	
	    // Add a model, or list of models to the set.
	    add: function(models, options) {
	      return this.set(models, _.extend({merge: false}, options, addOptions));
	    },
	
	    // Remove a model, or a list of models from the set.
	    remove: function(models, options) {
	      var singular = !_.isArray(models), removed;
	      models = singular ? [models] : _.clone(models);
	      options || (options = {});
	      removed = this._removeModels(models, options);
	      if (!options.silent && removed) this.trigger('update', this, options);
	      return singular ? models[0] : models;
	    },
	
	    // Update a collection by `set`-ing a new list of models, adding new ones,
	    // removing models that are no longer present, and merging models that
	    // already exist in the collection, as necessary. Similar to **Model#set**,
	    // the core operation for updating the data contained by the collection.
	    set: function(models, options) {
	      options = _.defaults({}, options, setOptions);
	      if (options.parse) models = this.parse(models, options);
	      var singular = !_.isArray(models);
	      models = singular ? (models ? [models] : []) : models.slice();
	      var id, model, attrs, existing, sort;
	      var at = options.at;
	      if (at != null) at = +at;
	      if (at < 0) at += this.length + 1;
	      var sortable = this.comparator && (at == null) && options.sort !== false;
	      var sortAttr = _.isString(this.comparator) ? this.comparator : null;
	      var toAdd = [], toRemove = [], modelMap = {};
	      var add = options.add, merge = options.merge, remove = options.remove;
	      var order = !sortable && add && remove ? [] : false;
	      var orderChanged = false;
	
	      // Turn bare objects into model references, and prevent invalid models
	      // from being added.
	      for (var i = 0; i < models.length; i++) {
	        attrs = models[i];
	
	        // If a duplicate is found, prevent it from being added and
	        // optionally merge it into the existing model.
	        if (existing = this.get(attrs)) {
	          if (remove) modelMap[existing.cid] = true;
	          if (merge && attrs !== existing) {
	            attrs = this._isModel(attrs) ? attrs.attributes : attrs;
	            if (options.parse) attrs = existing.parse(attrs, options);
	            existing.set(attrs, options);
	            if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
	          }
	          models[i] = existing;
	
	        // If this is a new, valid model, push it to the `toAdd` list.
	        } else if (add) {
	          model = models[i] = this._prepareModel(attrs, options);
	          if (!model) continue;
	          toAdd.push(model);
	          this._addReference(model, options);
	        }
	
	        // Do not add multiple models with the same `id`.
	        model = existing || model;
	        if (!model) continue;
	        id = this.modelId(model.attributes);
	        if (order && (model.isNew() || !modelMap[id])) {
	          order.push(model);
	
	          // Check to see if this is actually a new model at this index.
	          orderChanged = orderChanged || !this.models[i] || model.cid !== this.models[i].cid;
	        }
	
	        modelMap[id] = true;
	      }
	
	      // Remove nonexistent models if appropriate.
	      if (remove) {
	        for (var i = 0; i < this.length; i++) {
	          if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
	        }
	        if (toRemove.length) this._removeModels(toRemove, options);
	      }
	
	      // See if sorting is needed, update `length` and splice in new models.
	      if (toAdd.length || orderChanged) {
	        if (sortable) sort = true;
	        this.length += toAdd.length;
	        if (at != null) {
	          for (var i = 0; i < toAdd.length; i++) {
	            this.models.splice(at + i, 0, toAdd[i]);
	          }
	        } else {
	          if (order) this.models.length = 0;
	          var orderedModels = order || toAdd;
	          for (var i = 0; i < orderedModels.length; i++) {
	            this.models.push(orderedModels[i]);
	          }
	        }
	      }
	
	      // Silently sort the collection if appropriate.
	      if (sort) this.sort({silent: true});
	
	      // Unless silenced, it's time to fire all appropriate add/sort events.
	      if (!options.silent) {
	        var addOpts = at != null ? _.clone(options) : options;
	        for (var i = 0; i < toAdd.length; i++) {
	          if (at != null) addOpts.index = at + i;
	          (model = toAdd[i]).trigger('add', model, this, addOpts);
	        }
	        if (sort || orderChanged) this.trigger('sort', this, options);
	        if (toAdd.length || toRemove.length) this.trigger('update', this, options);
	      }
	
	      // Return the added (or merged) model (or models).
	      return singular ? models[0] : models;
	    },
	
	    // When you have more items than you want to add or remove individually,
	    // you can reset the entire set with a new list of models, without firing
	    // any granular `add` or `remove` events. Fires `reset` when finished.
	    // Useful for bulk operations and optimizations.
	    reset: function(models, options) {
	      options = options ? _.clone(options) : {};
	      for (var i = 0; i < this.models.length; i++) {
	        this._removeReference(this.models[i], options);
	      }
	      options.previousModels = this.models;
	      this._reset();
	      models = this.add(models, _.extend({silent: true}, options));
	      if (!options.silent) this.trigger('reset', this, options);
	      return models;
	    },
	
	    // Add a model to the end of the collection.
	    push: function(model, options) {
	      return this.add(model, _.extend({at: this.length}, options));
	    },
	
	    // Remove a model from the end of the collection.
	    pop: function(options) {
	      var model = this.at(this.length - 1);
	      this.remove(model, options);
	      return model;
	    },
	
	    // Add a model to the beginning of the collection.
	    unshift: function(model, options) {
	      return this.add(model, _.extend({at: 0}, options));
	    },
	
	    // Remove a model from the beginning of the collection.
	    shift: function(options) {
	      var model = this.at(0);
	      this.remove(model, options);
	      return model;
	    },
	
	    // Slice out a sub-array of models from the collection.
	    slice: function() {
	      return slice.apply(this.models, arguments);
	    },
	
	    // Get a model from the set by id.
	    get: function(obj) {
	      if (obj == null) return void 0;
	      var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
	      return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
	    },
	
	    // Get the model at the given index.
	    at: function(index) {
	      if (index < 0) index += this.length;
	      return this.models[index];
	    },
	
	    // Return models with matching attributes. Useful for simple cases of
	    // `filter`.
	    where: function(attrs, first) {
	      var matches = _.matches(attrs);
	      return this[first ? 'find' : 'filter'](function(model) {
	        return matches(model.attributes);
	      });
	    },
	
	    // Return the first model with matching attributes. Useful for simple cases
	    // of `find`.
	    findWhere: function(attrs) {
	      return this.where(attrs, true);
	    },
	
	    // Force the collection to re-sort itself. You don't need to call this under
	    // normal circumstances, as the set will maintain sort order as each item
	    // is added.
	    sort: function(options) {
	      if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
	      options || (options = {});
	
	      // Run sort based on type of `comparator`.
	      if (_.isString(this.comparator) || this.comparator.length === 1) {
	        this.models = this.sortBy(this.comparator, this);
	      } else {
	        this.models.sort(_.bind(this.comparator, this));
	      }
	
	      if (!options.silent) this.trigger('sort', this, options);
	      return this;
	    },
	
	    // Pluck an attribute from each model in the collection.
	    pluck: function(attr) {
	      return _.invoke(this.models, 'get', attr);
	    },
	
	    // Fetch the default set of models for this collection, resetting the
	    // collection when they arrive. If `reset: true` is passed, the response
	    // data will be passed through the `reset` method instead of `set`.
	    fetch: function(options) {
	      options = options ? _.clone(options) : {};
	      if (options.parse === void 0) options.parse = true;
	      var success = options.success;
	      var collection = this;
	      options.success = function(resp) {
	        var method = options.reset ? 'reset' : 'set';
	        collection[method](resp, options);
	        if (success) success.call(options.context, collection, resp, options);
	        collection.trigger('sync', collection, resp, options);
	      };
	      wrapError(this, options);
	      return this.sync('read', this, options);
	    },
	
	    // Create a new instance of a model in this collection. Add the model to the
	    // collection immediately, unless `wait: true` is passed, in which case we
	    // wait for the server to agree.
	    create: function(model, options) {
	      options = options ? _.clone(options) : {};
	      var wait = options.wait;
	      if (!(model = this._prepareModel(model, options))) return false;
	      if (!wait) this.add(model, options);
	      var collection = this;
	      var success = options.success;
	      options.success = function(model, resp, callbackOpts) {
	        if (wait) collection.add(model, callbackOpts);
	        if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
	      };
	      model.save(null, options);
	      return model;
	    },
	
	    // **parse** converts a response into a list of models to be added to the
	    // collection. The default implementation is just to pass it through.
	    parse: function(resp, options) {
	      return resp;
	    },
	
	    // Create a new collection with an identical list of models as this one.
	    clone: function() {
	      return new this.constructor(this.models, {
	        model: this.model,
	        comparator: this.comparator
	      });
	    },
	
	    // Define how to uniquely identify models in the collection.
	    modelId: function (attrs) {
	      return attrs[this.model.prototype.idAttribute || 'id'];
	    },
	
	    // Private method to reset all internal state. Called when the collection
	    // is first initialized or reset.
	    _reset: function() {
	      this.length = 0;
	      this.models = [];
	      this._byId  = {};
	    },
	
	    // Prepare a hash of attributes (or other model) to be added to this
	    // collection.
	    _prepareModel: function(attrs, options) {
	      if (this._isModel(attrs)) {
	        if (!attrs.collection) attrs.collection = this;
	        return attrs;
	      }
	      options = options ? _.clone(options) : {};
	      options.collection = this;
	      var model = new this.model(attrs, options);
	      if (!model.validationError) return model;
	      this.trigger('invalid', this, model.validationError, options);
	      return false;
	    },
	
	    // Internal method called by both remove and set. Does not trigger any
	    // additional events. Returns true if anything was actually removed.
	    _removeModels: function(models, options) {
	      var i, l, index, model, removed = false;
	      for (var i = 0, j = 0; i < models.length; i++) {
	        var model = models[i] = this.get(models[i]);
	        if (!model) continue;
	        var id = this.modelId(model.attributes);
	        if (id != null) delete this._byId[id];
	        delete this._byId[model.cid];
	        var index = this.indexOf(model);
	        this.models.splice(index, 1);
	        this.length--;
	        if (!options.silent) {
	          options.index = index;
	          model.trigger('remove', model, this, options);
	        }
	        models[j++] = model;
	        this._removeReference(model, options);
	        removed = true;
	      }
	      // We only need to slice if models array should be smaller, which is
	      // caused by some models not actually getting removed.
	      if (models.length !== j) models = models.slice(0, j);
	      return removed;
	    },
	
	    // Method for checking whether an object should be considered a model for
	    // the purposes of adding to the collection.
	    _isModel: function (model) {
	      return model instanceof Model;
	    },
	
	    // Internal method to create a model's ties to a collection.
	    _addReference: function(model, options) {
	      this._byId[model.cid] = model;
	      var id = this.modelId(model.attributes);
	      if (id != null) this._byId[id] = model;
	      model.on('all', this._onModelEvent, this);
	    },
	
	    // Internal method to sever a model's ties to a collection.
	    _removeReference: function(model, options) {
	      if (this === model.collection) delete model.collection;
	      model.off('all', this._onModelEvent, this);
	    },
	
	    // Internal method called every time a model in the set fires an event.
	    // Sets need to update their indexes when models change ids. All other
	    // events simply proxy through. "add" and "remove" events that originate
	    // in other collections are ignored.
	    _onModelEvent: function(event, model, collection, options) {
	      if ((event === 'add' || event === 'remove') && collection !== this) return;
	      if (event === 'destroy') this.remove(model, options);
	      if (event === 'change') {
	        var prevId = this.modelId(model.previousAttributes());
	        var id = this.modelId(model.attributes);
	        if (prevId !== id) {
	          if (prevId != null) delete this._byId[prevId];
	          if (id != null) this._byId[id] = model;
	        }
	      }
	      this.trigger.apply(this, arguments);
	    }
	
	  });
	
	  // Underscore methods that we want to implement on the Collection.
	  // 90% of the core usefulness of Backbone Collections is actually implemented
	  // right here:
	  var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
	      foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
	      select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 2,
	      contains: 2, invoke: 2, max: 3, min: 3, toArray: 1, size: 1, first: 3,
	      head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
	      without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
	      isEmpty: 1, chain: 1, sample: 3, partition: 3 };
	
	  // Mix in each Underscore method as a proxy to `Collection#models`.
	  addUnderscoreMethods(Collection, collectionMethods, 'models');
	
	  // Underscore methods that take a property name as an argument.
	  var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
	
	  // Use attributes instead of properties.
	  _.each(attributeMethods, function(method) {
	    if (!_[method]) return;
	    Collection.prototype[method] = function(value, context) {
	      var iterator = _.isFunction(value) ? value : function(model) {
	        return model.get(value);
	      };
	      return _[method](this.models, iterator, context);
	    };
	  });
	
	  // Backbone.View
	  // -------------
	
	  // Backbone Views are almost more convention than they are actual code. A View
	  // is simply a JavaScript object that represents a logical chunk of UI in the
	  // DOM. This might be a single item, an entire list, a sidebar or panel, or
	  // even the surrounding frame which wraps your whole app. Defining a chunk of
	  // UI as a **View** allows you to define your DOM events declaratively, without
	  // having to worry about render order ... and makes it easy for the view to
	  // react to specific changes in the state of your models.
	
	  // Creating a Backbone.View creates its initial element outside of the DOM,
	  // if an existing element is not provided...
	  var View = Backbone.View = function(options) {
	    this.cid = _.uniqueId('view');
	    options || (options = {});
	    _.extend(this, _.pick(options, viewOptions));
	    this._ensureElement();
	    this.initialize.apply(this, arguments);
	  };
	
	  // Cached regex to split keys for `delegate`.
	  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
	
	  // List of view options to be merged as properties.
	  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
	
	  // Set up all inheritable **Backbone.View** properties and methods.
	  _.extend(View.prototype, Events, {
	
	    // The default `tagName` of a View's element is `"div"`.
	    tagName: 'div',
	
	    // jQuery delegate for element lookup, scoped to DOM elements within the
	    // current view. This should be preferred to global lookups where possible.
	    $: function(selector) {
	      return this.$el.find(selector);
	    },
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // **render** is the core function that your view should override, in order
	    // to populate its element (`this.el`), with the appropriate HTML. The
	    // convention is for **render** to always return `this`.
	    render: function() {
	      return this;
	    },
	
	    // Remove this view by taking the element out of the DOM, and removing any
	    // applicable Backbone.Events listeners.
	    remove: function() {
	      this._removeElement();
	      this.stopListening();
	      return this;
	    },
	
	    // Remove this view's element from the document and all event listeners
	    // attached to it. Exposed for subclasses using an alternative DOM
	    // manipulation API.
	    _removeElement: function() {
	      this.$el.remove();
	    },
	
	    // Change the view's element (`this.el` property) and re-delegate the
	    // view's events on the new element.
	    setElement: function(element) {
	      this.undelegateEvents();
	      this._setElement(element);
	      this.delegateEvents();
	      return this;
	    },
	
	    // Creates the `this.el` and `this.$el` references for this view using the
	    // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
	    // context or an element. Subclasses can override this to utilize an
	    // alternative DOM manipulation API and are only required to set the
	    // `this.el` property.
	    _setElement: function(el) {
	      this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
	      this.el = this.$el[0];
	    },
	
	    // Set callbacks, where `this.events` is a hash of
	    //
	    // *{"event selector": "callback"}*
	    //
	    //     {
	    //       'mousedown .title':  'edit',
	    //       'click .button':     'save',
	    //       'click .open':       function(e) { ... }
	    //     }
	    //
	    // pairs. Callbacks will be bound to the view, with `this` set properly.
	    // Uses event delegation for efficiency.
	    // Omitting the selector binds the event to `this.el`.
	    delegateEvents: function(events) {
	      if (!(events || (events = _.result(this, 'events')))) return this;
	      this.undelegateEvents();
	      for (var key in events) {
	        var method = events[key];
	        if (!_.isFunction(method)) method = this[events[key]];
	        if (!method) continue;
	        var match = key.match(delegateEventSplitter);
	        this.delegate(match[1], match[2], _.bind(method, this));
	      }
	      return this;
	    },
	
	    // Add a single event listener to the view's element (or a child element
	    // using `selector`). This only works for delegate-able events: not `focus`,
	    // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
	    delegate: function(eventName, selector, listener) {
	      this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
	    },
	
	    // Clears all callbacks previously bound to the view by `delegateEvents`.
	    // You usually don't need to use this, but may wish to if you have multiple
	    // Backbone views attached to the same DOM element.
	    undelegateEvents: function() {
	      if (this.$el) this.$el.off('.delegateEvents' + this.cid);
	      return this;
	    },
	
	    // A finer-grained `undelegateEvents` for removing a single delegated event.
	    // `selector` and `listener` are both optional.
	    undelegate: function(eventName, selector, listener) {
	      this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
	    },
	
	    // Produces a DOM element to be assigned to your view. Exposed for
	    // subclasses using an alternative DOM manipulation API.
	    _createElement: function(tagName) {
	      return document.createElement(tagName);
	    },
	
	    // Ensure that the View has a DOM element to render into.
	    // If `this.el` is a string, pass it through `$()`, take the first
	    // matching element, and re-assign it to `el`. Otherwise, create
	    // an element from the `id`, `className` and `tagName` properties.
	    _ensureElement: function() {
	      if (!this.el) {
	        var attrs = _.extend({}, _.result(this, 'attributes'));
	        if (this.id) attrs.id = _.result(this, 'id');
	        if (this.className) attrs['class'] = _.result(this, 'className');
	        this.setElement(this._createElement(_.result(this, 'tagName')));
	        this._setAttributes(attrs);
	      } else {
	        this.setElement(_.result(this, 'el'));
	      }
	    },
	
	    // Set attributes from a hash on this view's element.  Exposed for
	    // subclasses using an alternative DOM manipulation API.
	    _setAttributes: function(attributes) {
	      this.$el.attr(attributes);
	    }
	
	  });
	
	  // Backbone.sync
	  // -------------
	
	  // Override this function to change the manner in which Backbone persists
	  // models to the server. You will be passed the type of request, and the
	  // model in question. By default, makes a RESTful Ajax request
	  // to the model's `url()`. Some possible customizations could be:
	  //
	  // * Use `setTimeout` to batch rapid-fire updates into a single request.
	  // * Send up the models as XML instead of JSON.
	  // * Persist models via WebSockets instead of Ajax.
	  //
	  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
	  // as `POST`, with a `_method` parameter containing the true HTTP method,
	  // as well as all requests with the body as `application/x-www-form-urlencoded`
	  // instead of `application/json` with the model in a param named `model`.
	  // Useful when interfacing with server-side languages like **PHP** that make
	  // it difficult to read the body of `PUT` requests.
	  Backbone.sync = function(method, model, options) {
	    var type = methodMap[method];
	
	    // Default options, unless specified.
	    _.defaults(options || (options = {}), {
	      emulateHTTP: Backbone.emulateHTTP,
	      emulateJSON: Backbone.emulateJSON
	    });
	
	    // Default JSON-request options.
	    var params = {type: type, dataType: 'json'};
	
	    // Ensure that we have a URL.
	    if (!options.url) {
	      params.url = _.result(model, 'url') || urlError();
	    }
	
	    // Ensure that we have the appropriate request data.
	    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
	      params.contentType = 'application/json';
	      params.data = JSON.stringify(options.attrs || model.toJSON(options));
	    }
	
	    // For older servers, emulate JSON by encoding the request into an HTML-form.
	    if (options.emulateJSON) {
	      params.contentType = 'application/x-www-form-urlencoded';
	      params.data = params.data ? {model: params.data} : {};
	    }
	
	    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
	    // And an `X-HTTP-Method-Override` header.
	    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
	      params.type = 'POST';
	      if (options.emulateJSON) params.data._method = type;
	      var beforeSend = options.beforeSend;
	      options.beforeSend = function(xhr) {
	        xhr.setRequestHeader('X-HTTP-Method-Override', type);
	        if (beforeSend) return beforeSend.apply(this, arguments);
	      };
	    }
	
	    // Don't process data on a non-GET request.
	    if (params.type !== 'GET' && !options.emulateJSON) {
	      params.processData = false;
	    }
	
	    // Pass along `textStatus` and `errorThrown` from jQuery.
	    var error = options.error;
	    options.error = function(xhr, textStatus, errorThrown) {
	      options.textStatus = textStatus;
	      options.errorThrown = errorThrown;
	      if (error) error.call(options.context, xhr, textStatus, errorThrown);
	    };
	
	    // Make the request, allowing the user to override any Ajax options.
	    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
	    model.trigger('request', model, xhr, options);
	    return xhr;
	  };
	
	  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
	  var methodMap = {
	    'create': 'POST',
	    'update': 'PUT',
	    'patch':  'PATCH',
	    'delete': 'DELETE',
	    'read':   'GET'
	  };
	
	  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
	  // Override this if you'd like to use a different library.
	  Backbone.ajax = function() {
	    return Backbone.$.ajax.apply(Backbone.$, arguments);
	  };
	
	  // Backbone.Router
	  // ---------------
	
	  // Routers map faux-URLs to actions, and fire events when routes are
	  // matched. Creating a new one sets its `routes` hash, if not set statically.
	  var Router = Backbone.Router = function(options) {
	    options || (options = {});
	    if (options.routes) this.routes = options.routes;
	    this._bindRoutes();
	    this.initialize.apply(this, arguments);
	  };
	
	  // Cached regular expressions for matching named param parts and splatted
	  // parts of route strings.
	  var optionalParam = /\((.*?)\)/g;
	  var namedParam    = /(\(\?)?:\w+/g;
	  var splatParam    = /\*\w+/g;
	  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
	
	  // Set up all inheritable **Backbone.Router** properties and methods.
	  _.extend(Router.prototype, Events, {
	
	    // Initialize is an empty function by default. Override it with your own
	    // initialization logic.
	    initialize: function(){},
	
	    // Manually bind a single named route to a callback. For example:
	    //
	    //     this.route('search/:query/p:num', 'search', function(query, num) {
	    //       ...
	    //     });
	    //
	    route: function(route, name, callback) {
	      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
	      if (_.isFunction(name)) {
	        callback = name;
	        name = '';
	      }
	      if (!callback) callback = this[name];
	      var router = this;
	      Backbone.history.route(route, function(fragment) {
	        var args = router._extractParameters(route, fragment);
	        if (router.execute(callback, args, name) !== false) {
	          router.trigger.apply(router, ['route:' + name].concat(args));
	          router.trigger('route', name, args);
	          Backbone.history.trigger('route', router, name, args);
	        }
	      });
	      return this;
	    },
	
	    // Execute a route handler with the provided parameters.  This is an
	    // excellent place to do pre-route setup or post-route cleanup.
	    execute: function(callback, args, name) {
	      if (callback) callback.apply(this, args);
	    },
	
	    // Simple proxy to `Backbone.history` to save a fragment into the history.
	    navigate: function(fragment, options) {
	      Backbone.history.navigate(fragment, options);
	      return this;
	    },
	
	    // Bind all defined routes to `Backbone.history`. We have to reverse the
	    // order of the routes here to support behavior where the most general
	    // routes can be defined at the bottom of the route map.
	    _bindRoutes: function() {
	      if (!this.routes) return;
	      this.routes = _.result(this, 'routes');
	      var route, routes = _.keys(this.routes);
	      while ((route = routes.pop()) != null) {
	        this.route(route, this.routes[route]);
	      }
	    },
	
	    // Convert a route string into a regular expression, suitable for matching
	    // against the current location hash.
	    _routeToRegExp: function(route) {
	      route = route.replace(escapeRegExp, '\\$&')
	                   .replace(optionalParam, '(?:$1)?')
	                   .replace(namedParam, function(match, optional) {
	                     return optional ? match : '([^/?]+)';
	                   })
	                   .replace(splatParam, '([^?]*?)');
	      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
	    },
	
	    // Given a route, and a URL fragment that it matches, return the array of
	    // extracted decoded parameters. Empty or unmatched parameters will be
	    // treated as `null` to normalize cross-browser behavior.
	    _extractParameters: function(route, fragment) {
	      var params = route.exec(fragment).slice(1);
	      return _.map(params, function(param, i) {
	        // Don't decode the search params.
	        if (i === params.length - 1) return param || null;
	        return param ? decodeURIComponent(param) : null;
	      });
	    }
	
	  });
	
	  // Backbone.History
	  // ----------------
	
	  // Handles cross-browser history management, based on either
	  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
	  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
	  // and URL fragments. If the browser supports neither (old IE, natch),
	  // falls back to polling.
	  var History = Backbone.History = function() {
	    this.handlers = [];
	    _.bindAll(this, 'checkUrl');
	
	    // Ensure that `History` can be used outside of the browser.
	    if (typeof window !== 'undefined') {
	      this.location = window.location;
	      this.history = window.history;
	    }
	  };
	
	  // Cached regex for stripping a leading hash/slash and trailing space.
	  var routeStripper = /^[#\/]|\s+$/g;
	
	  // Cached regex for stripping leading and trailing slashes.
	  var rootStripper = /^\/+|\/+$/g;
	
	  // Cached regex for stripping urls of hash.
	  var pathStripper = /#.*$/;
	
	  // Has the history handling already been started?
	  History.started = false;
	
	  // Set up all inheritable **Backbone.History** properties and methods.
	  _.extend(History.prototype, Events, {
	
	    // The default interval to poll for hash changes, if necessary, is
	    // twenty times a second.
	    interval: 50,
	
	    // Are we at the app root?
	    atRoot: function() {
	      var path = this.location.pathname.replace(/[^\/]$/, '$&/');
	      return path === this.root && !this.getSearch();
	    },
	
	    // Does the pathname match the root?
	    matchRoot: function() {
	      var path = this.decodeFragment(this.location.pathname);
	      var root = path.slice(0, this.root.length - 1) + '/';
	      return root === this.root;
	    },
	
	    // Unicode characters in `location.pathname` are percent encoded so they're
	    // decoded for comparison. `%25` should not be decoded since it may be part
	    // of an encoded parameter.
	    decodeFragment: function(fragment) {
	      return decodeURI(fragment.replace(/%25/g, '%2525'));
	    },
	
	    // In IE6, the hash fragment and search params are incorrect if the
	    // fragment contains `?`.
	    getSearch: function() {
	      var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
	      return match ? match[0] : '';
	    },
	
	    // Gets the true hash value. Cannot use location.hash directly due to bug
	    // in Firefox where location.hash will always be decoded.
	    getHash: function(window) {
	      var match = (window || this).location.href.match(/#(.*)$/);
	      return match ? match[1] : '';
	    },
	
	    // Get the pathname and search params, without the root.
	    getPath: function() {
	      var path = this.decodeFragment(
	        this.location.pathname + this.getSearch()
	      ).slice(this.root.length - 1);
	      return path.charAt(0) === '/' ? path.slice(1) : path;
	    },
	
	    // Get the cross-browser normalized URL fragment from the path or hash.
	    getFragment: function(fragment) {
	      if (fragment == null) {
	        if (this._usePushState || !this._wantsHashChange) {
	          fragment = this.getPath();
	        } else {
	          fragment = this.getHash();
	        }
	      }
	      return fragment.replace(routeStripper, '');
	    },
	
	    // Start the hash change handling, returning `true` if the current URL matches
	    // an existing route, and `false` otherwise.
	    start: function(options) {
	      if (History.started) throw new Error('Backbone.history has already been started');
	      History.started = true;
	
	      // Figure out the initial configuration. Do we need an iframe?
	      // Is pushState desired ... is it available?
	      this.options          = _.extend({root: '/'}, this.options, options);
	      this.root             = this.options.root;
	      this._wantsHashChange = this.options.hashChange !== false;
	      this._hasHashChange   = 'onhashchange' in window;
	      this._useHashChange   = this._wantsHashChange && this._hasHashChange;
	      this._wantsPushState  = !!this.options.pushState;
	      this._hasPushState    = !!(this.history && this.history.pushState);
	      this._usePushState    = this._wantsPushState && this._hasPushState;
	      this.fragment         = this.getFragment();
	
	      // Normalize root to always include a leading and trailing slash.
	      this.root = ('/' + this.root + '/').replace(rootStripper, '/');
	
	      // Transition from hashChange to pushState or vice versa if both are
	      // requested.
	      if (this._wantsHashChange && this._wantsPushState) {
	
	        // If we've started off with a route from a `pushState`-enabled
	        // browser, but we're currently in a browser that doesn't support it...
	        if (!this._hasPushState && !this.atRoot()) {
	          var root = this.root.slice(0, -1) || '/';
	          this.location.replace(root + '#' + this.getPath());
	          // Return immediately as browser will do redirect to new url
	          return true;
	
	        // Or if we've started out with a hash-based route, but we're currently
	        // in a browser where it could be `pushState`-based instead...
	        } else if (this._hasPushState && this.atRoot()) {
	          this.navigate(this.getHash(), {replace: true});
	        }
	
	      }
	
	      // Proxy an iframe to handle location events if the browser doesn't
	      // support the `hashchange` event, HTML5 history, or the user wants
	      // `hashChange` but not `pushState`.
	      if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
	        var iframe = document.createElement('iframe');
	        iframe.src = 'javascript:0';
	        iframe.style.display = 'none';
	        iframe.tabIndex = -1;
	        var body = document.body;
	        // Using `appendChild` will throw on IE < 9 if the document is not ready.
	        this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow;
	        this.iframe.document.open().close();
	        this.iframe.location.hash = '#' + this.fragment;
	      }
	
	      // Add a cross-platform `addEventListener` shim for older browsers.
	      var addEventListener = window.addEventListener || function (eventName, listener) {
	        return attachEvent('on' + eventName, listener);
	      };
	
	      // Depending on whether we're using pushState or hashes, and whether
	      // 'onhashchange' is supported, determine how we check the URL state.
	      if (this._usePushState) {
	        addEventListener('popstate', this.checkUrl, false);
	      } else if (this._useHashChange && !this.iframe) {
	        addEventListener('hashchange', this.checkUrl, false);
	      } else if (this._wantsHashChange) {
	        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
	      }
	
	      if (!this.options.silent) return this.loadUrl();
	    },
	
	    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
	    // but possibly useful for unit testing Routers.
	    stop: function() {
	      // Add a cross-platform `removeEventListener` shim for older browsers.
	      var removeEventListener = window.removeEventListener || function (eventName, listener) {
	        return detachEvent('on' + eventName, listener);
	      };
	
	      // Remove window listeners.
	      if (this._usePushState) {
	        removeEventListener('popstate', this.checkUrl, false);
	      } else if (this._useHashChange && !this.iframe) {
	        removeEventListener('hashchange', this.checkUrl, false);
	      }
	
	      // Clean up the iframe if necessary.
	      if (this.iframe) {
	        document.body.removeChild(this.iframe.frameElement);
	        this.iframe = null;
	      }
	
	      // Some environments will throw when clearing an undefined interval.
	      if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
	      History.started = false;
	    },
	
	    // Add a route to be tested when the fragment changes. Routes added later
	    // may override previous routes.
	    route: function(route, callback) {
	      this.handlers.unshift({route: route, callback: callback});
	    },
	
	    // Checks the current URL to see if it has changed, and if it has,
	    // calls `loadUrl`, normalizing across the hidden iframe.
	    checkUrl: function(e) {
	      var current = this.getFragment();
	
	      // If the user pressed the back button, the iframe's hash will have
	      // changed and we should use that for comparison.
	      if (current === this.fragment && this.iframe) {
	        current = this.getHash(this.iframe);
	      }
	
	      if (current === this.fragment) return false;
	      if (this.iframe) this.navigate(current);
	      this.loadUrl();
	    },
	
	    // Attempt to load the current URL fragment. If a route succeeds with a
	    // match, returns `true`. If no defined routes matches the fragment,
	    // returns `false`.
	    loadUrl: function(fragment) {
	      // If the root doesn't match, no routes can match either.
	      if (!this.matchRoot()) return false;
	      fragment = this.fragment = this.getFragment(fragment);
	      return _.any(this.handlers, function(handler) {
	        if (handler.route.test(fragment)) {
	          handler.callback(fragment);
	          return true;
	        }
	      });
	    },
	
	    // Save a fragment into the hash history, or replace the URL state if the
	    // 'replace' option is passed. You are responsible for properly URL-encoding
	    // the fragment in advance.
	    //
	    // The options object can contain `trigger: true` if you wish to have the
	    // route callback be fired (not usually desirable), or `replace: true`, if
	    // you wish to modify the current URL without adding an entry to the history.
	    navigate: function(fragment, options) {
	      if (!History.started) return false;
	      if (!options || options === true) options = {trigger: !!options};
	
	      // Normalize the fragment.
	      fragment = this.getFragment(fragment || '');
	
	      // Don't include a trailing slash on the root.
	      var root = this.root;
	      if (fragment === '' || fragment.charAt(0) === '?') {
	        root = root.slice(0, -1) || '/';
	      }
	      var url = root + fragment;
	
	      // Strip the hash and decode for matching.
	      fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
	
	      if (this.fragment === fragment) return;
	      this.fragment = fragment;
	
	      // If pushState is available, we use it to set the fragment as a real URL.
	      if (this._usePushState) {
	        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
	
	      // If hash changes haven't been explicitly disabled, update the hash
	      // fragment to store history.
	      } else if (this._wantsHashChange) {
	        this._updateHash(this.location, fragment, options.replace);
	        if (this.iframe && (fragment !== this.getHash(this.iframe))) {
	          // Opening and closing the iframe tricks IE7 and earlier to push a
	          // history entry on hash-tag change.  When replace is true, we don't
	          // want this.
	          if (!options.replace) this.iframe.document.open().close();
	          this._updateHash(this.iframe.location, fragment, options.replace);
	        }
	
	      // If you've told us that you explicitly don't want fallback hashchange-
	      // based history, then `navigate` becomes a page refresh.
	      } else {
	        return this.location.assign(url);
	      }
	      if (options.trigger) return this.loadUrl(fragment);
	    },
	
	    // Update the hash location, either replacing the current entry, or adding
	    // a new one to the browser history.
	    _updateHash: function(location, fragment, replace) {
	      if (replace) {
	        var href = location.href.replace(/(javascript:|#).*$/, '');
	        location.replace(href + '#' + fragment);
	      } else {
	        // Some browsers require that `hash` contains a leading #.
	        location.hash = '#' + fragment;
	      }
	    }
	
	  });
	
	  // Create the default Backbone.history.
	  Backbone.history = new History;
	
	  // Helpers
	  // -------
	
	  // Helper function to correctly set up the prototype chain for subclasses.
	  // Similar to `goog.inherits`, but uses a hash of prototype properties and
	  // class properties to be extended.
	  var extend = function(protoProps, staticProps) {
	    var parent = this;
	    var child;
	
	    // The constructor function for the new subclass is either defined by you
	    // (the "constructor" property in your `extend` definition), or defaulted
	    // by us to simply call the parent constructor.
	    if (protoProps && _.has(protoProps, 'constructor')) {
	      child = protoProps.constructor;
	    } else {
	      child = function(){ return parent.apply(this, arguments); };
	    }
	
	    // Add static properties to the constructor function, if supplied.
	    _.extend(child, parent, staticProps);
	
	    // Set the prototype chain to inherit from `parent`, without calling
	    // `parent` constructor function.
	    var Surrogate = function(){ this.constructor = child; };
	    Surrogate.prototype = parent.prototype;
	    child.prototype = new Surrogate;
	
	    // Add prototype properties (instance properties) to the subclass,
	    // if supplied.
	    if (protoProps) _.extend(child.prototype, protoProps);
	
	    // Set a convenience property in case the parent's prototype is needed
	    // later.
	    child.__super__ = parent.prototype;
	
	    return child;
	  };
	
	  // Set up inheritance for the model, collection, router, view and history.
	  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
	
	  // Throw an error when a URL is needed, and none is supplied.
	  var urlError = function() {
	    throw new Error('A "url" property or function must be specified');
	  };
	
	  // Wrap an optional error callback with a fallback error event.
	  var wrapError = function(model, options) {
	    var error = options.error;
	    options.error = function(resp) {
	      if (error) error.call(options.context, model, resp, options);
	      model.trigger('error', model, resp, options);
	    };
	  };
	
	  return Backbone;
	
	}));
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
})
/** END DEFINE BLOCK for backbone@1.2.0/backbone.js **/


/** START DEFINE BLOCK for jquery@2.2.4/dist/jquery.js **/
jupyter.define('jquery@2.2.4/dist/jquery.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery JavaScript Library v2.2.4
	 * http://jquery.com/
	 *
	 * Includes Sizzle.js
	 * http://sizzlejs.com/
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license
	 * http://jquery.org/license
	 *
	 * Date: 2016-05-20T17:23Z
	 */
	
	(function( global, factory ) {
	
		if ( typeof module === "object" && typeof module.exports === "object" ) {
			// For CommonJS and CommonJS-like environments where a proper `window`
			// is present, execute the factory and get jQuery.
			// For environments that do not have a `window` with a `document`
			// (such as Node.js), expose a factory as module.exports.
			// This accentuates the need for the creation of a real `window`.
			// e.g. var jQuery = require("jquery")(window);
			// See ticket #14549 for more info.
			module.exports = global.document ?
				factory( global, true ) :
				function( w ) {
					if ( !w.document ) {
						throw new Error( "jQuery requires a window with a document" );
					}
					return factory( w );
				};
		} else {
			factory( global );
		}
	
	// Pass this if window is not defined yet
	}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
	
	// Support: Firefox 18+
	// Can't be in strict mode, several libs including ASP.NET trace
	// the stack via arguments.caller.callee and Firefox dies if
	// you try to trace through "use strict" call chains. (#13335)
	//"use strict";
	var arr = [];
	
	var document = window.document;
	
	var slice = arr.slice;
	
	var concat = arr.concat;
	
	var push = arr.push;
	
	var indexOf = arr.indexOf;
	
	var class2type = {};
	
	var toString = class2type.toString;
	
	var hasOwn = class2type.hasOwnProperty;
	
	var support = {};
	
	
	
	var
		version = "2.2.4",
	
		// Define a local copy of jQuery
		jQuery = function( selector, context ) {
	
			// The jQuery object is actually just the init constructor 'enhanced'
			// Need init if jQuery is called (just allow error to be thrown if not included)
			return new jQuery.fn.init( selector, context );
		},
	
		// Support: Android<4.1
		// Make sure we trim BOM and NBSP
		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
	
		// Matches dashed string for camelizing
		rmsPrefix = /^-ms-/,
		rdashAlpha = /-([\da-z])/gi,
	
		// Used by jQuery.camelCase as callback to replace()
		fcamelCase = function( all, letter ) {
			return letter.toUpperCase();
		};
	
	jQuery.fn = jQuery.prototype = {
	
		// The current version of jQuery being used
		jquery: version,
	
		constructor: jQuery,
	
		// Start with an empty selector
		selector: "",
	
		// The default length of a jQuery object is 0
		length: 0,
	
		toArray: function() {
			return slice.call( this );
		},
	
		// Get the Nth element in the matched element set OR
		// Get the whole matched element set as a clean array
		get: function( num ) {
			return num != null ?
	
				// Return just the one element from the set
				( num < 0 ? this[ num + this.length ] : this[ num ] ) :
	
				// Return all the elements in a clean array
				slice.call( this );
		},
	
		// Take an array of elements and push it onto the stack
		// (returning the new matched element set)
		pushStack: function( elems ) {
	
			// Build a new jQuery matched element set
			var ret = jQuery.merge( this.constructor(), elems );
	
			// Add the old object onto the stack (as a reference)
			ret.prevObject = this;
			ret.context = this.context;
	
			// Return the newly-formed element set
			return ret;
		},
	
		// Execute a callback for every element in the matched set.
		each: function( callback ) {
			return jQuery.each( this, callback );
		},
	
		map: function( callback ) {
			return this.pushStack( jQuery.map( this, function( elem, i ) {
				return callback.call( elem, i, elem );
			} ) );
		},
	
		slice: function() {
			return this.pushStack( slice.apply( this, arguments ) );
		},
	
		first: function() {
			return this.eq( 0 );
		},
	
		last: function() {
			return this.eq( -1 );
		},
	
		eq: function( i ) {
			var len = this.length,
				j = +i + ( i < 0 ? len : 0 );
			return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
		},
	
		end: function() {
			return this.prevObject || this.constructor();
		},
	
		// For internal use only.
		// Behaves like an Array's method, not like a jQuery method.
		push: push,
		sort: arr.sort,
		splice: arr.splice
	};
	
	jQuery.extend = jQuery.fn.extend = function() {
		var options, name, src, copy, copyIsArray, clone,
			target = arguments[ 0 ] || {},
			i = 1,
			length = arguments.length,
			deep = false;
	
		// Handle a deep copy situation
		if ( typeof target === "boolean" ) {
			deep = target;
	
			// Skip the boolean and the target
			target = arguments[ i ] || {};
			i++;
		}
	
		// Handle case when target is a string or something (possible in deep copy)
		if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
			target = {};
		}
	
		// Extend jQuery itself if only one argument is passed
		if ( i === length ) {
			target = this;
			i--;
		}
	
		for ( ; i < length; i++ ) {
	
			// Only deal with non-null/undefined values
			if ( ( options = arguments[ i ] ) != null ) {
	
				// Extend the base object
				for ( name in options ) {
					src = target[ name ];
					copy = options[ name ];
	
					// Prevent never-ending loop
					if ( target === copy ) {
						continue;
					}
	
					// Recurse if we're merging plain objects or arrays
					if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
						( copyIsArray = jQuery.isArray( copy ) ) ) ) {
	
						if ( copyIsArray ) {
							copyIsArray = false;
							clone = src && jQuery.isArray( src ) ? src : [];
	
						} else {
							clone = src && jQuery.isPlainObject( src ) ? src : {};
						}
	
						// Never move original objects, clone them
						target[ name ] = jQuery.extend( deep, clone, copy );
	
					// Don't bring in undefined values
					} else if ( copy !== undefined ) {
						target[ name ] = copy;
					}
				}
			}
		}
	
		// Return the modified object
		return target;
	};
	
	jQuery.extend( {
	
		// Unique for each copy of jQuery on the page
		expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
	
		// Assume jQuery is ready without the ready module
		isReady: true,
	
		error: function( msg ) {
			throw new Error( msg );
		},
	
		noop: function() {},
	
		isFunction: function( obj ) {
			return jQuery.type( obj ) === "function";
		},
	
		isArray: Array.isArray,
	
		isWindow: function( obj ) {
			return obj != null && obj === obj.window;
		},
	
		isNumeric: function( obj ) {
	
			// parseFloat NaNs numeric-cast false positives (null|true|false|"")
			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
			// subtraction forces infinities to NaN
			// adding 1 corrects loss of precision from parseFloat (#15100)
			var realStringObj = obj && obj.toString();
			return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
		},
	
		isPlainObject: function( obj ) {
			var key;
	
			// Not plain objects:
			// - Any object or value whose internal [[Class]] property is not "[object Object]"
			// - DOM nodes
			// - window
			if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
				return false;
			}
	
			// Not own constructor property must be Object
			if ( obj.constructor &&
					!hasOwn.call( obj, "constructor" ) &&
					!hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
				return false;
			}
	
			// Own properties are enumerated firstly, so to speed up,
			// if last one is own, then all properties are own
			for ( key in obj ) {}
	
			return key === undefined || hasOwn.call( obj, key );
		},
	
		isEmptyObject: function( obj ) {
			var name;
			for ( name in obj ) {
				return false;
			}
			return true;
		},
	
		type: function( obj ) {
			if ( obj == null ) {
				return obj + "";
			}
	
			// Support: Android<4.0, iOS<6 (functionish RegExp)
			return typeof obj === "object" || typeof obj === "function" ?
				class2type[ toString.call( obj ) ] || "object" :
				typeof obj;
		},
	
		// Evaluates a script in a global context
		globalEval: function( code ) {
			var script,
				indirect = eval;
	
			code = jQuery.trim( code );
	
			if ( code ) {
	
				// If the code includes a valid, prologue position
				// strict mode pragma, execute code by injecting a
				// script tag into the document.
				if ( code.indexOf( "use strict" ) === 1 ) {
					script = document.createElement( "script" );
					script.text = code;
					document.head.appendChild( script ).parentNode.removeChild( script );
				} else {
	
					// Otherwise, avoid the DOM node creation, insertion
					// and removal by using an indirect global eval
	
					indirect( code );
				}
			}
		},
	
		// Convert dashed to camelCase; used by the css and data modules
		// Support: IE9-11+
		// Microsoft forgot to hump their vendor prefix (#9572)
		camelCase: function( string ) {
			return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
		},
	
		nodeName: function( elem, name ) {
			return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
		},
	
		each: function( obj, callback ) {
			var length, i = 0;
	
			if ( isArrayLike( obj ) ) {
				length = obj.length;
				for ( ; i < length; i++ ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			}
	
			return obj;
		},
	
		// Support: Android<4.1
		trim: function( text ) {
			return text == null ?
				"" :
				( text + "" ).replace( rtrim, "" );
		},
	
		// results is for internal usage only
		makeArray: function( arr, results ) {
			var ret = results || [];
	
			if ( arr != null ) {
				if ( isArrayLike( Object( arr ) ) ) {
					jQuery.merge( ret,
						typeof arr === "string" ?
						[ arr ] : arr
					);
				} else {
					push.call( ret, arr );
				}
			}
	
			return ret;
		},
	
		inArray: function( elem, arr, i ) {
			return arr == null ? -1 : indexOf.call( arr, elem, i );
		},
	
		merge: function( first, second ) {
			var len = +second.length,
				j = 0,
				i = first.length;
	
			for ( ; j < len; j++ ) {
				first[ i++ ] = second[ j ];
			}
	
			first.length = i;
	
			return first;
		},
	
		grep: function( elems, callback, invert ) {
			var callbackInverse,
				matches = [],
				i = 0,
				length = elems.length,
				callbackExpect = !invert;
	
			// Go through the array, only saving the items
			// that pass the validator function
			for ( ; i < length; i++ ) {
				callbackInverse = !callback( elems[ i ], i );
				if ( callbackInverse !== callbackExpect ) {
					matches.push( elems[ i ] );
				}
			}
	
			return matches;
		},
	
		// arg is for internal usage only
		map: function( elems, callback, arg ) {
			var length, value,
				i = 0,
				ret = [];
	
			// Go through the array, translating each of the items to their new values
			if ( isArrayLike( elems ) ) {
				length = elems.length;
				for ( ; i < length; i++ ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
	
			// Go through every key on the object,
			} else {
				for ( i in elems ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
			}
	
			// Flatten any nested arrays
			return concat.apply( [], ret );
		},
	
		// A global GUID counter for objects
		guid: 1,
	
		// Bind a function to a context, optionally partially applying any
		// arguments.
		proxy: function( fn, context ) {
			var tmp, args, proxy;
	
			if ( typeof context === "string" ) {
				tmp = fn[ context ];
				context = fn;
				fn = tmp;
			}
	
			// Quick check to determine if target is callable, in the spec
			// this throws a TypeError, but we will just return undefined.
			if ( !jQuery.isFunction( fn ) ) {
				return undefined;
			}
	
			// Simulated bind
			args = slice.call( arguments, 2 );
			proxy = function() {
				return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
			};
	
			// Set the guid of unique handler to the same of original handler, so it can be removed
			proxy.guid = fn.guid = fn.guid || jQuery.guid++;
	
			return proxy;
		},
	
		now: Date.now,
	
		// jQuery.support is not used in Core but other projects attach their
		// properties to it so it needs to exist.
		support: support
	} );
	
	// JSHint would error on this code due to the Symbol not being defined in ES5.
	// Defining this global in .jshintrc would create a danger of using the global
	// unguarded in another place, it seems safer to just disable JSHint for these
	// three lines.
	/* jshint ignore: start */
	if ( typeof Symbol === "function" ) {
		jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
	}
	/* jshint ignore: end */
	
	// Populate the class2type map
	jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
	function( i, name ) {
		class2type[ "[object " + name + "]" ] = name.toLowerCase();
	} );
	
	function isArrayLike( obj ) {
	
		// Support: iOS 8.2 (not reproducible in simulator)
		// `in` check used to prevent JIT error (gh-2145)
		// hasOwn isn't used here due to false negatives
		// regarding Nodelist length in IE
		var length = !!obj && "length" in obj && obj.length,
			type = jQuery.type( obj );
	
		if ( type === "function" || jQuery.isWindow( obj ) ) {
			return false;
		}
	
		return type === "array" || length === 0 ||
			typeof length === "number" && length > 0 && ( length - 1 ) in obj;
	}
	var Sizzle =
	/*!
	 * Sizzle CSS Selector Engine v2.2.1
	 * http://sizzlejs.com/
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license
	 * http://jquery.org/license
	 *
	 * Date: 2015-10-17
	 */
	(function( window ) {
	
	var i,
		support,
		Expr,
		getText,
		isXML,
		tokenize,
		compile,
		select,
		outermostContext,
		sortInput,
		hasDuplicate,
	
		// Local document vars
		setDocument,
		document,
		docElem,
		documentIsHTML,
		rbuggyQSA,
		rbuggyMatches,
		matches,
		contains,
	
		// Instance-specific data
		expando = "sizzle" + 1 * new Date(),
		preferredDoc = window.document,
		dirruns = 0,
		done = 0,
		classCache = createCache(),
		tokenCache = createCache(),
		compilerCache = createCache(),
		sortOrder = function( a, b ) {
			if ( a === b ) {
				hasDuplicate = true;
			}
			return 0;
		},
	
		// General-purpose constants
		MAX_NEGATIVE = 1 << 31,
	
		// Instance methods
		hasOwn = ({}).hasOwnProperty,
		arr = [],
		pop = arr.pop,
		push_native = arr.push,
		push = arr.push,
		slice = arr.slice,
		// Use a stripped-down indexOf as it's faster than native
		// http://jsperf.com/thor-indexof-vs-for/5
		indexOf = function( list, elem ) {
			var i = 0,
				len = list.length;
			for ( ; i < len; i++ ) {
				if ( list[i] === elem ) {
					return i;
				}
			}
			return -1;
		},
	
		booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
	
		// Regular expressions
	
		// http://www.w3.org/TR/css3-selectors/#whitespace
		whitespace = "[\\x20\\t\\r\\n\\f]",
	
		// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
		identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
	
		// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
		attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
			// Operator (capture 2)
			"*([*^$|!~]?=)" + whitespace +
			// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
			"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
			"*\\]",
	
		pseudos = ":(" + identifier + ")(?:\\((" +
			// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
			// 1. quoted (capture 3; capture 4 or capture 5)
			"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
			// 2. simple (capture 6)
			"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
			// 3. anything else (capture 2)
			".*" +
			")\\)|)",
	
		// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
		rwhitespace = new RegExp( whitespace + "+", "g" ),
		rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
	
		rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
		rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
	
		rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
	
		rpseudo = new RegExp( pseudos ),
		ridentifier = new RegExp( "^" + identifier + "$" ),
	
		matchExpr = {
			"ID": new RegExp( "^#(" + identifier + ")" ),
			"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
			"TAG": new RegExp( "^(" + identifier + "|[*])" ),
			"ATTR": new RegExp( "^" + attributes ),
			"PSEUDO": new RegExp( "^" + pseudos ),
			"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
				"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
				"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
			"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
			// For use in libraries implementing .is()
			// We use this for POS matching in `select`
			"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
				whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
		},
	
		rinputs = /^(?:input|select|textarea|button)$/i,
		rheader = /^h\d$/i,
	
		rnative = /^[^{]+\{\s*\[native \w/,
	
		// Easily-parseable/retrievable ID or TAG or CLASS selectors
		rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
	
		rsibling = /[+~]/,
		rescape = /'|\\/g,
	
		// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
		runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
		funescape = function( _, escaped, escapedWhitespace ) {
			var high = "0x" + escaped - 0x10000;
			// NaN means non-codepoint
			// Support: Firefox<24
			// Workaround erroneous numeric interpretation of +"0x"
			return high !== high || escapedWhitespace ?
				escaped :
				high < 0 ?
					// BMP codepoint
					String.fromCharCode( high + 0x10000 ) :
					// Supplemental Plane codepoint (surrogate pair)
					String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
		},
	
		// Used for iframes
		// See setDocument()
		// Removing the function wrapper causes a "Permission Denied"
		// error in IE
		unloadHandler = function() {
			setDocument();
		};
	
	// Optimize for push.apply( _, NodeList )
	try {
		push.apply(
			(arr = slice.call( preferredDoc.childNodes )),
			preferredDoc.childNodes
		);
		// Support: Android<4.0
		// Detect silently failing push.apply
		arr[ preferredDoc.childNodes.length ].nodeType;
	} catch ( e ) {
		push = { apply: arr.length ?
	
			// Leverage slice if possible
			function( target, els ) {
				push_native.apply( target, slice.call(els) );
			} :
	
			// Support: IE<9
			// Otherwise append directly
			function( target, els ) {
				var j = target.length,
					i = 0;
				// Can't trust NodeList.length
				while ( (target[j++] = els[i++]) ) {}
				target.length = j - 1;
			}
		};
	}
	
	function Sizzle( selector, context, results, seed ) {
		var m, i, elem, nid, nidselect, match, groups, newSelector,
			newContext = context && context.ownerDocument,
	
			// nodeType defaults to 9, since context defaults to document
			nodeType = context ? context.nodeType : 9;
	
		results = results || [];
	
		// Return early from calls with invalid selector or context
		if ( typeof selector !== "string" || !selector ||
			nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
	
			return results;
		}
	
		// Try to shortcut find operations (as opposed to filters) in HTML documents
		if ( !seed ) {
	
			if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
				setDocument( context );
			}
			context = context || document;
	
			if ( documentIsHTML ) {
	
				// If the selector is sufficiently simple, try using a "get*By*" DOM method
				// (excepting DocumentFragment context, where the methods don't exist)
				if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
	
					// ID selector
					if ( (m = match[1]) ) {
	
						// Document context
						if ( nodeType === 9 ) {
							if ( (elem = context.getElementById( m )) ) {
	
								// Support: IE, Opera, Webkit
								// TODO: identify versions
								// getElementById can match elements by name instead of ID
								if ( elem.id === m ) {
									results.push( elem );
									return results;
								}
							} else {
								return results;
							}
	
						// Element context
						} else {
	
							// Support: IE, Opera, Webkit
							// TODO: identify versions
							// getElementById can match elements by name instead of ID
							if ( newContext && (elem = newContext.getElementById( m )) &&
								contains( context, elem ) &&
								elem.id === m ) {
	
								results.push( elem );
								return results;
							}
						}
	
					// Type selector
					} else if ( match[2] ) {
						push.apply( results, context.getElementsByTagName( selector ) );
						return results;
	
					// Class selector
					} else if ( (m = match[3]) && support.getElementsByClassName &&
						context.getElementsByClassName ) {
	
						push.apply( results, context.getElementsByClassName( m ) );
						return results;
					}
				}
	
				// Take advantage of querySelectorAll
				if ( support.qsa &&
					!compilerCache[ selector + " " ] &&
					(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
	
					if ( nodeType !== 1 ) {
						newContext = context;
						newSelector = selector;
	
					// qSA looks outside Element context, which is not what we want
					// Thanks to Andrew Dupont for this workaround technique
					// Support: IE <=8
					// Exclude object elements
					} else if ( context.nodeName.toLowerCase() !== "object" ) {
	
						// Capture the context ID, setting it first if necessary
						if ( (nid = context.getAttribute( "id" )) ) {
							nid = nid.replace( rescape, "\\$&" );
						} else {
							context.setAttribute( "id", (nid = expando) );
						}
	
						// Prefix every selector in the list
						groups = tokenize( selector );
						i = groups.length;
						nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
						while ( i-- ) {
							groups[i] = nidselect + " " + toSelector( groups[i] );
						}
						newSelector = groups.join( "," );
	
						// Expand context for sibling selectors
						newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
							context;
					}
	
					if ( newSelector ) {
						try {
							push.apply( results,
								newContext.querySelectorAll( newSelector )
							);
							return results;
						} catch ( qsaError ) {
						} finally {
							if ( nid === expando ) {
								context.removeAttribute( "id" );
							}
						}
					}
				}
			}
		}
	
		// All others
		return select( selector.replace( rtrim, "$1" ), context, results, seed );
	}
	
	/**
	 * Create key-value caches of limited size
	 * @returns {function(string, object)} Returns the Object data after storing it on itself with
	 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
	 *	deleting the oldest entry
	 */
	function createCache() {
		var keys = [];
	
		function cache( key, value ) {
			// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
			if ( keys.push( key + " " ) > Expr.cacheLength ) {
				// Only keep the most recent entries
				delete cache[ keys.shift() ];
			}
			return (cache[ key + " " ] = value);
		}
		return cache;
	}
	
	/**
	 * Mark a function for special use by Sizzle
	 * @param {Function} fn The function to mark
	 */
	function markFunction( fn ) {
		fn[ expando ] = true;
		return fn;
	}
	
	/**
	 * Support testing using an element
	 * @param {Function} fn Passed the created div and expects a boolean result
	 */
	function assert( fn ) {
		var div = document.createElement("div");
	
		try {
			return !!fn( div );
		} catch (e) {
			return false;
		} finally {
			// Remove from its parent by default
			if ( div.parentNode ) {
				div.parentNode.removeChild( div );
			}
			// release memory in IE
			div = null;
		}
	}
	
	/**
	 * Adds the same handler for all of the specified attrs
	 * @param {String} attrs Pipe-separated list of attributes
	 * @param {Function} handler The method that will be applied
	 */
	function addHandle( attrs, handler ) {
		var arr = attrs.split("|"),
			i = arr.length;
	
		while ( i-- ) {
			Expr.attrHandle[ arr[i] ] = handler;
		}
	}
	
	/**
	 * Checks document order of two siblings
	 * @param {Element} a
	 * @param {Element} b
	 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
	 */
	function siblingCheck( a, b ) {
		var cur = b && a,
			diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
				( ~b.sourceIndex || MAX_NEGATIVE ) -
				( ~a.sourceIndex || MAX_NEGATIVE );
	
		// Use IE sourceIndex if available on both nodes
		if ( diff ) {
			return diff;
		}
	
		// Check if b follows a
		if ( cur ) {
			while ( (cur = cur.nextSibling) ) {
				if ( cur === b ) {
					return -1;
				}
			}
		}
	
		return a ? 1 : -1;
	}
	
	/**
	 * Returns a function to use in pseudos for input types
	 * @param {String} type
	 */
	function createInputPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return name === "input" && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for buttons
	 * @param {String} type
	 */
	function createButtonPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return (name === "input" || name === "button") && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for positionals
	 * @param {Function} fn
	 */
	function createPositionalPseudo( fn ) {
		return markFunction(function( argument ) {
			argument = +argument;
			return markFunction(function( seed, matches ) {
				var j,
					matchIndexes = fn( [], seed.length, argument ),
					i = matchIndexes.length;
	
				// Match elements found at the specified indexes
				while ( i-- ) {
					if ( seed[ (j = matchIndexes[i]) ] ) {
						seed[j] = !(matches[j] = seed[j]);
					}
				}
			});
		});
	}
	
	/**
	 * Checks a node for validity as a Sizzle context
	 * @param {Element|Object=} context
	 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
	 */
	function testContext( context ) {
		return context && typeof context.getElementsByTagName !== "undefined" && context;
	}
	
	// Expose support vars for convenience
	support = Sizzle.support = {};
	
	/**
	 * Detects XML nodes
	 * @param {Element|Object} elem An element or a document
	 * @returns {Boolean} True iff elem is a non-HTML XML node
	 */
	isXML = Sizzle.isXML = function( elem ) {
		// documentElement is verified for cases where it doesn't yet exist
		// (such as loading iframes in IE - #4833)
		var documentElement = elem && (elem.ownerDocument || elem).documentElement;
		return documentElement ? documentElement.nodeName !== "HTML" : false;
	};
	
	/**
	 * Sets document-related variables once based on the current document
	 * @param {Element|Object} [doc] An element or document object to use to set the document
	 * @returns {Object} Returns the current document
	 */
	setDocument = Sizzle.setDocument = function( node ) {
		var hasCompare, parent,
			doc = node ? node.ownerDocument || node : preferredDoc;
	
		// Return early if doc is invalid or already selected
		if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
			return document;
		}
	
		// Update global variables
		document = doc;
		docElem = document.documentElement;
		documentIsHTML = !isXML( document );
	
		// Support: IE 9-11, Edge
		// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
		if ( (parent = document.defaultView) && parent.top !== parent ) {
			// Support: IE 11
			if ( parent.addEventListener ) {
				parent.addEventListener( "unload", unloadHandler, false );
	
			// Support: IE 9 - 10 only
			} else if ( parent.attachEvent ) {
				parent.attachEvent( "onunload", unloadHandler );
			}
		}
	
		/* Attributes
		---------------------------------------------------------------------- */
	
		// Support: IE<8
		// Verify that getAttribute really returns attributes and not properties
		// (excepting IE8 booleans)
		support.attributes = assert(function( div ) {
			div.className = "i";
			return !div.getAttribute("className");
		});
	
		/* getElement(s)By*
		---------------------------------------------------------------------- */
	
		// Check if getElementsByTagName("*") returns only elements
		support.getElementsByTagName = assert(function( div ) {
			div.appendChild( document.createComment("") );
			return !div.getElementsByTagName("*").length;
		});
	
		// Support: IE<9
		support.getElementsByClassName = rnative.test( document.getElementsByClassName );
	
		// Support: IE<10
		// Check if getElementById returns elements by name
		// The broken getElementById methods don't pick up programatically-set names,
		// so use a roundabout getElementsByName test
		support.getById = assert(function( div ) {
			docElem.appendChild( div ).id = expando;
			return !document.getElementsByName || !document.getElementsByName( expando ).length;
		});
	
		// ID find and filter
		if ( support.getById ) {
			Expr.find["ID"] = function( id, context ) {
				if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
					var m = context.getElementById( id );
					return m ? [ m ] : [];
				}
			};
			Expr.filter["ID"] = function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					return elem.getAttribute("id") === attrId;
				};
			};
		} else {
			// Support: IE6/7
			// getElementById is not reliable as a find shortcut
			delete Expr.find["ID"];
	
			Expr.filter["ID"] =  function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					var node = typeof elem.getAttributeNode !== "undefined" &&
						elem.getAttributeNode("id");
					return node && node.value === attrId;
				};
			};
		}
	
		// Tag
		Expr.find["TAG"] = support.getElementsByTagName ?
			function( tag, context ) {
				if ( typeof context.getElementsByTagName !== "undefined" ) {
					return context.getElementsByTagName( tag );
	
				// DocumentFragment nodes don't have gEBTN
				} else if ( support.qsa ) {
					return context.querySelectorAll( tag );
				}
			} :
	
			function( tag, context ) {
				var elem,
					tmp = [],
					i = 0,
					// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
					results = context.getElementsByTagName( tag );
	
				// Filter out possible comments
				if ( tag === "*" ) {
					while ( (elem = results[i++]) ) {
						if ( elem.nodeType === 1 ) {
							tmp.push( elem );
						}
					}
	
					return tmp;
				}
				return results;
			};
	
		// Class
		Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
			if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
				return context.getElementsByClassName( className );
			}
		};
	
		/* QSA/matchesSelector
		---------------------------------------------------------------------- */
	
		// QSA and matchesSelector support
	
		// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
		rbuggyMatches = [];
	
		// qSa(:focus) reports false when true (Chrome 21)
		// We allow this because of a bug in IE8/9 that throws an error
		// whenever `document.activeElement` is accessed on an iframe
		// So, we allow :focus to pass through QSA all the time to avoid the IE error
		// See http://bugs.jquery.com/ticket/13378
		rbuggyQSA = [];
	
		if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
			// Build QSA regex
			// Regex strategy adopted from Diego Perini
			assert(function( div ) {
				// Select is set to empty string on purpose
				// This is to test IE's treatment of not explicitly
				// setting a boolean content attribute,
				// since its presence should be enough
				// http://bugs.jquery.com/ticket/12359
				docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
					"<select id='" + expando + "-\r\\' msallowcapture=''>" +
					"<option selected=''></option></select>";
	
				// Support: IE8, Opera 11-12.16
				// Nothing should be selected when empty strings follow ^= or $= or *=
				// The test attribute must be unknown in Opera but "safe" for WinRT
				// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
				if ( div.querySelectorAll("[msallowcapture^='']").length ) {
					rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
				}
	
				// Support: IE8
				// Boolean attributes and "value" are not treated correctly
				if ( !div.querySelectorAll("[selected]").length ) {
					rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
				}
	
				// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
				if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
					rbuggyQSA.push("~=");
				}
	
				// Webkit/Opera - :checked should return selected option elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				// IE8 throws error here and will not see later tests
				if ( !div.querySelectorAll(":checked").length ) {
					rbuggyQSA.push(":checked");
				}
	
				// Support: Safari 8+, iOS 8+
				// https://bugs.webkit.org/show_bug.cgi?id=136851
				// In-page `selector#id sibing-combinator selector` fails
				if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
					rbuggyQSA.push(".#.+[+~]");
				}
			});
	
			assert(function( div ) {
				// Support: Windows 8 Native Apps
				// The type and name attributes are restricted during .innerHTML assignment
				var input = document.createElement("input");
				input.setAttribute( "type", "hidden" );
				div.appendChild( input ).setAttribute( "name", "D" );
	
				// Support: IE8
				// Enforce case-sensitivity of name attribute
				if ( div.querySelectorAll("[name=d]").length ) {
					rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
				}
	
				// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
				// IE8 throws error here and will not see later tests
				if ( !div.querySelectorAll(":enabled").length ) {
					rbuggyQSA.push( ":enabled", ":disabled" );
				}
	
				// Opera 10-11 does not throw on post-comma invalid pseudos
				div.querySelectorAll("*,:x");
				rbuggyQSA.push(",.*:");
			});
		}
	
		if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
			docElem.webkitMatchesSelector ||
			docElem.mozMatchesSelector ||
			docElem.oMatchesSelector ||
			docElem.msMatchesSelector) )) ) {
	
			assert(function( div ) {
				// Check to see if it's possible to do matchesSelector
				// on a disconnected node (IE 9)
				support.disconnectedMatch = matches.call( div, "div" );
	
				// This should fail with an exception
				// Gecko does not error, returns false instead
				matches.call( div, "[s!='']:x" );
				rbuggyMatches.push( "!=", pseudos );
			});
		}
	
		rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
		rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
	
		/* Contains
		---------------------------------------------------------------------- */
		hasCompare = rnative.test( docElem.compareDocumentPosition );
	
		// Element contains another
		// Purposefully self-exclusive
		// As in, an element does not contain itself
		contains = hasCompare || rnative.test( docElem.contains ) ?
			function( a, b ) {
				var adown = a.nodeType === 9 ? a.documentElement : a,
					bup = b && b.parentNode;
				return a === bup || !!( bup && bup.nodeType === 1 && (
					adown.contains ?
						adown.contains( bup ) :
						a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
				));
			} :
			function( a, b ) {
				if ( b ) {
					while ( (b = b.parentNode) ) {
						if ( b === a ) {
							return true;
						}
					}
				}
				return false;
			};
	
		/* Sorting
		---------------------------------------------------------------------- */
	
		// Document order sorting
		sortOrder = hasCompare ?
		function( a, b ) {
	
			// Flag for duplicate removal
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			// Sort on method existence if only one input has compareDocumentPosition
			var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
			if ( compare ) {
				return compare;
			}
	
			// Calculate position if both inputs belong to the same document
			compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
				a.compareDocumentPosition( b ) :
	
				// Otherwise we know they are disconnected
				1;
	
			// Disconnected nodes
			if ( compare & 1 ||
				(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
	
				// Choose the first element that is related to our preferred document
				if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
					return -1;
				}
				if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
					return 1;
				}
	
				// Maintain original order
				return sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
			}
	
			return compare & 4 ? -1 : 1;
		} :
		function( a, b ) {
			// Exit early if the nodes are identical
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			var cur,
				i = 0,
				aup = a.parentNode,
				bup = b.parentNode,
				ap = [ a ],
				bp = [ b ];
	
			// Parentless nodes are either documents or disconnected
			if ( !aup || !bup ) {
				return a === document ? -1 :
					b === document ? 1 :
					aup ? -1 :
					bup ? 1 :
					sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
	
			// If the nodes are siblings, we can do a quick check
			} else if ( aup === bup ) {
				return siblingCheck( a, b );
			}
	
			// Otherwise we need full lists of their ancestors for comparison
			cur = a;
			while ( (cur = cur.parentNode) ) {
				ap.unshift( cur );
			}
			cur = b;
			while ( (cur = cur.parentNode) ) {
				bp.unshift( cur );
			}
	
			// Walk down the tree looking for a discrepancy
			while ( ap[i] === bp[i] ) {
				i++;
			}
	
			return i ?
				// Do a sibling check if the nodes have a common ancestor
				siblingCheck( ap[i], bp[i] ) :
	
				// Otherwise nodes in our document sort first
				ap[i] === preferredDoc ? -1 :
				bp[i] === preferredDoc ? 1 :
				0;
		};
	
		return document;
	};
	
	Sizzle.matches = function( expr, elements ) {
		return Sizzle( expr, null, null, elements );
	};
	
	Sizzle.matchesSelector = function( elem, expr ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		// Make sure that attribute selectors are quoted
		expr = expr.replace( rattributeQuotes, "='$1']" );
	
		if ( support.matchesSelector && documentIsHTML &&
			!compilerCache[ expr + " " ] &&
			( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
			( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
	
			try {
				var ret = matches.call( elem, expr );
	
				// IE 9's matchesSelector returns false on disconnected nodes
				if ( ret || support.disconnectedMatch ||
						// As well, disconnected nodes are said to be in a document
						// fragment in IE 9
						elem.document && elem.document.nodeType !== 11 ) {
					return ret;
				}
			} catch (e) {}
		}
	
		return Sizzle( expr, document, null, [ elem ] ).length > 0;
	};
	
	Sizzle.contains = function( context, elem ) {
		// Set document vars if needed
		if ( ( context.ownerDocument || context ) !== document ) {
			setDocument( context );
		}
		return contains( context, elem );
	};
	
	Sizzle.attr = function( elem, name ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		var fn = Expr.attrHandle[ name.toLowerCase() ],
			// Don't get fooled by Object.prototype properties (jQuery #13807)
			val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
				fn( elem, name, !documentIsHTML ) :
				undefined;
	
		return val !== undefined ?
			val :
			support.attributes || !documentIsHTML ?
				elem.getAttribute( name ) :
				(val = elem.getAttributeNode(name)) && val.specified ?
					val.value :
					null;
	};
	
	Sizzle.error = function( msg ) {
		throw new Error( "Syntax error, unrecognized expression: " + msg );
	};
	
	/**
	 * Document sorting and removing duplicates
	 * @param {ArrayLike} results
	 */
	Sizzle.uniqueSort = function( results ) {
		var elem,
			duplicates = [],
			j = 0,
			i = 0;
	
		// Unless we *know* we can detect duplicates, assume their presence
		hasDuplicate = !support.detectDuplicates;
		sortInput = !support.sortStable && results.slice( 0 );
		results.sort( sortOrder );
	
		if ( hasDuplicate ) {
			while ( (elem = results[i++]) ) {
				if ( elem === results[ i ] ) {
					j = duplicates.push( i );
				}
			}
			while ( j-- ) {
				results.splice( duplicates[ j ], 1 );
			}
		}
	
		// Clear input after sorting to release objects
		// See https://github.com/jquery/sizzle/pull/225
		sortInput = null;
	
		return results;
	};
	
	/**
	 * Utility function for retrieving the text value of an array of DOM nodes
	 * @param {Array|Element} elem
	 */
	getText = Sizzle.getText = function( elem ) {
		var node,
			ret = "",
			i = 0,
			nodeType = elem.nodeType;
	
		if ( !nodeType ) {
			// If no nodeType, this is expected to be an array
			while ( (node = elem[i++]) ) {
				// Do not traverse comment nodes
				ret += getText( node );
			}
		} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
			// Use textContent for elements
			// innerText usage removed for consistency of new lines (jQuery #11153)
			if ( typeof elem.textContent === "string" ) {
				return elem.textContent;
			} else {
				// Traverse its children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					ret += getText( elem );
				}
			}
		} else if ( nodeType === 3 || nodeType === 4 ) {
			return elem.nodeValue;
		}
		// Do not include comment or processing instruction nodes
	
		return ret;
	};
	
	Expr = Sizzle.selectors = {
	
		// Can be adjusted by the user
		cacheLength: 50,
	
		createPseudo: markFunction,
	
		match: matchExpr,
	
		attrHandle: {},
	
		find: {},
	
		relative: {
			">": { dir: "parentNode", first: true },
			" ": { dir: "parentNode" },
			"+": { dir: "previousSibling", first: true },
			"~": { dir: "previousSibling" }
		},
	
		preFilter: {
			"ATTR": function( match ) {
				match[1] = match[1].replace( runescape, funescape );
	
				// Move the given value to match[3] whether quoted or unquoted
				match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
	
				if ( match[2] === "~=" ) {
					match[3] = " " + match[3] + " ";
				}
	
				return match.slice( 0, 4 );
			},
	
			"CHILD": function( match ) {
				/* matches from matchExpr["CHILD"]
					1 type (only|nth|...)
					2 what (child|of-type)
					3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
					4 xn-component of xn+y argument ([+-]?\d*n|)
					5 sign of xn-component
					6 x of xn-component
					7 sign of y-component
					8 y of y-component
				*/
				match[1] = match[1].toLowerCase();
	
				if ( match[1].slice( 0, 3 ) === "nth" ) {
					// nth-* requires argument
					if ( !match[3] ) {
						Sizzle.error( match[0] );
					}
	
					// numeric x and y parameters for Expr.filter.CHILD
					// remember that false/true cast respectively to 0/1
					match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
					match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
	
				// other types prohibit arguments
				} else if ( match[3] ) {
					Sizzle.error( match[0] );
				}
	
				return match;
			},
	
			"PSEUDO": function( match ) {
				var excess,
					unquoted = !match[6] && match[2];
	
				if ( matchExpr["CHILD"].test( match[0] ) ) {
					return null;
				}
	
				// Accept quoted arguments as-is
				if ( match[3] ) {
					match[2] = match[4] || match[5] || "";
	
				// Strip excess characters from unquoted arguments
				} else if ( unquoted && rpseudo.test( unquoted ) &&
					// Get excess from tokenize (recursively)
					(excess = tokenize( unquoted, true )) &&
					// advance to the next closing parenthesis
					(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
	
					// excess is a negative index
					match[0] = match[0].slice( 0, excess );
					match[2] = unquoted.slice( 0, excess );
				}
	
				// Return only captures needed by the pseudo filter method (type and argument)
				return match.slice( 0, 3 );
			}
		},
	
		filter: {
	
			"TAG": function( nodeNameSelector ) {
				var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
				return nodeNameSelector === "*" ?
					function() { return true; } :
					function( elem ) {
						return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
					};
			},
	
			"CLASS": function( className ) {
				var pattern = classCache[ className + " " ];
	
				return pattern ||
					(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
					classCache( className, function( elem ) {
						return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
					});
			},
	
			"ATTR": function( name, operator, check ) {
				return function( elem ) {
					var result = Sizzle.attr( elem, name );
	
					if ( result == null ) {
						return operator === "!=";
					}
					if ( !operator ) {
						return true;
					}
	
					result += "";
	
					return operator === "=" ? result === check :
						operator === "!=" ? result !== check :
						operator === "^=" ? check && result.indexOf( check ) === 0 :
						operator === "*=" ? check && result.indexOf( check ) > -1 :
						operator === "$=" ? check && result.slice( -check.length ) === check :
						operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
						operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
						false;
				};
			},
	
			"CHILD": function( type, what, argument, first, last ) {
				var simple = type.slice( 0, 3 ) !== "nth",
					forward = type.slice( -4 ) !== "last",
					ofType = what === "of-type";
	
				return first === 1 && last === 0 ?
	
					// Shortcut for :nth-*(n)
					function( elem ) {
						return !!elem.parentNode;
					} :
	
					function( elem, context, xml ) {
						var cache, uniqueCache, outerCache, node, nodeIndex, start,
							dir = simple !== forward ? "nextSibling" : "previousSibling",
							parent = elem.parentNode,
							name = ofType && elem.nodeName.toLowerCase(),
							useCache = !xml && !ofType,
							diff = false;
	
						if ( parent ) {
	
							// :(first|last|only)-(child|of-type)
							if ( simple ) {
								while ( dir ) {
									node = elem;
									while ( (node = node[ dir ]) ) {
										if ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) {
	
											return false;
										}
									}
									// Reverse direction for :only-* (if we haven't yet done so)
									start = dir = type === "only" && !start && "nextSibling";
								}
								return true;
							}
	
							start = [ forward ? parent.firstChild : parent.lastChild ];
	
							// non-xml :nth-child(...) stores cache data on `parent`
							if ( forward && useCache ) {
	
								// Seek `elem` from a previously-cached index
	
								// ...in a gzip-friendly way
								node = parent;
								outerCache = node[ expando ] || (node[ expando ] = {});
	
								// Support: IE <9 only
								// Defend against cloned attroperties (jQuery gh-1709)
								uniqueCache = outerCache[ node.uniqueID ] ||
									(outerCache[ node.uniqueID ] = {});
	
								cache = uniqueCache[ type ] || [];
								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
								diff = nodeIndex && cache[ 2 ];
								node = nodeIndex && parent.childNodes[ nodeIndex ];
	
								while ( (node = ++nodeIndex && node && node[ dir ] ||
	
									// Fallback to seeking `elem` from the start
									(diff = nodeIndex = 0) || start.pop()) ) {
	
									// When found, cache indexes on `parent` and break
									if ( node.nodeType === 1 && ++diff && node === elem ) {
										uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
										break;
									}
								}
	
							} else {
								// Use previously-cached element index if available
								if ( useCache ) {
									// ...in a gzip-friendly way
									node = elem;
									outerCache = node[ expando ] || (node[ expando ] = {});
	
									// Support: IE <9 only
									// Defend against cloned attroperties (jQuery gh-1709)
									uniqueCache = outerCache[ node.uniqueID ] ||
										(outerCache[ node.uniqueID ] = {});
	
									cache = uniqueCache[ type ] || [];
									nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
									diff = nodeIndex;
								}
	
								// xml :nth-child(...)
								// or :nth-last-child(...) or :nth(-last)?-of-type(...)
								if ( diff === false ) {
									// Use the same loop as above to seek `elem` from the start
									while ( (node = ++nodeIndex && node && node[ dir ] ||
										(diff = nodeIndex = 0) || start.pop()) ) {
	
										if ( ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) &&
											++diff ) {
	
											// Cache the index of each encountered element
											if ( useCache ) {
												outerCache = node[ expando ] || (node[ expando ] = {});
	
												// Support: IE <9 only
												// Defend against cloned attroperties (jQuery gh-1709)
												uniqueCache = outerCache[ node.uniqueID ] ||
													(outerCache[ node.uniqueID ] = {});
	
												uniqueCache[ type ] = [ dirruns, diff ];
											}
	
											if ( node === elem ) {
												break;
											}
										}
									}
								}
							}
	
							// Incorporate the offset, then check against cycle size
							diff -= last;
							return diff === first || ( diff % first === 0 && diff / first >= 0 );
						}
					};
			},
	
			"PSEUDO": function( pseudo, argument ) {
				// pseudo-class names are case-insensitive
				// http://www.w3.org/TR/selectors/#pseudo-classes
				// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
				// Remember that setFilters inherits from pseudos
				var args,
					fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
						Sizzle.error( "unsupported pseudo: " + pseudo );
	
				// The user may use createPseudo to indicate that
				// arguments are needed to create the filter function
				// just as Sizzle does
				if ( fn[ expando ] ) {
					return fn( argument );
				}
	
				// But maintain support for old signatures
				if ( fn.length > 1 ) {
					args = [ pseudo, pseudo, "", argument ];
					return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
						markFunction(function( seed, matches ) {
							var idx,
								matched = fn( seed, argument ),
								i = matched.length;
							while ( i-- ) {
								idx = indexOf( seed, matched[i] );
								seed[ idx ] = !( matches[ idx ] = matched[i] );
							}
						}) :
						function( elem ) {
							return fn( elem, 0, args );
						};
				}
	
				return fn;
			}
		},
	
		pseudos: {
			// Potentially complex pseudos
			"not": markFunction(function( selector ) {
				// Trim the selector passed to compile
				// to avoid treating leading and trailing
				// spaces as combinators
				var input = [],
					results = [],
					matcher = compile( selector.replace( rtrim, "$1" ) );
	
				return matcher[ expando ] ?
					markFunction(function( seed, matches, context, xml ) {
						var elem,
							unmatched = matcher( seed, null, xml, [] ),
							i = seed.length;
	
						// Match elements unmatched by `matcher`
						while ( i-- ) {
							if ( (elem = unmatched[i]) ) {
								seed[i] = !(matches[i] = elem);
							}
						}
					}) :
					function( elem, context, xml ) {
						input[0] = elem;
						matcher( input, null, xml, results );
						// Don't keep the element (issue #299)
						input[0] = null;
						return !results.pop();
					};
			}),
	
			"has": markFunction(function( selector ) {
				return function( elem ) {
					return Sizzle( selector, elem ).length > 0;
				};
			}),
	
			"contains": markFunction(function( text ) {
				text = text.replace( runescape, funescape );
				return function( elem ) {
					return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
				};
			}),
	
			// "Whether an element is represented by a :lang() selector
			// is based solely on the element's language value
			// being equal to the identifier C,
			// or beginning with the identifier C immediately followed by "-".
			// The matching of C against the element's language value is performed case-insensitively.
			// The identifier C does not have to be a valid language name."
			// http://www.w3.org/TR/selectors/#lang-pseudo
			"lang": markFunction( function( lang ) {
				// lang value must be a valid identifier
				if ( !ridentifier.test(lang || "") ) {
					Sizzle.error( "unsupported lang: " + lang );
				}
				lang = lang.replace( runescape, funescape ).toLowerCase();
				return function( elem ) {
					var elemLang;
					do {
						if ( (elemLang = documentIsHTML ?
							elem.lang :
							elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
	
							elemLang = elemLang.toLowerCase();
							return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
						}
					} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
					return false;
				};
			}),
	
			// Miscellaneous
			"target": function( elem ) {
				var hash = window.location && window.location.hash;
				return hash && hash.slice( 1 ) === elem.id;
			},
	
			"root": function( elem ) {
				return elem === docElem;
			},
	
			"focus": function( elem ) {
				return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
			},
	
			// Boolean properties
			"enabled": function( elem ) {
				return elem.disabled === false;
			},
	
			"disabled": function( elem ) {
				return elem.disabled === true;
			},
	
			"checked": function( elem ) {
				// In CSS3, :checked should return both checked and selected elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				var nodeName = elem.nodeName.toLowerCase();
				return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
			},
	
			"selected": function( elem ) {
				// Accessing this property makes selected-by-default
				// options in Safari work properly
				if ( elem.parentNode ) {
					elem.parentNode.selectedIndex;
				}
	
				return elem.selected === true;
			},
	
			// Contents
			"empty": function( elem ) {
				// http://www.w3.org/TR/selectors/#empty-pseudo
				// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
				//   but not by others (comment: 8; processing instruction: 7; etc.)
				// nodeType < 6 works because attributes (2) do not appear as children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					if ( elem.nodeType < 6 ) {
						return false;
					}
				}
				return true;
			},
	
			"parent": function( elem ) {
				return !Expr.pseudos["empty"]( elem );
			},
	
			// Element/input types
			"header": function( elem ) {
				return rheader.test( elem.nodeName );
			},
	
			"input": function( elem ) {
				return rinputs.test( elem.nodeName );
			},
	
			"button": function( elem ) {
				var name = elem.nodeName.toLowerCase();
				return name === "input" && elem.type === "button" || name === "button";
			},
	
			"text": function( elem ) {
				var attr;
				return elem.nodeName.toLowerCase() === "input" &&
					elem.type === "text" &&
	
					// Support: IE<8
					// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
					( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
			},
	
			// Position-in-collection
			"first": createPositionalPseudo(function() {
				return [ 0 ];
			}),
	
			"last": createPositionalPseudo(function( matchIndexes, length ) {
				return [ length - 1 ];
			}),
	
			"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
				return [ argument < 0 ? argument + length : argument ];
			}),
	
			"even": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 0;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"odd": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 1;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; --i >= 0; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; ++i < length; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			})
		}
	};
	
	Expr.pseudos["nth"] = Expr.pseudos["eq"];
	
	// Add button/input type pseudos
	for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
		Expr.pseudos[ i ] = createInputPseudo( i );
	}
	for ( i in { submit: true, reset: true } ) {
		Expr.pseudos[ i ] = createButtonPseudo( i );
	}
	
	// Easy API for creating new setFilters
	function setFilters() {}
	setFilters.prototype = Expr.filters = Expr.pseudos;
	Expr.setFilters = new setFilters();
	
	tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
		var matched, match, tokens, type,
			soFar, groups, preFilters,
			cached = tokenCache[ selector + " " ];
	
		if ( cached ) {
			return parseOnly ? 0 : cached.slice( 0 );
		}
	
		soFar = selector;
		groups = [];
		preFilters = Expr.preFilter;
	
		while ( soFar ) {
	
			// Comma and first run
			if ( !matched || (match = rcomma.exec( soFar )) ) {
				if ( match ) {
					// Don't consume trailing commas as valid
					soFar = soFar.slice( match[0].length ) || soFar;
				}
				groups.push( (tokens = []) );
			}
	
			matched = false;
	
			// Combinators
			if ( (match = rcombinators.exec( soFar )) ) {
				matched = match.shift();
				tokens.push({
					value: matched,
					// Cast descendant combinators to space
					type: match[0].replace( rtrim, " " )
				});
				soFar = soFar.slice( matched.length );
			}
	
			// Filters
			for ( type in Expr.filter ) {
				if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
					(match = preFilters[ type ]( match ))) ) {
					matched = match.shift();
					tokens.push({
						value: matched,
						type: type,
						matches: match
					});
					soFar = soFar.slice( matched.length );
				}
			}
	
			if ( !matched ) {
				break;
			}
		}
	
		// Return the length of the invalid excess
		// if we're just parsing
		// Otherwise, throw an error or return tokens
		return parseOnly ?
			soFar.length :
			soFar ?
				Sizzle.error( selector ) :
				// Cache the tokens
				tokenCache( selector, groups ).slice( 0 );
	};
	
	function toSelector( tokens ) {
		var i = 0,
			len = tokens.length,
			selector = "";
		for ( ; i < len; i++ ) {
			selector += tokens[i].value;
		}
		return selector;
	}
	
	function addCombinator( matcher, combinator, base ) {
		var dir = combinator.dir,
			checkNonElements = base && dir === "parentNode",
			doneName = done++;
	
		return combinator.first ?
			// Check against closest ancestor/preceding element
			function( elem, context, xml ) {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						return matcher( elem, context, xml );
					}
				}
			} :
	
			// Check against all ancestor/preceding elements
			function( elem, context, xml ) {
				var oldCache, uniqueCache, outerCache,
					newCache = [ dirruns, doneName ];
	
				// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
				if ( xml ) {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							if ( matcher( elem, context, xml ) ) {
								return true;
							}
						}
					}
				} else {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							outerCache = elem[ expando ] || (elem[ expando ] = {});
	
							// Support: IE <9 only
							// Defend against cloned attroperties (jQuery gh-1709)
							uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
	
							if ( (oldCache = uniqueCache[ dir ]) &&
								oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
	
								// Assign to newCache so results back-propagate to previous elements
								return (newCache[ 2 ] = oldCache[ 2 ]);
							} else {
								// Reuse newcache so results back-propagate to previous elements
								uniqueCache[ dir ] = newCache;
	
								// A match means we're done; a fail means we have to keep checking
								if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
									return true;
								}
							}
						}
					}
				}
			};
	}
	
	function elementMatcher( matchers ) {
		return matchers.length > 1 ?
			function( elem, context, xml ) {
				var i = matchers.length;
				while ( i-- ) {
					if ( !matchers[i]( elem, context, xml ) ) {
						return false;
					}
				}
				return true;
			} :
			matchers[0];
	}
	
	function multipleContexts( selector, contexts, results ) {
		var i = 0,
			len = contexts.length;
		for ( ; i < len; i++ ) {
			Sizzle( selector, contexts[i], results );
		}
		return results;
	}
	
	function condense( unmatched, map, filter, context, xml ) {
		var elem,
			newUnmatched = [],
			i = 0,
			len = unmatched.length,
			mapped = map != null;
	
		for ( ; i < len; i++ ) {
			if ( (elem = unmatched[i]) ) {
				if ( !filter || filter( elem, context, xml ) ) {
					newUnmatched.push( elem );
					if ( mapped ) {
						map.push( i );
					}
				}
			}
		}
	
		return newUnmatched;
	}
	
	function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
		if ( postFilter && !postFilter[ expando ] ) {
			postFilter = setMatcher( postFilter );
		}
		if ( postFinder && !postFinder[ expando ] ) {
			postFinder = setMatcher( postFinder, postSelector );
		}
		return markFunction(function( seed, results, context, xml ) {
			var temp, i, elem,
				preMap = [],
				postMap = [],
				preexisting = results.length,
	
				// Get initial elements from seed or context
				elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
	
				// Prefilter to get matcher input, preserving a map for seed-results synchronization
				matcherIn = preFilter && ( seed || !selector ) ?
					condense( elems, preMap, preFilter, context, xml ) :
					elems,
	
				matcherOut = matcher ?
					// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
					postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
	
						// ...intermediate processing is necessary
						[] :
	
						// ...otherwise use results directly
						results :
					matcherIn;
	
			// Find primary matches
			if ( matcher ) {
				matcher( matcherIn, matcherOut, context, xml );
			}
	
			// Apply postFilter
			if ( postFilter ) {
				temp = condense( matcherOut, postMap );
				postFilter( temp, [], context, xml );
	
				// Un-match failing elements by moving them back to matcherIn
				i = temp.length;
				while ( i-- ) {
					if ( (elem = temp[i]) ) {
						matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
					}
				}
			}
	
			if ( seed ) {
				if ( postFinder || preFilter ) {
					if ( postFinder ) {
						// Get the final matcherOut by condensing this intermediate into postFinder contexts
						temp = [];
						i = matcherOut.length;
						while ( i-- ) {
							if ( (elem = matcherOut[i]) ) {
								// Restore matcherIn since elem is not yet a final match
								temp.push( (matcherIn[i] = elem) );
							}
						}
						postFinder( null, (matcherOut = []), temp, xml );
					}
	
					// Move matched elements from seed to results to keep them synchronized
					i = matcherOut.length;
					while ( i-- ) {
						if ( (elem = matcherOut[i]) &&
							(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
	
							seed[temp] = !(results[temp] = elem);
						}
					}
				}
	
			// Add elements to results, through postFinder if defined
			} else {
				matcherOut = condense(
					matcherOut === results ?
						matcherOut.splice( preexisting, matcherOut.length ) :
						matcherOut
				);
				if ( postFinder ) {
					postFinder( null, results, matcherOut, xml );
				} else {
					push.apply( results, matcherOut );
				}
			}
		});
	}
	
	function matcherFromTokens( tokens ) {
		var checkContext, matcher, j,
			len = tokens.length,
			leadingRelative = Expr.relative[ tokens[0].type ],
			implicitRelative = leadingRelative || Expr.relative[" "],
			i = leadingRelative ? 1 : 0,
	
			// The foundational matcher ensures that elements are reachable from top-level context(s)
			matchContext = addCombinator( function( elem ) {
				return elem === checkContext;
			}, implicitRelative, true ),
			matchAnyContext = addCombinator( function( elem ) {
				return indexOf( checkContext, elem ) > -1;
			}, implicitRelative, true ),
			matchers = [ function( elem, context, xml ) {
				var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
					(checkContext = context).nodeType ?
						matchContext( elem, context, xml ) :
						matchAnyContext( elem, context, xml ) );
				// Avoid hanging onto element (issue #299)
				checkContext = null;
				return ret;
			} ];
	
		for ( ; i < len; i++ ) {
			if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
				matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
			} else {
				matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
	
				// Return special upon seeing a positional matcher
				if ( matcher[ expando ] ) {
					// Find the next relative operator (if any) for proper handling
					j = ++i;
					for ( ; j < len; j++ ) {
						if ( Expr.relative[ tokens[j].type ] ) {
							break;
						}
					}
					return setMatcher(
						i > 1 && elementMatcher( matchers ),
						i > 1 && toSelector(
							// If the preceding token was a descendant combinator, insert an implicit any-element `*`
							tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
						).replace( rtrim, "$1" ),
						matcher,
						i < j && matcherFromTokens( tokens.slice( i, j ) ),
						j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
						j < len && toSelector( tokens )
					);
				}
				matchers.push( matcher );
			}
		}
	
		return elementMatcher( matchers );
	}
	
	function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
		var bySet = setMatchers.length > 0,
			byElement = elementMatchers.length > 0,
			superMatcher = function( seed, context, xml, results, outermost ) {
				var elem, j, matcher,
					matchedCount = 0,
					i = "0",
					unmatched = seed && [],
					setMatched = [],
					contextBackup = outermostContext,
					// We must always have either seed elements or outermost context
					elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
					// Use integer dirruns iff this is the outermost matcher
					dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
					len = elems.length;
	
				if ( outermost ) {
					outermostContext = context === document || context || outermost;
				}
	
				// Add elements passing elementMatchers directly to results
				// Support: IE<9, Safari
				// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
				for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
					if ( byElement && elem ) {
						j = 0;
						if ( !context && elem.ownerDocument !== document ) {
							setDocument( elem );
							xml = !documentIsHTML;
						}
						while ( (matcher = elementMatchers[j++]) ) {
							if ( matcher( elem, context || document, xml) ) {
								results.push( elem );
								break;
							}
						}
						if ( outermost ) {
							dirruns = dirrunsUnique;
						}
					}
	
					// Track unmatched elements for set filters
					if ( bySet ) {
						// They will have gone through all possible matchers
						if ( (elem = !matcher && elem) ) {
							matchedCount--;
						}
	
						// Lengthen the array for every element, matched or not
						if ( seed ) {
							unmatched.push( elem );
						}
					}
				}
	
				// `i` is now the count of elements visited above, and adding it to `matchedCount`
				// makes the latter nonnegative.
				matchedCount += i;
	
				// Apply set filters to unmatched elements
				// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
				// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
				// no element matchers and no seed.
				// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
				// case, which will result in a "00" `matchedCount` that differs from `i` but is also
				// numerically zero.
				if ( bySet && i !== matchedCount ) {
					j = 0;
					while ( (matcher = setMatchers[j++]) ) {
						matcher( unmatched, setMatched, context, xml );
					}
	
					if ( seed ) {
						// Reintegrate element matches to eliminate the need for sorting
						if ( matchedCount > 0 ) {
							while ( i-- ) {
								if ( !(unmatched[i] || setMatched[i]) ) {
									setMatched[i] = pop.call( results );
								}
							}
						}
	
						// Discard index placeholder values to get only actual matches
						setMatched = condense( setMatched );
					}
	
					// Add matches to results
					push.apply( results, setMatched );
	
					// Seedless set matches succeeding multiple successful matchers stipulate sorting
					if ( outermost && !seed && setMatched.length > 0 &&
						( matchedCount + setMatchers.length ) > 1 ) {
	
						Sizzle.uniqueSort( results );
					}
				}
	
				// Override manipulation of globals by nested matchers
				if ( outermost ) {
					dirruns = dirrunsUnique;
					outermostContext = contextBackup;
				}
	
				return unmatched;
			};
	
		return bySet ?
			markFunction( superMatcher ) :
			superMatcher;
	}
	
	compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
		var i,
			setMatchers = [],
			elementMatchers = [],
			cached = compilerCache[ selector + " " ];
	
		if ( !cached ) {
			// Generate a function of recursive functions that can be used to check each element
			if ( !match ) {
				match = tokenize( selector );
			}
			i = match.length;
			while ( i-- ) {
				cached = matcherFromTokens( match[i] );
				if ( cached[ expando ] ) {
					setMatchers.push( cached );
				} else {
					elementMatchers.push( cached );
				}
			}
	
			// Cache the compiled function
			cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
	
			// Save selector and tokenization
			cached.selector = selector;
		}
		return cached;
	};
	
	/**
	 * A low-level selection function that works with Sizzle's compiled
	 *  selector functions
	 * @param {String|Function} selector A selector or a pre-compiled
	 *  selector function built with Sizzle.compile
	 * @param {Element} context
	 * @param {Array} [results]
	 * @param {Array} [seed] A set of elements to match against
	 */
	select = Sizzle.select = function( selector, context, results, seed ) {
		var i, tokens, token, type, find,
			compiled = typeof selector === "function" && selector,
			match = !seed && tokenize( (selector = compiled.selector || selector) );
	
		results = results || [];
	
		// Try to minimize operations if there is only one selector in the list and no seed
		// (the latter of which guarantees us context)
		if ( match.length === 1 ) {
	
			// Reduce context if the leading compound selector is an ID
			tokens = match[0] = match[0].slice( 0 );
			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
					support.getById && context.nodeType === 9 && documentIsHTML &&
					Expr.relative[ tokens[1].type ] ) {
	
				context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
				if ( !context ) {
					return results;
	
				// Precompiled matchers will still verify ancestry, so step up a level
				} else if ( compiled ) {
					context = context.parentNode;
				}
	
				selector = selector.slice( tokens.shift().value.length );
			}
	
			// Fetch a seed set for right-to-left matching
			i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
			while ( i-- ) {
				token = tokens[i];
	
				// Abort if we hit a combinator
				if ( Expr.relative[ (type = token.type) ] ) {
					break;
				}
				if ( (find = Expr.find[ type ]) ) {
					// Search, expanding context for leading sibling combinators
					if ( (seed = find(
						token.matches[0].replace( runescape, funescape ),
						rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
					)) ) {
	
						// If seed is empty or no tokens remain, we can return early
						tokens.splice( i, 1 );
						selector = seed.length && toSelector( tokens );
						if ( !selector ) {
							push.apply( results, seed );
							return results;
						}
	
						break;
					}
				}
			}
		}
	
		// Compile and execute a filtering function if one is not provided
		// Provide `match` to avoid retokenization if we modified the selector above
		( compiled || compile( selector, match ) )(
			seed,
			context,
			!documentIsHTML,
			results,
			!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
		);
		return results;
	};
	
	// One-time assignments
	
	// Sort stability
	support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
	
	// Support: Chrome 14-35+
	// Always assume duplicates if they aren't passed to the comparison function
	support.detectDuplicates = !!hasDuplicate;
	
	// Initialize against the default document
	setDocument();
	
	// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
	// Detached nodes confoundingly follow *each other*
	support.sortDetached = assert(function( div1 ) {
		// Should return 1, but returns 4 (following)
		return div1.compareDocumentPosition( document.createElement("div") ) & 1;
	});
	
	// Support: IE<8
	// Prevent attribute/property "interpolation"
	// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
	if ( !assert(function( div ) {
		div.innerHTML = "<a href='#'></a>";
		return div.firstChild.getAttribute("href") === "#" ;
	}) ) {
		addHandle( "type|href|height|width", function( elem, name, isXML ) {
			if ( !isXML ) {
				return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
			}
		});
	}
	
	// Support: IE<9
	// Use defaultValue in place of getAttribute("value")
	if ( !support.attributes || !assert(function( div ) {
		div.innerHTML = "<input/>";
		div.firstChild.setAttribute( "value", "" );
		return div.firstChild.getAttribute( "value" ) === "";
	}) ) {
		addHandle( "value", function( elem, name, isXML ) {
			if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
				return elem.defaultValue;
			}
		});
	}
	
	// Support: IE<9
	// Use getAttributeNode to fetch booleans when getAttribute lies
	if ( !assert(function( div ) {
		return div.getAttribute("disabled") == null;
	}) ) {
		addHandle( booleans, function( elem, name, isXML ) {
			var val;
			if ( !isXML ) {
				return elem[ name ] === true ? name.toLowerCase() :
						(val = elem.getAttributeNode( name )) && val.specified ?
						val.value :
					null;
			}
		});
	}
	
	return Sizzle;
	
	})( window );
	
	
	
	jQuery.find = Sizzle;
	jQuery.expr = Sizzle.selectors;
	jQuery.expr[ ":" ] = jQuery.expr.pseudos;
	jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
	jQuery.text = Sizzle.getText;
	jQuery.isXMLDoc = Sizzle.isXML;
	jQuery.contains = Sizzle.contains;
	
	
	
	var dir = function( elem, dir, until ) {
		var matched = [],
			truncate = until !== undefined;
	
		while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
			if ( elem.nodeType === 1 ) {
				if ( truncate && jQuery( elem ).is( until ) ) {
					break;
				}
				matched.push( elem );
			}
		}
		return matched;
	};
	
	
	var siblings = function( n, elem ) {
		var matched = [];
	
		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				matched.push( n );
			}
		}
	
		return matched;
	};
	
	
	var rneedsContext = jQuery.expr.match.needsContext;
	
	var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
	
	
	
	var risSimple = /^.[^:#\[\.,]*$/;
	
	// Implement the identical functionality for filter and not
	function winnow( elements, qualifier, not ) {
		if ( jQuery.isFunction( qualifier ) ) {
			return jQuery.grep( elements, function( elem, i ) {
				/* jshint -W018 */
				return !!qualifier.call( elem, i, elem ) !== not;
			} );
	
		}
	
		if ( qualifier.nodeType ) {
			return jQuery.grep( elements, function( elem ) {
				return ( elem === qualifier ) !== not;
			} );
	
		}
	
		if ( typeof qualifier === "string" ) {
			if ( risSimple.test( qualifier ) ) {
				return jQuery.filter( qualifier, elements, not );
			}
	
			qualifier = jQuery.filter( qualifier, elements );
		}
	
		return jQuery.grep( elements, function( elem ) {
			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
		} );
	}
	
	jQuery.filter = function( expr, elems, not ) {
		var elem = elems[ 0 ];
	
		if ( not ) {
			expr = ":not(" + expr + ")";
		}
	
		return elems.length === 1 && elem.nodeType === 1 ?
			jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
			jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
				return elem.nodeType === 1;
			} ) );
	};
	
	jQuery.fn.extend( {
		find: function( selector ) {
			var i,
				len = this.length,
				ret = [],
				self = this;
	
			if ( typeof selector !== "string" ) {
				return this.pushStack( jQuery( selector ).filter( function() {
					for ( i = 0; i < len; i++ ) {
						if ( jQuery.contains( self[ i ], this ) ) {
							return true;
						}
					}
				} ) );
			}
	
			for ( i = 0; i < len; i++ ) {
				jQuery.find( selector, self[ i ], ret );
			}
	
			// Needed because $( selector, context ) becomes $( context ).find( selector )
			ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
			ret.selector = this.selector ? this.selector + " " + selector : selector;
			return ret;
		},
		filter: function( selector ) {
			return this.pushStack( winnow( this, selector || [], false ) );
		},
		not: function( selector ) {
			return this.pushStack( winnow( this, selector || [], true ) );
		},
		is: function( selector ) {
			return !!winnow(
				this,
	
				// If this is a positional/relative selector, check membership in the returned set
				// so $("p:first").is("p:last") won't return true for a doc with two "p".
				typeof selector === "string" && rneedsContext.test( selector ) ?
					jQuery( selector ) :
					selector || [],
				false
			).length;
		}
	} );
	
	
	// Initialize a jQuery object
	
	
	// A central reference to the root jQuery(document)
	var rootjQuery,
	
		// A simple way to check for HTML strings
		// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
		// Strict HTML recognition (#11290: must start with <)
		rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
	
		init = jQuery.fn.init = function( selector, context, root ) {
			var match, elem;
	
			// HANDLE: $(""), $(null), $(undefined), $(false)
			if ( !selector ) {
				return this;
			}
	
			// Method init() accepts an alternate rootjQuery
			// so migrate can support jQuery.sub (gh-2101)
			root = root || rootjQuery;
	
			// Handle HTML strings
			if ( typeof selector === "string" ) {
				if ( selector[ 0 ] === "<" &&
					selector[ selector.length - 1 ] === ">" &&
					selector.length >= 3 ) {
	
					// Assume that strings that start and end with <> are HTML and skip the regex check
					match = [ null, selector, null ];
	
				} else {
					match = rquickExpr.exec( selector );
				}
	
				// Match html or make sure no context is specified for #id
				if ( match && ( match[ 1 ] || !context ) ) {
	
					// HANDLE: $(html) -> $(array)
					if ( match[ 1 ] ) {
						context = context instanceof jQuery ? context[ 0 ] : context;
	
						// Option to run scripts is true for back-compat
						// Intentionally let the error be thrown if parseHTML is not present
						jQuery.merge( this, jQuery.parseHTML(
							match[ 1 ],
							context && context.nodeType ? context.ownerDocument || context : document,
							true
						) );
	
						// HANDLE: $(html, props)
						if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
							for ( match in context ) {
	
								// Properties of context are called as methods if possible
								if ( jQuery.isFunction( this[ match ] ) ) {
									this[ match ]( context[ match ] );
	
								// ...and otherwise set as attributes
								} else {
									this.attr( match, context[ match ] );
								}
							}
						}
	
						return this;
	
					// HANDLE: $(#id)
					} else {
						elem = document.getElementById( match[ 2 ] );
	
						// Support: Blackberry 4.6
						// gEBID returns nodes no longer in the document (#6963)
						if ( elem && elem.parentNode ) {
	
							// Inject the element directly into the jQuery object
							this.length = 1;
							this[ 0 ] = elem;
						}
	
						this.context = document;
						this.selector = selector;
						return this;
					}
	
				// HANDLE: $(expr, $(...))
				} else if ( !context || context.jquery ) {
					return ( context || root ).find( selector );
	
				// HANDLE: $(expr, context)
				// (which is just equivalent to: $(context).find(expr)
				} else {
					return this.constructor( context ).find( selector );
				}
	
			// HANDLE: $(DOMElement)
			} else if ( selector.nodeType ) {
				this.context = this[ 0 ] = selector;
				this.length = 1;
				return this;
	
			// HANDLE: $(function)
			// Shortcut for document ready
			} else if ( jQuery.isFunction( selector ) ) {
				return root.ready !== undefined ?
					root.ready( selector ) :
	
					// Execute immediately if ready is not present
					selector( jQuery );
			}
	
			if ( selector.selector !== undefined ) {
				this.selector = selector.selector;
				this.context = selector.context;
			}
	
			return jQuery.makeArray( selector, this );
		};
	
	// Give the init function the jQuery prototype for later instantiation
	init.prototype = jQuery.fn;
	
	// Initialize central reference
	rootjQuery = jQuery( document );
	
	
	var rparentsprev = /^(?:parents|prev(?:Until|All))/,
	
		// Methods guaranteed to produce a unique set when starting from a unique set
		guaranteedUnique = {
			children: true,
			contents: true,
			next: true,
			prev: true
		};
	
	jQuery.fn.extend( {
		has: function( target ) {
			var targets = jQuery( target, this ),
				l = targets.length;
	
			return this.filter( function() {
				var i = 0;
				for ( ; i < l; i++ ) {
					if ( jQuery.contains( this, targets[ i ] ) ) {
						return true;
					}
				}
			} );
		},
	
		closest: function( selectors, context ) {
			var cur,
				i = 0,
				l = this.length,
				matched = [],
				pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
					jQuery( selectors, context || this.context ) :
					0;
	
			for ( ; i < l; i++ ) {
				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
	
					// Always skip document fragments
					if ( cur.nodeType < 11 && ( pos ?
						pos.index( cur ) > -1 :
	
						// Don't pass non-elements to Sizzle
						cur.nodeType === 1 &&
							jQuery.find.matchesSelector( cur, selectors ) ) ) {
	
						matched.push( cur );
						break;
					}
				}
			}
	
			return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
		},
	
		// Determine the position of an element within the set
		index: function( elem ) {
	
			// No argument, return index in parent
			if ( !elem ) {
				return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
			}
	
			// Index in selector
			if ( typeof elem === "string" ) {
				return indexOf.call( jQuery( elem ), this[ 0 ] );
			}
	
			// Locate the position of the desired element
			return indexOf.call( this,
	
				// If it receives a jQuery object, the first element is used
				elem.jquery ? elem[ 0 ] : elem
			);
		},
	
		add: function( selector, context ) {
			return this.pushStack(
				jQuery.uniqueSort(
					jQuery.merge( this.get(), jQuery( selector, context ) )
				)
			);
		},
	
		addBack: function( selector ) {
			return this.add( selector == null ?
				this.prevObject : this.prevObject.filter( selector )
			);
		}
	} );
	
	function sibling( cur, dir ) {
		while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
		return cur;
	}
	
	jQuery.each( {
		parent: function( elem ) {
			var parent = elem.parentNode;
			return parent && parent.nodeType !== 11 ? parent : null;
		},
		parents: function( elem ) {
			return dir( elem, "parentNode" );
		},
		parentsUntil: function( elem, i, until ) {
			return dir( elem, "parentNode", until );
		},
		next: function( elem ) {
			return sibling( elem, "nextSibling" );
		},
		prev: function( elem ) {
			return sibling( elem, "previousSibling" );
		},
		nextAll: function( elem ) {
			return dir( elem, "nextSibling" );
		},
		prevAll: function( elem ) {
			return dir( elem, "previousSibling" );
		},
		nextUntil: function( elem, i, until ) {
			return dir( elem, "nextSibling", until );
		},
		prevUntil: function( elem, i, until ) {
			return dir( elem, "previousSibling", until );
		},
		siblings: function( elem ) {
			return siblings( ( elem.parentNode || {} ).firstChild, elem );
		},
		children: function( elem ) {
			return siblings( elem.firstChild );
		},
		contents: function( elem ) {
			return elem.contentDocument || jQuery.merge( [], elem.childNodes );
		}
	}, function( name, fn ) {
		jQuery.fn[ name ] = function( until, selector ) {
			var matched = jQuery.map( this, fn, until );
	
			if ( name.slice( -5 ) !== "Until" ) {
				selector = until;
			}
	
			if ( selector && typeof selector === "string" ) {
				matched = jQuery.filter( selector, matched );
			}
	
			if ( this.length > 1 ) {
	
				// Remove duplicates
				if ( !guaranteedUnique[ name ] ) {
					jQuery.uniqueSort( matched );
				}
	
				// Reverse order for parents* and prev-derivatives
				if ( rparentsprev.test( name ) ) {
					matched.reverse();
				}
			}
	
			return this.pushStack( matched );
		};
	} );
	var rnotwhite = ( /\S+/g );
	
	
	
	// Convert String-formatted options into Object-formatted ones
	function createOptions( options ) {
		var object = {};
		jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
			object[ flag ] = true;
		} );
		return object;
	}
	
	/*
	 * Create a callback list using the following parameters:
	 *
	 *	options: an optional list of space-separated options that will change how
	 *			the callback list behaves or a more traditional option object
	 *
	 * By default a callback list will act like an event callback list and can be
	 * "fired" multiple times.
	 *
	 * Possible options:
	 *
	 *	once:			will ensure the callback list can only be fired once (like a Deferred)
	 *
	 *	memory:			will keep track of previous values and will call any callback added
	 *					after the list has been fired right away with the latest "memorized"
	 *					values (like a Deferred)
	 *
	 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
	 *
	 *	stopOnFalse:	interrupt callings when a callback returns false
	 *
	 */
	jQuery.Callbacks = function( options ) {
	
		// Convert options from String-formatted to Object-formatted if needed
		// (we check in cache first)
		options = typeof options === "string" ?
			createOptions( options ) :
			jQuery.extend( {}, options );
	
		var // Flag to know if list is currently firing
			firing,
	
			// Last fire value for non-forgettable lists
			memory,
	
			// Flag to know if list was already fired
			fired,
	
			// Flag to prevent firing
			locked,
	
			// Actual callback list
			list = [],
	
			// Queue of execution data for repeatable lists
			queue = [],
	
			// Index of currently firing callback (modified by add/remove as needed)
			firingIndex = -1,
	
			// Fire callbacks
			fire = function() {
	
				// Enforce single-firing
				locked = options.once;
	
				// Execute callbacks for all pending executions,
				// respecting firingIndex overrides and runtime changes
				fired = firing = true;
				for ( ; queue.length; firingIndex = -1 ) {
					memory = queue.shift();
					while ( ++firingIndex < list.length ) {
	
						// Run callback and check for early termination
						if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
							options.stopOnFalse ) {
	
							// Jump to end and forget the data so .add doesn't re-fire
							firingIndex = list.length;
							memory = false;
						}
					}
				}
	
				// Forget the data if we're done with it
				if ( !options.memory ) {
					memory = false;
				}
	
				firing = false;
	
				// Clean up if we're done firing for good
				if ( locked ) {
	
					// Keep an empty list if we have data for future add calls
					if ( memory ) {
						list = [];
	
					// Otherwise, this object is spent
					} else {
						list = "";
					}
				}
			},
	
			// Actual Callbacks object
			self = {
	
				// Add a callback or a collection of callbacks to the list
				add: function() {
					if ( list ) {
	
						// If we have memory from a past run, we should fire after adding
						if ( memory && !firing ) {
							firingIndex = list.length - 1;
							queue.push( memory );
						}
	
						( function add( args ) {
							jQuery.each( args, function( _, arg ) {
								if ( jQuery.isFunction( arg ) ) {
									if ( !options.unique || !self.has( arg ) ) {
										list.push( arg );
									}
								} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
	
									// Inspect recursively
									add( arg );
								}
							} );
						} )( arguments );
	
						if ( memory && !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Remove a callback from the list
				remove: function() {
					jQuery.each( arguments, function( _, arg ) {
						var index;
						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
							list.splice( index, 1 );
	
							// Handle firing indexes
							if ( index <= firingIndex ) {
								firingIndex--;
							}
						}
					} );
					return this;
				},
	
				// Check if a given callback is in the list.
				// If no argument is given, return whether or not list has callbacks attached.
				has: function( fn ) {
					return fn ?
						jQuery.inArray( fn, list ) > -1 :
						list.length > 0;
				},
	
				// Remove all callbacks from the list
				empty: function() {
					if ( list ) {
						list = [];
					}
					return this;
				},
	
				// Disable .fire and .add
				// Abort any current/pending executions
				// Clear all callbacks and values
				disable: function() {
					locked = queue = [];
					list = memory = "";
					return this;
				},
				disabled: function() {
					return !list;
				},
	
				// Disable .fire
				// Also disable .add unless we have memory (since it would have no effect)
				// Abort any pending executions
				lock: function() {
					locked = queue = [];
					if ( !memory ) {
						list = memory = "";
					}
					return this;
				},
				locked: function() {
					return !!locked;
				},
	
				// Call all callbacks with the given context and arguments
				fireWith: function( context, args ) {
					if ( !locked ) {
						args = args || [];
						args = [ context, args.slice ? args.slice() : args ];
						queue.push( args );
						if ( !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Call all the callbacks with the given arguments
				fire: function() {
					self.fireWith( this, arguments );
					return this;
				},
	
				// To know if the callbacks have already been called at least once
				fired: function() {
					return !!fired;
				}
			};
	
		return self;
	};
	
	
	jQuery.extend( {
	
		Deferred: function( func ) {
			var tuples = [
	
					// action, add listener, listener list, final state
					[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
					[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
					[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
				],
				state = "pending",
				promise = {
					state: function() {
						return state;
					},
					always: function() {
						deferred.done( arguments ).fail( arguments );
						return this;
					},
					then: function( /* fnDone, fnFail, fnProgress */ ) {
						var fns = arguments;
						return jQuery.Deferred( function( newDefer ) {
							jQuery.each( tuples, function( i, tuple ) {
								var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
	
								// deferred[ done | fail | progress ] for forwarding actions to newDefer
								deferred[ tuple[ 1 ] ]( function() {
									var returned = fn && fn.apply( this, arguments );
									if ( returned && jQuery.isFunction( returned.promise ) ) {
										returned.promise()
											.progress( newDefer.notify )
											.done( newDefer.resolve )
											.fail( newDefer.reject );
									} else {
										newDefer[ tuple[ 0 ] + "With" ](
											this === promise ? newDefer.promise() : this,
											fn ? [ returned ] : arguments
										);
									}
								} );
							} );
							fns = null;
						} ).promise();
					},
	
					// Get a promise for this deferred
					// If obj is provided, the promise aspect is added to the object
					promise: function( obj ) {
						return obj != null ? jQuery.extend( obj, promise ) : promise;
					}
				},
				deferred = {};
	
			// Keep pipe for back-compat
			promise.pipe = promise.then;
	
			// Add list-specific methods
			jQuery.each( tuples, function( i, tuple ) {
				var list = tuple[ 2 ],
					stateString = tuple[ 3 ];
	
				// promise[ done | fail | progress ] = list.add
				promise[ tuple[ 1 ] ] = list.add;
	
				// Handle state
				if ( stateString ) {
					list.add( function() {
	
						// state = [ resolved | rejected ]
						state = stateString;
	
					// [ reject_list | resolve_list ].disable; progress_list.lock
					}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
				}
	
				// deferred[ resolve | reject | notify ]
				deferred[ tuple[ 0 ] ] = function() {
					deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
					return this;
				};
				deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
			} );
	
			// Make the deferred a promise
			promise.promise( deferred );
	
			// Call given func if any
			if ( func ) {
				func.call( deferred, deferred );
			}
	
			// All done!
			return deferred;
		},
	
		// Deferred helper
		when: function( subordinate /* , ..., subordinateN */ ) {
			var i = 0,
				resolveValues = slice.call( arguments ),
				length = resolveValues.length,
	
				// the count of uncompleted subordinates
				remaining = length !== 1 ||
					( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
	
				// the master Deferred.
				// If resolveValues consist of only a single Deferred, just use that.
				deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
	
				// Update function for both resolve and progress values
				updateFunc = function( i, contexts, values ) {
					return function( value ) {
						contexts[ i ] = this;
						values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
						if ( values === progressValues ) {
							deferred.notifyWith( contexts, values );
						} else if ( !( --remaining ) ) {
							deferred.resolveWith( contexts, values );
						}
					};
				},
	
				progressValues, progressContexts, resolveContexts;
	
			// Add listeners to Deferred subordinates; treat others as resolved
			if ( length > 1 ) {
				progressValues = new Array( length );
				progressContexts = new Array( length );
				resolveContexts = new Array( length );
				for ( ; i < length; i++ ) {
					if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
						resolveValues[ i ].promise()
							.progress( updateFunc( i, progressContexts, progressValues ) )
							.done( updateFunc( i, resolveContexts, resolveValues ) )
							.fail( deferred.reject );
					} else {
						--remaining;
					}
				}
			}
	
			// If we're not waiting on anything, resolve the master
			if ( !remaining ) {
				deferred.resolveWith( resolveContexts, resolveValues );
			}
	
			return deferred.promise();
		}
	} );
	
	
	// The deferred used on DOM ready
	var readyList;
	
	jQuery.fn.ready = function( fn ) {
	
		// Add the callback
		jQuery.ready.promise().done( fn );
	
		return this;
	};
	
	jQuery.extend( {
	
		// Is the DOM ready to be used? Set to true once it occurs.
		isReady: false,
	
		// A counter to track how many items to wait for before
		// the ready event fires. See #6781
		readyWait: 1,
	
		// Hold (or release) the ready event
		holdReady: function( hold ) {
			if ( hold ) {
				jQuery.readyWait++;
			} else {
				jQuery.ready( true );
			}
		},
	
		// Handle when the DOM is ready
		ready: function( wait ) {
	
			// Abort if there are pending holds or we're already ready
			if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
				return;
			}
	
			// Remember that the DOM is ready
			jQuery.isReady = true;
	
			// If a normal DOM Ready event fired, decrement, and wait if need be
			if ( wait !== true && --jQuery.readyWait > 0 ) {
				return;
			}
	
			// If there are functions bound, to execute
			readyList.resolveWith( document, [ jQuery ] );
	
			// Trigger any bound ready events
			if ( jQuery.fn.triggerHandler ) {
				jQuery( document ).triggerHandler( "ready" );
				jQuery( document ).off( "ready" );
			}
		}
	} );
	
	/**
	 * The ready event handler and self cleanup method
	 */
	function completed() {
		document.removeEventListener( "DOMContentLoaded", completed );
		window.removeEventListener( "load", completed );
		jQuery.ready();
	}
	
	jQuery.ready.promise = function( obj ) {
		if ( !readyList ) {
	
			readyList = jQuery.Deferred();
	
			// Catch cases where $(document).ready() is called
			// after the browser event has already occurred.
			// Support: IE9-10 only
			// Older IE sometimes signals "interactive" too soon
			if ( document.readyState === "complete" ||
				( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
	
				// Handle it asynchronously to allow scripts the opportunity to delay ready
				window.setTimeout( jQuery.ready );
	
			} else {
	
				// Use the handy event callback
				document.addEventListener( "DOMContentLoaded", completed );
	
				// A fallback to window.onload, that will always work
				window.addEventListener( "load", completed );
			}
		}
		return readyList.promise( obj );
	};
	
	// Kick off the DOM ready check even if the user does not
	jQuery.ready.promise();
	
	
	
	
	// Multifunctional method to get and set values of a collection
	// The value/s can optionally be executed if it's a function
	var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
		var i = 0,
			len = elems.length,
			bulk = key == null;
	
		// Sets many values
		if ( jQuery.type( key ) === "object" ) {
			chainable = true;
			for ( i in key ) {
				access( elems, fn, i, key[ i ], true, emptyGet, raw );
			}
	
		// Sets one value
		} else if ( value !== undefined ) {
			chainable = true;
	
			if ( !jQuery.isFunction( value ) ) {
				raw = true;
			}
	
			if ( bulk ) {
	
				// Bulk operations run against the entire set
				if ( raw ) {
					fn.call( elems, value );
					fn = null;
	
				// ...except when executing function values
				} else {
					bulk = fn;
					fn = function( elem, key, value ) {
						return bulk.call( jQuery( elem ), value );
					};
				}
			}
	
			if ( fn ) {
				for ( ; i < len; i++ ) {
					fn(
						elems[ i ], key, raw ?
						value :
						value.call( elems[ i ], i, fn( elems[ i ], key ) )
					);
				}
			}
		}
	
		return chainable ?
			elems :
	
			// Gets
			bulk ?
				fn.call( elems ) :
				len ? fn( elems[ 0 ], key ) : emptyGet;
	};
	var acceptData = function( owner ) {
	
		// Accepts only:
		//  - Node
		//    - Node.ELEMENT_NODE
		//    - Node.DOCUMENT_NODE
		//  - Object
		//    - Any
		/* jshint -W018 */
		return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
	};
	
	
	
	
	function Data() {
		this.expando = jQuery.expando + Data.uid++;
	}
	
	Data.uid = 1;
	
	Data.prototype = {
	
		register: function( owner, initial ) {
			var value = initial || {};
	
			// If it is a node unlikely to be stringify-ed or looped over
			// use plain assignment
			if ( owner.nodeType ) {
				owner[ this.expando ] = value;
	
			// Otherwise secure it in a non-enumerable, non-writable property
			// configurability must be true to allow the property to be
			// deleted with the delete operator
			} else {
				Object.defineProperty( owner, this.expando, {
					value: value,
					writable: true,
					configurable: true
				} );
			}
			return owner[ this.expando ];
		},
		cache: function( owner ) {
	
			// We can accept data for non-element nodes in modern browsers,
			// but we should not, see #8335.
			// Always return an empty object.
			if ( !acceptData( owner ) ) {
				return {};
			}
	
			// Check if the owner object already has a cache
			var value = owner[ this.expando ];
	
			// If not, create one
			if ( !value ) {
				value = {};
	
				// We can accept data for non-element nodes in modern browsers,
				// but we should not, see #8335.
				// Always return an empty object.
				if ( acceptData( owner ) ) {
	
					// If it is a node unlikely to be stringify-ed or looped over
					// use plain assignment
					if ( owner.nodeType ) {
						owner[ this.expando ] = value;
	
					// Otherwise secure it in a non-enumerable property
					// configurable must be true to allow the property to be
					// deleted when data is removed
					} else {
						Object.defineProperty( owner, this.expando, {
							value: value,
							configurable: true
						} );
					}
				}
			}
	
			return value;
		},
		set: function( owner, data, value ) {
			var prop,
				cache = this.cache( owner );
	
			// Handle: [ owner, key, value ] args
			if ( typeof data === "string" ) {
				cache[ data ] = value;
	
			// Handle: [ owner, { properties } ] args
			} else {
	
				// Copy the properties one-by-one to the cache object
				for ( prop in data ) {
					cache[ prop ] = data[ prop ];
				}
			}
			return cache;
		},
		get: function( owner, key ) {
			return key === undefined ?
				this.cache( owner ) :
				owner[ this.expando ] && owner[ this.expando ][ key ];
		},
		access: function( owner, key, value ) {
			var stored;
	
			// In cases where either:
			//
			//   1. No key was specified
			//   2. A string key was specified, but no value provided
			//
			// Take the "read" path and allow the get method to determine
			// which value to return, respectively either:
			//
			//   1. The entire cache object
			//   2. The data stored at the key
			//
			if ( key === undefined ||
					( ( key && typeof key === "string" ) && value === undefined ) ) {
	
				stored = this.get( owner, key );
	
				return stored !== undefined ?
					stored : this.get( owner, jQuery.camelCase( key ) );
			}
	
			// When the key is not a string, or both a key and value
			// are specified, set or extend (existing objects) with either:
			//
			//   1. An object of properties
			//   2. A key and value
			//
			this.set( owner, key, value );
	
			// Since the "set" path can have two possible entry points
			// return the expected data based on which path was taken[*]
			return value !== undefined ? value : key;
		},
		remove: function( owner, key ) {
			var i, name, camel,
				cache = owner[ this.expando ];
	
			if ( cache === undefined ) {
				return;
			}
	
			if ( key === undefined ) {
				this.register( owner );
	
			} else {
	
				// Support array or space separated string of keys
				if ( jQuery.isArray( key ) ) {
	
					// If "name" is an array of keys...
					// When data is initially created, via ("key", "val") signature,
					// keys will be converted to camelCase.
					// Since there is no way to tell _how_ a key was added, remove
					// both plain key and camelCase key. #12786
					// This will only penalize the array argument path.
					name = key.concat( key.map( jQuery.camelCase ) );
				} else {
					camel = jQuery.camelCase( key );
	
					// Try the string as a key before any manipulation
					if ( key in cache ) {
						name = [ key, camel ];
					} else {
	
						// If a key with the spaces exists, use it.
						// Otherwise, create an array by matching non-whitespace
						name = camel;
						name = name in cache ?
							[ name ] : ( name.match( rnotwhite ) || [] );
					}
				}
	
				i = name.length;
	
				while ( i-- ) {
					delete cache[ name[ i ] ];
				}
			}
	
			// Remove the expando if there's no more data
			if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
	
				// Support: Chrome <= 35-45+
				// Webkit & Blink performance suffers when deleting properties
				// from DOM nodes, so set to undefined instead
				// https://code.google.com/p/chromium/issues/detail?id=378607
				if ( owner.nodeType ) {
					owner[ this.expando ] = undefined;
				} else {
					delete owner[ this.expando ];
				}
			}
		},
		hasData: function( owner ) {
			var cache = owner[ this.expando ];
			return cache !== undefined && !jQuery.isEmptyObject( cache );
		}
	};
	var dataPriv = new Data();
	
	var dataUser = new Data();
	
	
	
	//	Implementation Summary
	//
	//	1. Enforce API surface and semantic compatibility with 1.9.x branch
	//	2. Improve the module's maintainability by reducing the storage
	//		paths to a single mechanism.
	//	3. Use the same single mechanism to support "private" and "user" data.
	//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
	//	5. Avoid exposing implementation details on user objects (eg. expando properties)
	//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
	
	var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
		rmultiDash = /[A-Z]/g;
	
	function dataAttr( elem, key, data ) {
		var name;
	
		// If nothing was found internally, try to fetch any
		// data from the HTML5 data-* attribute
		if ( data === undefined && elem.nodeType === 1 ) {
			name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
			data = elem.getAttribute( name );
	
			if ( typeof data === "string" ) {
				try {
					data = data === "true" ? true :
						data === "false" ? false :
						data === "null" ? null :
	
						// Only convert to a number if it doesn't change the string
						+data + "" === data ? +data :
						rbrace.test( data ) ? jQuery.parseJSON( data ) :
						data;
				} catch ( e ) {}
	
				// Make sure we set the data so it isn't changed later
				dataUser.set( elem, key, data );
			} else {
				data = undefined;
			}
		}
		return data;
	}
	
	jQuery.extend( {
		hasData: function( elem ) {
			return dataUser.hasData( elem ) || dataPriv.hasData( elem );
		},
	
		data: function( elem, name, data ) {
			return dataUser.access( elem, name, data );
		},
	
		removeData: function( elem, name ) {
			dataUser.remove( elem, name );
		},
	
		// TODO: Now that all calls to _data and _removeData have been replaced
		// with direct calls to dataPriv methods, these can be deprecated.
		_data: function( elem, name, data ) {
			return dataPriv.access( elem, name, data );
		},
	
		_removeData: function( elem, name ) {
			dataPriv.remove( elem, name );
		}
	} );
	
	jQuery.fn.extend( {
		data: function( key, value ) {
			var i, name, data,
				elem = this[ 0 ],
				attrs = elem && elem.attributes;
	
			// Gets all values
			if ( key === undefined ) {
				if ( this.length ) {
					data = dataUser.get( elem );
	
					if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
						i = attrs.length;
						while ( i-- ) {
	
							// Support: IE11+
							// The attrs elements can be null (#14894)
							if ( attrs[ i ] ) {
								name = attrs[ i ].name;
								if ( name.indexOf( "data-" ) === 0 ) {
									name = jQuery.camelCase( name.slice( 5 ) );
									dataAttr( elem, name, data[ name ] );
								}
							}
						}
						dataPriv.set( elem, "hasDataAttrs", true );
					}
				}
	
				return data;
			}
	
			// Sets multiple values
			if ( typeof key === "object" ) {
				return this.each( function() {
					dataUser.set( this, key );
				} );
			}
	
			return access( this, function( value ) {
				var data, camelKey;
	
				// The calling jQuery object (element matches) is not empty
				// (and therefore has an element appears at this[ 0 ]) and the
				// `value` parameter was not undefined. An empty jQuery object
				// will result in `undefined` for elem = this[ 0 ] which will
				// throw an exception if an attempt to read a data cache is made.
				if ( elem && value === undefined ) {
	
					// Attempt to get data from the cache
					// with the key as-is
					data = dataUser.get( elem, key ) ||
	
						// Try to find dashed key if it exists (gh-2779)
						// This is for 2.2.x only
						dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
	
					if ( data !== undefined ) {
						return data;
					}
	
					camelKey = jQuery.camelCase( key );
	
					// Attempt to get data from the cache
					// with the key camelized
					data = dataUser.get( elem, camelKey );
					if ( data !== undefined ) {
						return data;
					}
	
					// Attempt to "discover" the data in
					// HTML5 custom data-* attrs
					data = dataAttr( elem, camelKey, undefined );
					if ( data !== undefined ) {
						return data;
					}
	
					// We tried really hard, but the data doesn't exist.
					return;
				}
	
				// Set the data...
				camelKey = jQuery.camelCase( key );
				this.each( function() {
	
					// First, attempt to store a copy or reference of any
					// data that might've been store with a camelCased key.
					var data = dataUser.get( this, camelKey );
	
					// For HTML5 data-* attribute interop, we have to
					// store property names with dashes in a camelCase form.
					// This might not apply to all properties...*
					dataUser.set( this, camelKey, value );
	
					// *... In the case of properties that might _actually_
					// have dashes, we need to also store a copy of that
					// unchanged property.
					if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
						dataUser.set( this, key, value );
					}
				} );
			}, null, value, arguments.length > 1, null, true );
		},
	
		removeData: function( key ) {
			return this.each( function() {
				dataUser.remove( this, key );
			} );
		}
	} );
	
	
	jQuery.extend( {
		queue: function( elem, type, data ) {
			var queue;
	
			if ( elem ) {
				type = ( type || "fx" ) + "queue";
				queue = dataPriv.get( elem, type );
	
				// Speed up dequeue by getting out quickly if this is just a lookup
				if ( data ) {
					if ( !queue || jQuery.isArray( data ) ) {
						queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
					} else {
						queue.push( data );
					}
				}
				return queue || [];
			}
		},
	
		dequeue: function( elem, type ) {
			type = type || "fx";
	
			var queue = jQuery.queue( elem, type ),
				startLength = queue.length,
				fn = queue.shift(),
				hooks = jQuery._queueHooks( elem, type ),
				next = function() {
					jQuery.dequeue( elem, type );
				};
	
			// If the fx queue is dequeued, always remove the progress sentinel
			if ( fn === "inprogress" ) {
				fn = queue.shift();
				startLength--;
			}
	
			if ( fn ) {
	
				// Add a progress sentinel to prevent the fx queue from being
				// automatically dequeued
				if ( type === "fx" ) {
					queue.unshift( "inprogress" );
				}
	
				// Clear up the last queue stop function
				delete hooks.stop;
				fn.call( elem, next, hooks );
			}
	
			if ( !startLength && hooks ) {
				hooks.empty.fire();
			}
		},
	
		// Not public - generate a queueHooks object, or return the current one
		_queueHooks: function( elem, type ) {
			var key = type + "queueHooks";
			return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
				empty: jQuery.Callbacks( "once memory" ).add( function() {
					dataPriv.remove( elem, [ type + "queue", key ] );
				} )
			} );
		}
	} );
	
	jQuery.fn.extend( {
		queue: function( type, data ) {
			var setter = 2;
	
			if ( typeof type !== "string" ) {
				data = type;
				type = "fx";
				setter--;
			}
	
			if ( arguments.length < setter ) {
				return jQuery.queue( this[ 0 ], type );
			}
	
			return data === undefined ?
				this :
				this.each( function() {
					var queue = jQuery.queue( this, type, data );
	
					// Ensure a hooks for this queue
					jQuery._queueHooks( this, type );
	
					if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
						jQuery.dequeue( this, type );
					}
				} );
		},
		dequeue: function( type ) {
			return this.each( function() {
				jQuery.dequeue( this, type );
			} );
		},
		clearQueue: function( type ) {
			return this.queue( type || "fx", [] );
		},
	
		// Get a promise resolved when queues of a certain type
		// are emptied (fx is the type by default)
		promise: function( type, obj ) {
			var tmp,
				count = 1,
				defer = jQuery.Deferred(),
				elements = this,
				i = this.length,
				resolve = function() {
					if ( !( --count ) ) {
						defer.resolveWith( elements, [ elements ] );
					}
				};
	
			if ( typeof type !== "string" ) {
				obj = type;
				type = undefined;
			}
			type = type || "fx";
	
			while ( i-- ) {
				tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
				if ( tmp && tmp.empty ) {
					count++;
					tmp.empty.add( resolve );
				}
			}
			resolve();
			return defer.promise( obj );
		}
	} );
	var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
	
	var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
	
	
	var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
	
	var isHidden = function( elem, el ) {
	
			// isHidden might be called from jQuery#filter function;
			// in that case, element will be second argument
			elem = el || elem;
			return jQuery.css( elem, "display" ) === "none" ||
				!jQuery.contains( elem.ownerDocument, elem );
		};
	
	
	
	function adjustCSS( elem, prop, valueParts, tween ) {
		var adjusted,
			scale = 1,
			maxIterations = 20,
			currentValue = tween ?
				function() { return tween.cur(); } :
				function() { return jQuery.css( elem, prop, "" ); },
			initial = currentValue(),
			unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
	
			// Starting value computation is required for potential unit mismatches
			initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
				rcssNum.exec( jQuery.css( elem, prop ) );
	
		if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
	
			// Trust units reported by jQuery.css
			unit = unit || initialInUnit[ 3 ];
	
			// Make sure we update the tween properties later on
			valueParts = valueParts || [];
	
			// Iteratively approximate from a nonzero starting point
			initialInUnit = +initial || 1;
	
			do {
	
				// If previous iteration zeroed out, double until we get *something*.
				// Use string for doubling so we don't accidentally see scale as unchanged below
				scale = scale || ".5";
	
				// Adjust and apply
				initialInUnit = initialInUnit / scale;
				jQuery.style( elem, prop, initialInUnit + unit );
	
			// Update scale, tolerating zero or NaN from tween.cur()
			// Break the loop if scale is unchanged or perfect, or if we've just had enough.
			} while (
				scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
			);
		}
	
		if ( valueParts ) {
			initialInUnit = +initialInUnit || +initial || 0;
	
			// Apply relative offset (+=/-=) if specified
			adjusted = valueParts[ 1 ] ?
				initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
				+valueParts[ 2 ];
			if ( tween ) {
				tween.unit = unit;
				tween.start = initialInUnit;
				tween.end = adjusted;
			}
		}
		return adjusted;
	}
	var rcheckableType = ( /^(?:checkbox|radio)$/i );
	
	var rtagName = ( /<([\w:-]+)/ );
	
	var rscriptType = ( /^$|\/(?:java|ecma)script/i );
	
	
	
	// We have to close these tags to support XHTML (#13200)
	var wrapMap = {
	
		// Support: IE9
		option: [ 1, "<select multiple='multiple'>", "</select>" ],
	
		// XHTML parsers do not magically insert elements in the
		// same way that tag soup parsers do. So we cannot shorten
		// this by omitting <tbody> or other required elements.
		thead: [ 1, "<table>", "</table>" ],
		col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
	
		_default: [ 0, "", "" ]
	};
	
	// Support: IE9
	wrapMap.optgroup = wrapMap.option;
	
	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
	wrapMap.th = wrapMap.td;
	
	
	function getAll( context, tag ) {
	
		// Support: IE9-11+
		// Use typeof to avoid zero-argument method invocation on host objects (#15151)
		var ret = typeof context.getElementsByTagName !== "undefined" ?
				context.getElementsByTagName( tag || "*" ) :
				typeof context.querySelectorAll !== "undefined" ?
					context.querySelectorAll( tag || "*" ) :
				[];
	
		return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
			jQuery.merge( [ context ], ret ) :
			ret;
	}
	
	
	// Mark scripts as having already been evaluated
	function setGlobalEval( elems, refElements ) {
		var i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			dataPriv.set(
				elems[ i ],
				"globalEval",
				!refElements || dataPriv.get( refElements[ i ], "globalEval" )
			);
		}
	}
	
	
	var rhtml = /<|&#?\w+;/;
	
	function buildFragment( elems, context, scripts, selection, ignored ) {
		var elem, tmp, tag, wrap, contains, j,
			fragment = context.createDocumentFragment(),
			nodes = [],
			i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			elem = elems[ i ];
	
			if ( elem || elem === 0 ) {
	
				// Add nodes directly
				if ( jQuery.type( elem ) === "object" ) {
	
					// Support: Android<4.1, PhantomJS<2
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
	
				// Convert non-html into a text node
				} else if ( !rhtml.test( elem ) ) {
					nodes.push( context.createTextNode( elem ) );
	
				// Convert html into DOM nodes
				} else {
					tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
	
					// Deserialize a standard representation
					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
					wrap = wrapMap[ tag ] || wrapMap._default;
					tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
	
					// Descend through wrappers to the right content
					j = wrap[ 0 ];
					while ( j-- ) {
						tmp = tmp.lastChild;
					}
	
					// Support: Android<4.1, PhantomJS<2
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, tmp.childNodes );
	
					// Remember the top-level container
					tmp = fragment.firstChild;
	
					// Ensure the created nodes are orphaned (#12392)
					tmp.textContent = "";
				}
			}
		}
	
		// Remove wrapper from fragment
		fragment.textContent = "";
	
		i = 0;
		while ( ( elem = nodes[ i++ ] ) ) {
	
			// Skip elements already in the context collection (trac-4087)
			if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
				if ( ignored ) {
					ignored.push( elem );
				}
				continue;
			}
	
			contains = jQuery.contains( elem.ownerDocument, elem );
	
			// Append to fragment
			tmp = getAll( fragment.appendChild( elem ), "script" );
	
			// Preserve script evaluation history
			if ( contains ) {
				setGlobalEval( tmp );
			}
	
			// Capture executables
			if ( scripts ) {
				j = 0;
				while ( ( elem = tmp[ j++ ] ) ) {
					if ( rscriptType.test( elem.type || "" ) ) {
						scripts.push( elem );
					}
				}
			}
		}
	
		return fragment;
	}
	
	
	( function() {
		var fragment = document.createDocumentFragment(),
			div = fragment.appendChild( document.createElement( "div" ) ),
			input = document.createElement( "input" );
	
		// Support: Android 4.0-4.3, Safari<=5.1
		// Check state lost if the name is set (#11217)
		// Support: Windows Web Apps (WWA)
		// `name` and `type` must use .setAttribute for WWA (#14901)
		input.setAttribute( "type", "radio" );
		input.setAttribute( "checked", "checked" );
		input.setAttribute( "name", "t" );
	
		div.appendChild( input );
	
		// Support: Safari<=5.1, Android<4.2
		// Older WebKit doesn't clone checked state correctly in fragments
		support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
	
		// Support: IE<=11+
		// Make sure textarea (and checkbox) defaultValue is properly cloned
		div.innerHTML = "<textarea>x</textarea>";
		support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
	} )();
	
	
	var
		rkeyEvent = /^key/,
		rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
		rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
	
	function returnTrue() {
		return true;
	}
	
	function returnFalse() {
		return false;
	}
	
	// Support: IE9
	// See #13393 for more info
	function safeActiveElement() {
		try {
			return document.activeElement;
		} catch ( err ) { }
	}
	
	function on( elem, types, selector, data, fn, one ) {
		var origFn, type;
	
		// Types can be a map of types/handlers
		if ( typeof types === "object" ) {
	
			// ( types-Object, selector, data )
			if ( typeof selector !== "string" ) {
	
				// ( types-Object, data )
				data = data || selector;
				selector = undefined;
			}
			for ( type in types ) {
				on( elem, type, selector, data, types[ type ], one );
			}
			return elem;
		}
	
		if ( data == null && fn == null ) {
	
			// ( types, fn )
			fn = selector;
			data = selector = undefined;
		} else if ( fn == null ) {
			if ( typeof selector === "string" ) {
	
				// ( types, selector, fn )
				fn = data;
				data = undefined;
			} else {
	
				// ( types, data, fn )
				fn = data;
				data = selector;
				selector = undefined;
			}
		}
		if ( fn === false ) {
			fn = returnFalse;
		} else if ( !fn ) {
			return elem;
		}
	
		if ( one === 1 ) {
			origFn = fn;
			fn = function( event ) {
	
				// Can use an empty set, since event contains the info
				jQuery().off( event );
				return origFn.apply( this, arguments );
			};
	
			// Use same guid so caller can remove using origFn
			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
		}
		return elem.each( function() {
			jQuery.event.add( this, types, fn, data, selector );
		} );
	}
	
	/*
	 * Helper functions for managing events -- not part of the public interface.
	 * Props to Dean Edwards' addEvent library for many of the ideas.
	 */
	jQuery.event = {
	
		global: {},
	
		add: function( elem, types, handler, data, selector ) {
	
			var handleObjIn, eventHandle, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.get( elem );
	
			// Don't attach events to noData or text/comment nodes (but allow plain objects)
			if ( !elemData ) {
				return;
			}
	
			// Caller can pass in an object of custom data in lieu of the handler
			if ( handler.handler ) {
				handleObjIn = handler;
				handler = handleObjIn.handler;
				selector = handleObjIn.selector;
			}
	
			// Make sure that the handler has a unique ID, used to find/remove it later
			if ( !handler.guid ) {
				handler.guid = jQuery.guid++;
			}
	
			// Init the element's event structure and main handler, if this is the first
			if ( !( events = elemData.events ) ) {
				events = elemData.events = {};
			}
			if ( !( eventHandle = elemData.handle ) ) {
				eventHandle = elemData.handle = function( e ) {
	
					// Discard the second event of a jQuery.event.trigger() and
					// when an event is called after a page has unloaded
					return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
						jQuery.event.dispatch.apply( elem, arguments ) : undefined;
				};
			}
	
			// Handle multiple events separated by a space
			types = ( types || "" ).match( rnotwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// There *must* be a type, no attaching namespace-only handlers
				if ( !type ) {
					continue;
				}
	
				// If event changes its type, use the special event handlers for the changed type
				special = jQuery.event.special[ type ] || {};
	
				// If selector defined, determine special event api type, otherwise given type
				type = ( selector ? special.delegateType : special.bindType ) || type;
	
				// Update special based on newly reset type
				special = jQuery.event.special[ type ] || {};
	
				// handleObj is passed to all event handlers
				handleObj = jQuery.extend( {
					type: type,
					origType: origType,
					data: data,
					handler: handler,
					guid: handler.guid,
					selector: selector,
					needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
					namespace: namespaces.join( "." )
				}, handleObjIn );
	
				// Init the event handler queue if we're the first
				if ( !( handlers = events[ type ] ) ) {
					handlers = events[ type ] = [];
					handlers.delegateCount = 0;
	
					// Only use addEventListener if the special events handler returns false
					if ( !special.setup ||
						special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
	
						if ( elem.addEventListener ) {
							elem.addEventListener( type, eventHandle );
						}
					}
				}
	
				if ( special.add ) {
					special.add.call( elem, handleObj );
	
					if ( !handleObj.handler.guid ) {
						handleObj.handler.guid = handler.guid;
					}
				}
	
				// Add to the element's handler list, delegates in front
				if ( selector ) {
					handlers.splice( handlers.delegateCount++, 0, handleObj );
				} else {
					handlers.push( handleObj );
				}
	
				// Keep track of which events have ever been used, for event optimization
				jQuery.event.global[ type ] = true;
			}
	
		},
	
		// Detach an event or set of events from an element
		remove: function( elem, types, handler, selector, mappedTypes ) {
	
			var j, origCount, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
	
			if ( !elemData || !( events = elemData.events ) ) {
				return;
			}
	
			// Once for each type.namespace in types; type may be omitted
			types = ( types || "" ).match( rnotwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// Unbind all events (on this namespace, if provided) for the element
				if ( !type ) {
					for ( type in events ) {
						jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
					}
					continue;
				}
	
				special = jQuery.event.special[ type ] || {};
				type = ( selector ? special.delegateType : special.bindType ) || type;
				handlers = events[ type ] || [];
				tmp = tmp[ 2 ] &&
					new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
	
				// Remove matching events
				origCount = j = handlers.length;
				while ( j-- ) {
					handleObj = handlers[ j ];
	
					if ( ( mappedTypes || origType === handleObj.origType ) &&
						( !handler || handler.guid === handleObj.guid ) &&
						( !tmp || tmp.test( handleObj.namespace ) ) &&
						( !selector || selector === handleObj.selector ||
							selector === "**" && handleObj.selector ) ) {
						handlers.splice( j, 1 );
	
						if ( handleObj.selector ) {
							handlers.delegateCount--;
						}
						if ( special.remove ) {
							special.remove.call( elem, handleObj );
						}
					}
				}
	
				// Remove generic event handler if we removed something and no more handlers exist
				// (avoids potential for endless recursion during removal of special event handlers)
				if ( origCount && !handlers.length ) {
					if ( !special.teardown ||
						special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
	
						jQuery.removeEvent( elem, type, elemData.handle );
					}
	
					delete events[ type ];
				}
			}
	
			// Remove data and the expando if it's no longer used
			if ( jQuery.isEmptyObject( events ) ) {
				dataPriv.remove( elem, "handle events" );
			}
		},
	
		dispatch: function( event ) {
	
			// Make a writable jQuery.Event from the native event object
			event = jQuery.event.fix( event );
	
			var i, j, ret, matched, handleObj,
				handlerQueue = [],
				args = slice.call( arguments ),
				handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
				special = jQuery.event.special[ event.type ] || {};
	
			// Use the fix-ed jQuery.Event rather than the (read-only) native event
			args[ 0 ] = event;
			event.delegateTarget = this;
	
			// Call the preDispatch hook for the mapped type, and let it bail if desired
			if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
				return;
			}
	
			// Determine handlers
			handlerQueue = jQuery.event.handlers.call( this, event, handlers );
	
			// Run delegates first; they may want to stop propagation beneath us
			i = 0;
			while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
				event.currentTarget = matched.elem;
	
				j = 0;
				while ( ( handleObj = matched.handlers[ j++ ] ) &&
					!event.isImmediatePropagationStopped() ) {
	
					// Triggered event must either 1) have no namespace, or 2) have namespace(s)
					// a subset or equal to those in the bound event (both can have no namespace).
					if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
	
						event.handleObj = handleObj;
						event.data = handleObj.data;
	
						ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
							handleObj.handler ).apply( matched.elem, args );
	
						if ( ret !== undefined ) {
							if ( ( event.result = ret ) === false ) {
								event.preventDefault();
								event.stopPropagation();
							}
						}
					}
				}
			}
	
			// Call the postDispatch hook for the mapped type
			if ( special.postDispatch ) {
				special.postDispatch.call( this, event );
			}
	
			return event.result;
		},
	
		handlers: function( event, handlers ) {
			var i, matches, sel, handleObj,
				handlerQueue = [],
				delegateCount = handlers.delegateCount,
				cur = event.target;
	
			// Support (at least): Chrome, IE9
			// Find delegate handlers
			// Black-hole SVG <use> instance trees (#13180)
			//
			// Support: Firefox<=42+
			// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
			if ( delegateCount && cur.nodeType &&
				( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
	
				for ( ; cur !== this; cur = cur.parentNode || this ) {
	
					// Don't check non-elements (#13208)
					// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
					if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
						matches = [];
						for ( i = 0; i < delegateCount; i++ ) {
							handleObj = handlers[ i ];
	
							// Don't conflict with Object.prototype properties (#13203)
							sel = handleObj.selector + " ";
	
							if ( matches[ sel ] === undefined ) {
								matches[ sel ] = handleObj.needsContext ?
									jQuery( sel, this ).index( cur ) > -1 :
									jQuery.find( sel, this, null, [ cur ] ).length;
							}
							if ( matches[ sel ] ) {
								matches.push( handleObj );
							}
						}
						if ( matches.length ) {
							handlerQueue.push( { elem: cur, handlers: matches } );
						}
					}
				}
			}
	
			// Add the remaining (directly-bound) handlers
			if ( delegateCount < handlers.length ) {
				handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
			}
	
			return handlerQueue;
		},
	
		// Includes some event props shared by KeyEvent and MouseEvent
		props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
			"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
	
		fixHooks: {},
	
		keyHooks: {
			props: "char charCode key keyCode".split( " " ),
			filter: function( event, original ) {
	
				// Add which for key events
				if ( event.which == null ) {
					event.which = original.charCode != null ? original.charCode : original.keyCode;
				}
	
				return event;
			}
		},
	
		mouseHooks: {
			props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
				"screenX screenY toElement" ).split( " " ),
			filter: function( event, original ) {
				var eventDoc, doc, body,
					button = original.button;
	
				// Calculate pageX/Y if missing and clientX/Y available
				if ( event.pageX == null && original.clientX != null ) {
					eventDoc = event.target.ownerDocument || document;
					doc = eventDoc.documentElement;
					body = eventDoc.body;
	
					event.pageX = original.clientX +
						( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
						( doc && doc.clientLeft || body && body.clientLeft || 0 );
					event.pageY = original.clientY +
						( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
						( doc && doc.clientTop  || body && body.clientTop  || 0 );
				}
	
				// Add which for click: 1 === left; 2 === middle; 3 === right
				// Note: button is not normalized, so don't use it
				if ( !event.which && button !== undefined ) {
					event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
				}
	
				return event;
			}
		},
	
		fix: function( event ) {
			if ( event[ jQuery.expando ] ) {
				return event;
			}
	
			// Create a writable copy of the event object and normalize some properties
			var i, prop, copy,
				type = event.type,
				originalEvent = event,
				fixHook = this.fixHooks[ type ];
	
			if ( !fixHook ) {
				this.fixHooks[ type ] = fixHook =
					rmouseEvent.test( type ) ? this.mouseHooks :
					rkeyEvent.test( type ) ? this.keyHooks :
					{};
			}
			copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
	
			event = new jQuery.Event( originalEvent );
	
			i = copy.length;
			while ( i-- ) {
				prop = copy[ i ];
				event[ prop ] = originalEvent[ prop ];
			}
	
			// Support: Cordova 2.5 (WebKit) (#13255)
			// All events should have a target; Cordova deviceready doesn't
			if ( !event.target ) {
				event.target = document;
			}
	
			// Support: Safari 6.0+, Chrome<28
			// Target should not be a text node (#504, #13143)
			if ( event.target.nodeType === 3 ) {
				event.target = event.target.parentNode;
			}
	
			return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
		},
	
		special: {
			load: {
	
				// Prevent triggered image.load events from bubbling to window.load
				noBubble: true
			},
			focus: {
	
				// Fire native event if possible so blur/focus sequence is correct
				trigger: function() {
					if ( this !== safeActiveElement() && this.focus ) {
						this.focus();
						return false;
					}
				},
				delegateType: "focusin"
			},
			blur: {
				trigger: function() {
					if ( this === safeActiveElement() && this.blur ) {
						this.blur();
						return false;
					}
				},
				delegateType: "focusout"
			},
			click: {
	
				// For checkbox, fire native event so checked state will be right
				trigger: function() {
					if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
						this.click();
						return false;
					}
				},
	
				// For cross-browser consistency, don't fire native .click() on links
				_default: function( event ) {
					return jQuery.nodeName( event.target, "a" );
				}
			},
	
			beforeunload: {
				postDispatch: function( event ) {
	
					// Support: Firefox 20+
					// Firefox doesn't alert if the returnValue field is not set.
					if ( event.result !== undefined && event.originalEvent ) {
						event.originalEvent.returnValue = event.result;
					}
				}
			}
		}
	};
	
	jQuery.removeEvent = function( elem, type, handle ) {
	
		// This "if" is needed for plain objects
		if ( elem.removeEventListener ) {
			elem.removeEventListener( type, handle );
		}
	};
	
	jQuery.Event = function( src, props ) {
	
		// Allow instantiation without the 'new' keyword
		if ( !( this instanceof jQuery.Event ) ) {
			return new jQuery.Event( src, props );
		}
	
		// Event object
		if ( src && src.type ) {
			this.originalEvent = src;
			this.type = src.type;
	
			// Events bubbling up the document may have been marked as prevented
			// by a handler lower down the tree; reflect the correct value.
			this.isDefaultPrevented = src.defaultPrevented ||
					src.defaultPrevented === undefined &&
	
					// Support: Android<4.0
					src.returnValue === false ?
				returnTrue :
				returnFalse;
	
		// Event type
		} else {
			this.type = src;
		}
	
		// Put explicitly provided properties onto the event object
		if ( props ) {
			jQuery.extend( this, props );
		}
	
		// Create a timestamp if incoming event doesn't have one
		this.timeStamp = src && src.timeStamp || jQuery.now();
	
		// Mark it as fixed
		this[ jQuery.expando ] = true;
	};
	
	// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
	// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
	jQuery.Event.prototype = {
		constructor: jQuery.Event,
		isDefaultPrevented: returnFalse,
		isPropagationStopped: returnFalse,
		isImmediatePropagationStopped: returnFalse,
		isSimulated: false,
	
		preventDefault: function() {
			var e = this.originalEvent;
	
			this.isDefaultPrevented = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.preventDefault();
			}
		},
		stopPropagation: function() {
			var e = this.originalEvent;
	
			this.isPropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopPropagation();
			}
		},
		stopImmediatePropagation: function() {
			var e = this.originalEvent;
	
			this.isImmediatePropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopImmediatePropagation();
			}
	
			this.stopPropagation();
		}
	};
	
	// Create mouseenter/leave events using mouseover/out and event-time checks
	// so that event delegation works in jQuery.
	// Do the same for pointerenter/pointerleave and pointerover/pointerout
	//
	// Support: Safari 7 only
	// Safari sends mouseenter too often; see:
	// https://code.google.com/p/chromium/issues/detail?id=470258
	// for the description of the bug (it existed in older Chrome versions as well).
	jQuery.each( {
		mouseenter: "mouseover",
		mouseleave: "mouseout",
		pointerenter: "pointerover",
		pointerleave: "pointerout"
	}, function( orig, fix ) {
		jQuery.event.special[ orig ] = {
			delegateType: fix,
			bindType: fix,
	
			handle: function( event ) {
				var ret,
					target = this,
					related = event.relatedTarget,
					handleObj = event.handleObj;
	
				// For mouseenter/leave call the handler if related is outside the target.
				// NB: No relatedTarget if the mouse left/entered the browser window
				if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
					event.type = handleObj.origType;
					ret = handleObj.handler.apply( this, arguments );
					event.type = fix;
				}
				return ret;
			}
		};
	} );
	
	jQuery.fn.extend( {
		on: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn );
		},
		one: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn, 1 );
		},
		off: function( types, selector, fn ) {
			var handleObj, type;
			if ( types && types.preventDefault && types.handleObj ) {
	
				// ( event )  dispatched jQuery.Event
				handleObj = types.handleObj;
				jQuery( types.delegateTarget ).off(
					handleObj.namespace ?
						handleObj.origType + "." + handleObj.namespace :
						handleObj.origType,
					handleObj.selector,
					handleObj.handler
				);
				return this;
			}
			if ( typeof types === "object" ) {
	
				// ( types-object [, selector] )
				for ( type in types ) {
					this.off( type, selector, types[ type ] );
				}
				return this;
			}
			if ( selector === false || typeof selector === "function" ) {
	
				// ( types [, fn] )
				fn = selector;
				selector = undefined;
			}
			if ( fn === false ) {
				fn = returnFalse;
			}
			return this.each( function() {
				jQuery.event.remove( this, types, fn, selector );
			} );
		}
	} );
	
	
	var
		rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
	
		// Support: IE 10-11, Edge 10240+
		// In IE/Edge using regex groups here causes severe slowdowns.
		// See https://connect.microsoft.com/IE/feedback/details/1736512/
		rnoInnerhtml = /<script|<style|<link/i,
	
		// checked="checked" or checked
		rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
		rscriptTypeMasked = /^true\/(.*)/,
		rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
	
	// Manipulating tables requires a tbody
	function manipulationTarget( elem, content ) {
		return jQuery.nodeName( elem, "table" ) &&
			jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
	
			elem.getElementsByTagName( "tbody" )[ 0 ] ||
				elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
			elem;
	}
	
	// Replace/restore the type attribute of script elements for safe DOM manipulation
	function disableScript( elem ) {
		elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
		return elem;
	}
	function restoreScript( elem ) {
		var match = rscriptTypeMasked.exec( elem.type );
	
		if ( match ) {
			elem.type = match[ 1 ];
		} else {
			elem.removeAttribute( "type" );
		}
	
		return elem;
	}
	
	function cloneCopyEvent( src, dest ) {
		var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
	
		if ( dest.nodeType !== 1 ) {
			return;
		}
	
		// 1. Copy private data: events, handlers, etc.
		if ( dataPriv.hasData( src ) ) {
			pdataOld = dataPriv.access( src );
			pdataCur = dataPriv.set( dest, pdataOld );
			events = pdataOld.events;
	
			if ( events ) {
				delete pdataCur.handle;
				pdataCur.events = {};
	
				for ( type in events ) {
					for ( i = 0, l = events[ type ].length; i < l; i++ ) {
						jQuery.event.add( dest, type, events[ type ][ i ] );
					}
				}
			}
		}
	
		// 2. Copy user data
		if ( dataUser.hasData( src ) ) {
			udataOld = dataUser.access( src );
			udataCur = jQuery.extend( {}, udataOld );
	
			dataUser.set( dest, udataCur );
		}
	}
	
	// Fix IE bugs, see support tests
	function fixInput( src, dest ) {
		var nodeName = dest.nodeName.toLowerCase();
	
		// Fails to persist the checked state of a cloned checkbox or radio button.
		if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
			dest.checked = src.checked;
	
		// Fails to return the selected option to the default selected state when cloning options
		} else if ( nodeName === "input" || nodeName === "textarea" ) {
			dest.defaultValue = src.defaultValue;
		}
	}
	
	function domManip( collection, args, callback, ignored ) {
	
		// Flatten any nested arrays
		args = concat.apply( [], args );
	
		var fragment, first, scripts, hasScripts, node, doc,
			i = 0,
			l = collection.length,
			iNoClone = l - 1,
			value = args[ 0 ],
			isFunction = jQuery.isFunction( value );
	
		// We can't cloneNode fragments that contain checked, in WebKit
		if ( isFunction ||
				( l > 1 && typeof value === "string" &&
					!support.checkClone && rchecked.test( value ) ) ) {
			return collection.each( function( index ) {
				var self = collection.eq( index );
				if ( isFunction ) {
					args[ 0 ] = value.call( this, index, self.html() );
				}
				domManip( self, args, callback, ignored );
			} );
		}
	
		if ( l ) {
			fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
			first = fragment.firstChild;
	
			if ( fragment.childNodes.length === 1 ) {
				fragment = first;
			}
	
			// Require either new content or an interest in ignored elements to invoke the callback
			if ( first || ignored ) {
				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
				hasScripts = scripts.length;
	
				// Use the original fragment for the last item
				// instead of the first because it can end up
				// being emptied incorrectly in certain situations (#8070).
				for ( ; i < l; i++ ) {
					node = fragment;
	
					if ( i !== iNoClone ) {
						node = jQuery.clone( node, true, true );
	
						// Keep references to cloned scripts for later restoration
						if ( hasScripts ) {
	
							// Support: Android<4.1, PhantomJS<2
							// push.apply(_, arraylike) throws on ancient WebKit
							jQuery.merge( scripts, getAll( node, "script" ) );
						}
					}
	
					callback.call( collection[ i ], node, i );
				}
	
				if ( hasScripts ) {
					doc = scripts[ scripts.length - 1 ].ownerDocument;
	
					// Reenable scripts
					jQuery.map( scripts, restoreScript );
	
					// Evaluate executable scripts on first document insertion
					for ( i = 0; i < hasScripts; i++ ) {
						node = scripts[ i ];
						if ( rscriptType.test( node.type || "" ) &&
							!dataPriv.access( node, "globalEval" ) &&
							jQuery.contains( doc, node ) ) {
	
							if ( node.src ) {
	
								// Optional AJAX dependency, but won't run scripts if not present
								if ( jQuery._evalUrl ) {
									jQuery._evalUrl( node.src );
								}
							} else {
								jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
							}
						}
					}
				}
			}
		}
	
		return collection;
	}
	
	function remove( elem, selector, keepData ) {
		var node,
			nodes = selector ? jQuery.filter( selector, elem ) : elem,
			i = 0;
	
		for ( ; ( node = nodes[ i ] ) != null; i++ ) {
			if ( !keepData && node.nodeType === 1 ) {
				jQuery.cleanData( getAll( node ) );
			}
	
			if ( node.parentNode ) {
				if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
					setGlobalEval( getAll( node, "script" ) );
				}
				node.parentNode.removeChild( node );
			}
		}
	
		return elem;
	}
	
	jQuery.extend( {
		htmlPrefilter: function( html ) {
			return html.replace( rxhtmlTag, "<$1></$2>" );
		},
	
		clone: function( elem, dataAndEvents, deepDataAndEvents ) {
			var i, l, srcElements, destElements,
				clone = elem.cloneNode( true ),
				inPage = jQuery.contains( elem.ownerDocument, elem );
	
			// Fix IE cloning issues
			if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
					!jQuery.isXMLDoc( elem ) ) {
	
				// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
				destElements = getAll( clone );
				srcElements = getAll( elem );
	
				for ( i = 0, l = srcElements.length; i < l; i++ ) {
					fixInput( srcElements[ i ], destElements[ i ] );
				}
			}
	
			// Copy the events from the original to the clone
			if ( dataAndEvents ) {
				if ( deepDataAndEvents ) {
					srcElements = srcElements || getAll( elem );
					destElements = destElements || getAll( clone );
	
					for ( i = 0, l = srcElements.length; i < l; i++ ) {
						cloneCopyEvent( srcElements[ i ], destElements[ i ] );
					}
				} else {
					cloneCopyEvent( elem, clone );
				}
			}
	
			// Preserve script evaluation history
			destElements = getAll( clone, "script" );
			if ( destElements.length > 0 ) {
				setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
			}
	
			// Return the cloned set
			return clone;
		},
	
		cleanData: function( elems ) {
			var data, elem, type,
				special = jQuery.event.special,
				i = 0;
	
			for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
				if ( acceptData( elem ) ) {
					if ( ( data = elem[ dataPriv.expando ] ) ) {
						if ( data.events ) {
							for ( type in data.events ) {
								if ( special[ type ] ) {
									jQuery.event.remove( elem, type );
	
								// This is a shortcut to avoid jQuery.event.remove's overhead
								} else {
									jQuery.removeEvent( elem, type, data.handle );
								}
							}
						}
	
						// Support: Chrome <= 35-45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataPriv.expando ] = undefined;
					}
					if ( elem[ dataUser.expando ] ) {
	
						// Support: Chrome <= 35-45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataUser.expando ] = undefined;
					}
				}
			}
		}
	} );
	
	jQuery.fn.extend( {
	
		// Keep domManip exposed until 3.0 (gh-2225)
		domManip: domManip,
	
		detach: function( selector ) {
			return remove( this, selector, true );
		},
	
		remove: function( selector ) {
			return remove( this, selector );
		},
	
		text: function( value ) {
			return access( this, function( value ) {
				return value === undefined ?
					jQuery.text( this ) :
					this.empty().each( function() {
						if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
							this.textContent = value;
						}
					} );
			}, null, value, arguments.length );
		},
	
		append: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.appendChild( elem );
				}
			} );
		},
	
		prepend: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.insertBefore( elem, target.firstChild );
				}
			} );
		},
	
		before: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this );
				}
			} );
		},
	
		after: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this.nextSibling );
				}
			} );
		},
	
		empty: function() {
			var elem,
				i = 0;
	
			for ( ; ( elem = this[ i ] ) != null; i++ ) {
				if ( elem.nodeType === 1 ) {
	
					// Prevent memory leaks
					jQuery.cleanData( getAll( elem, false ) );
	
					// Remove any remaining nodes
					elem.textContent = "";
				}
			}
	
			return this;
		},
	
		clone: function( dataAndEvents, deepDataAndEvents ) {
			dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
			deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
	
			return this.map( function() {
				return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
			} );
		},
	
		html: function( value ) {
			return access( this, function( value ) {
				var elem = this[ 0 ] || {},
					i = 0,
					l = this.length;
	
				if ( value === undefined && elem.nodeType === 1 ) {
					return elem.innerHTML;
				}
	
				// See if we can take a shortcut and just use innerHTML
				if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
					!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
	
					value = jQuery.htmlPrefilter( value );
	
					try {
						for ( ; i < l; i++ ) {
							elem = this[ i ] || {};
	
							// Remove element nodes and prevent memory leaks
							if ( elem.nodeType === 1 ) {
								jQuery.cleanData( getAll( elem, false ) );
								elem.innerHTML = value;
							}
						}
	
						elem = 0;
	
					// If using innerHTML throws an exception, use the fallback method
					} catch ( e ) {}
				}
	
				if ( elem ) {
					this.empty().append( value );
				}
			}, null, value, arguments.length );
		},
	
		replaceWith: function() {
			var ignored = [];
	
			// Make the changes, replacing each non-ignored context element with the new content
			return domManip( this, arguments, function( elem ) {
				var parent = this.parentNode;
	
				if ( jQuery.inArray( this, ignored ) < 0 ) {
					jQuery.cleanData( getAll( this ) );
					if ( parent ) {
						parent.replaceChild( elem, this );
					}
				}
	
			// Force callback invocation
			}, ignored );
		}
	} );
	
	jQuery.each( {
		appendTo: "append",
		prependTo: "prepend",
		insertBefore: "before",
		insertAfter: "after",
		replaceAll: "replaceWith"
	}, function( name, original ) {
		jQuery.fn[ name ] = function( selector ) {
			var elems,
				ret = [],
				insert = jQuery( selector ),
				last = insert.length - 1,
				i = 0;
	
			for ( ; i <= last; i++ ) {
				elems = i === last ? this : this.clone( true );
				jQuery( insert[ i ] )[ original ]( elems );
	
				// Support: QtWebKit
				// .get() because push.apply(_, arraylike) throws
				push.apply( ret, elems.get() );
			}
	
			return this.pushStack( ret );
		};
	} );
	
	
	var iframe,
		elemdisplay = {
	
			// Support: Firefox
			// We have to pre-define these values for FF (#10227)
			HTML: "block",
			BODY: "block"
		};
	
	/**
	 * Retrieve the actual display of a element
	 * @param {String} name nodeName of the element
	 * @param {Object} doc Document object
	 */
	
	// Called only from within defaultDisplay
	function actualDisplay( name, doc ) {
		var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
	
			display = jQuery.css( elem[ 0 ], "display" );
	
		// We don't have any data stored on the element,
		// so use "detach" method as fast way to get rid of the element
		elem.detach();
	
		return display;
	}
	
	/**
	 * Try to determine the default display value of an element
	 * @param {String} nodeName
	 */
	function defaultDisplay( nodeName ) {
		var doc = document,
			display = elemdisplay[ nodeName ];
	
		if ( !display ) {
			display = actualDisplay( nodeName, doc );
	
			// If the simple way fails, read from inside an iframe
			if ( display === "none" || !display ) {
	
				// Use the already-created iframe if possible
				iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
					.appendTo( doc.documentElement );
	
				// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
				doc = iframe[ 0 ].contentDocument;
	
				// Support: IE
				doc.write();
				doc.close();
	
				display = actualDisplay( nodeName, doc );
				iframe.detach();
			}
	
			// Store the correct default display
			elemdisplay[ nodeName ] = display;
		}
	
		return display;
	}
	var rmargin = ( /^margin/ );
	
	var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
	
	var getStyles = function( elem ) {
	
			// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
			// IE throws on elements created in popups
			// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
			var view = elem.ownerDocument.defaultView;
	
			if ( !view || !view.opener ) {
				view = window;
			}
	
			return view.getComputedStyle( elem );
		};
	
	var swap = function( elem, options, callback, args ) {
		var ret, name,
			old = {};
	
		// Remember the old values, and insert the new ones
		for ( name in options ) {
			old[ name ] = elem.style[ name ];
			elem.style[ name ] = options[ name ];
		}
	
		ret = callback.apply( elem, args || [] );
	
		// Revert the old values
		for ( name in options ) {
			elem.style[ name ] = old[ name ];
		}
	
		return ret;
	};
	
	
	var documentElement = document.documentElement;
	
	
	
	( function() {
		var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
			container = document.createElement( "div" ),
			div = document.createElement( "div" );
	
		// Finish early in limited (non-browser) environments
		if ( !div.style ) {
			return;
		}
	
		// Support: IE9-11+
		// Style of cloned element affects source element cloned (#8908)
		div.style.backgroundClip = "content-box";
		div.cloneNode( true ).style.backgroundClip = "";
		support.clearCloneStyle = div.style.backgroundClip === "content-box";
	
		container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
			"padding:0;margin-top:1px;position:absolute";
		container.appendChild( div );
	
		// Executing both pixelPosition & boxSizingReliable tests require only one layout
		// so they're executed at the same time to save the second computation.
		function computeStyleTests() {
			div.style.cssText =
	
				// Support: Firefox<29, Android 2.3
				// Vendor-prefix box-sizing
				"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
				"position:relative;display:block;" +
				"margin:auto;border:1px;padding:1px;" +
				"top:1%;width:50%";
			div.innerHTML = "";
			documentElement.appendChild( container );
	
			var divStyle = window.getComputedStyle( div );
			pixelPositionVal = divStyle.top !== "1%";
			reliableMarginLeftVal = divStyle.marginLeft === "2px";
			boxSizingReliableVal = divStyle.width === "4px";
	
			// Support: Android 4.0 - 4.3 only
			// Some styles come back with percentage values, even though they shouldn't
			div.style.marginRight = "50%";
			pixelMarginRightVal = divStyle.marginRight === "4px";
	
			documentElement.removeChild( container );
		}
	
		jQuery.extend( support, {
			pixelPosition: function() {
	
				// This test is executed only once but we still do memoizing
				// since we can use the boxSizingReliable pre-computing.
				// No need to check if the test was already performed, though.
				computeStyleTests();
				return pixelPositionVal;
			},
			boxSizingReliable: function() {
				if ( boxSizingReliableVal == null ) {
					computeStyleTests();
				}
				return boxSizingReliableVal;
			},
			pixelMarginRight: function() {
	
				// Support: Android 4.0-4.3
				// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
				// since that compresses better and they're computed together anyway.
				if ( boxSizingReliableVal == null ) {
					computeStyleTests();
				}
				return pixelMarginRightVal;
			},
			reliableMarginLeft: function() {
	
				// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
				if ( boxSizingReliableVal == null ) {
					computeStyleTests();
				}
				return reliableMarginLeftVal;
			},
			reliableMarginRight: function() {
	
				// Support: Android 2.3
				// Check if div with explicit width and no margin-right incorrectly
				// gets computed margin-right based on width of container. (#3333)
				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
				// This support function is only executed once so no memoizing is needed.
				var ret,
					marginDiv = div.appendChild( document.createElement( "div" ) );
	
				// Reset CSS: box-sizing; display; margin; border; padding
				marginDiv.style.cssText = div.style.cssText =
	
					// Support: Android 2.3
					// Vendor-prefix box-sizing
					"-webkit-box-sizing:content-box;box-sizing:content-box;" +
					"display:block;margin:0;border:0;padding:0";
				marginDiv.style.marginRight = marginDiv.style.width = "0";
				div.style.width = "1px";
				documentElement.appendChild( container );
	
				ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
	
				documentElement.removeChild( container );
				div.removeChild( marginDiv );
	
				return ret;
			}
		} );
	} )();
	
	
	function curCSS( elem, name, computed ) {
		var width, minWidth, maxWidth, ret,
			style = elem.style;
	
		computed = computed || getStyles( elem );
		ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
	
		// Support: Opera 12.1x only
		// Fall back to style even without computed
		// computed is undefined for elems on document fragments
		if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
			ret = jQuery.style( elem, name );
		}
	
		// Support: IE9
		// getPropertyValue is only needed for .css('filter') (#12537)
		if ( computed ) {
	
			// A tribute to the "awesome hack by Dean Edwards"
			// Android Browser returns percentage for some values,
			// but width seems to be reliably pixels.
			// This is against the CSSOM draft spec:
			// http://dev.w3.org/csswg/cssom/#resolved-values
			if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
	
				// Remember the original values
				width = style.width;
				minWidth = style.minWidth;
				maxWidth = style.maxWidth;
	
				// Put in the new values to get a computed value out
				style.minWidth = style.maxWidth = style.width = ret;
				ret = computed.width;
	
				// Revert the changed values
				style.width = width;
				style.minWidth = minWidth;
				style.maxWidth = maxWidth;
			}
		}
	
		return ret !== undefined ?
	
			// Support: IE9-11+
			// IE returns zIndex value as an integer.
			ret + "" :
			ret;
	}
	
	
	function addGetHookIf( conditionFn, hookFn ) {
	
		// Define the hook, we'll check on the first run if it's really needed.
		return {
			get: function() {
				if ( conditionFn() ) {
	
					// Hook not needed (or it's not possible to use it due
					// to missing dependency), remove it.
					delete this.get;
					return;
				}
	
				// Hook needed; redefine it so that the support test is not executed again.
				return ( this.get = hookFn ).apply( this, arguments );
			}
		};
	}
	
	
	var
	
		// Swappable if display is none or starts with table
		// except "table", "table-cell", or "table-caption"
		// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
		rdisplayswap = /^(none|table(?!-c[ea]).+)/,
	
		cssShow = { position: "absolute", visibility: "hidden", display: "block" },
		cssNormalTransform = {
			letterSpacing: "0",
			fontWeight: "400"
		},
	
		cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
		emptyStyle = document.createElement( "div" ).style;
	
	// Return a css property mapped to a potentially vendor prefixed property
	function vendorPropName( name ) {
	
		// Shortcut for names that are not vendor prefixed
		if ( name in emptyStyle ) {
			return name;
		}
	
		// Check for vendor prefixed names
		var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
			i = cssPrefixes.length;
	
		while ( i-- ) {
			name = cssPrefixes[ i ] + capName;
			if ( name in emptyStyle ) {
				return name;
			}
		}
	}
	
	function setPositiveNumber( elem, value, subtract ) {
	
		// Any relative (+/-) values have already been
		// normalized at this point
		var matches = rcssNum.exec( value );
		return matches ?
	
			// Guard against undefined "subtract", e.g., when used as in cssHooks
			Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
			value;
	}
	
	function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
		var i = extra === ( isBorderBox ? "border" : "content" ) ?
	
			// If we already have the right measurement, avoid augmentation
			4 :
	
			// Otherwise initialize for horizontal or vertical properties
			name === "width" ? 1 : 0,
	
			val = 0;
	
		for ( ; i < 4; i += 2 ) {
	
			// Both box models exclude margin, so add it if we want it
			if ( extra === "margin" ) {
				val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
			}
	
			if ( isBorderBox ) {
	
				// border-box includes padding, so remove it if we want content
				if ( extra === "content" ) {
					val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
				}
	
				// At this point, extra isn't border nor margin, so remove border
				if ( extra !== "margin" ) {
					val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			} else {
	
				// At this point, extra isn't content, so add padding
				val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
	
				// At this point, extra isn't content nor padding, so add border
				if ( extra !== "padding" ) {
					val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			}
		}
	
		return val;
	}
	
	function getWidthOrHeight( elem, name, extra ) {
	
		// Start with offset property, which is equivalent to the border-box value
		var valueIsBorderBox = true,
			val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
			styles = getStyles( elem ),
			isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
	
		// Some non-html elements return undefined for offsetWidth, so check for null/undefined
		// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
		// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
		if ( val <= 0 || val == null ) {
	
			// Fall back to computed then uncomputed css if necessary
			val = curCSS( elem, name, styles );
			if ( val < 0 || val == null ) {
				val = elem.style[ name ];
			}
	
			// Computed unit is not pixels. Stop here and return.
			if ( rnumnonpx.test( val ) ) {
				return val;
			}
	
			// Check for style in case a browser which returns unreliable values
			// for getComputedStyle silently falls back to the reliable elem.style
			valueIsBorderBox = isBorderBox &&
				( support.boxSizingReliable() || val === elem.style[ name ] );
	
			// Normalize "", auto, and prepare for extra
			val = parseFloat( val ) || 0;
		}
	
		// Use the active box-sizing model to add/subtract irrelevant styles
		return ( val +
			augmentWidthOrHeight(
				elem,
				name,
				extra || ( isBorderBox ? "border" : "content" ),
				valueIsBorderBox,
				styles
			)
		) + "px";
	}
	
	function showHide( elements, show ) {
		var display, elem, hidden,
			values = [],
			index = 0,
			length = elements.length;
	
		for ( ; index < length; index++ ) {
			elem = elements[ index ];
			if ( !elem.style ) {
				continue;
			}
	
			values[ index ] = dataPriv.get( elem, "olddisplay" );
			display = elem.style.display;
			if ( show ) {
	
				// Reset the inline display of this element to learn if it is
				// being hidden by cascaded rules or not
				if ( !values[ index ] && display === "none" ) {
					elem.style.display = "";
				}
	
				// Set elements which have been overridden with display: none
				// in a stylesheet to whatever the default browser style is
				// for such an element
				if ( elem.style.display === "" && isHidden( elem ) ) {
					values[ index ] = dataPriv.access(
						elem,
						"olddisplay",
						defaultDisplay( elem.nodeName )
					);
				}
			} else {
				hidden = isHidden( elem );
	
				if ( display !== "none" || !hidden ) {
					dataPriv.set(
						elem,
						"olddisplay",
						hidden ? display : jQuery.css( elem, "display" )
					);
				}
			}
		}
	
		// Set the display of most of the elements in a second loop
		// to avoid the constant reflow
		for ( index = 0; index < length; index++ ) {
			elem = elements[ index ];
			if ( !elem.style ) {
				continue;
			}
			if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
				elem.style.display = show ? values[ index ] || "" : "none";
			}
		}
	
		return elements;
	}
	
	jQuery.extend( {
	
		// Add in style property hooks for overriding the default
		// behavior of getting and setting a style property
		cssHooks: {
			opacity: {
				get: function( elem, computed ) {
					if ( computed ) {
	
						// We should always get a number back from opacity
						var ret = curCSS( elem, "opacity" );
						return ret === "" ? "1" : ret;
					}
				}
			}
		},
	
		// Don't automatically add "px" to these possibly-unitless properties
		cssNumber: {
			"animationIterationCount": true,
			"columnCount": true,
			"fillOpacity": true,
			"flexGrow": true,
			"flexShrink": true,
			"fontWeight": true,
			"lineHeight": true,
			"opacity": true,
			"order": true,
			"orphans": true,
			"widows": true,
			"zIndex": true,
			"zoom": true
		},
	
		// Add in properties whose names you wish to fix before
		// setting or getting the value
		cssProps: {
			"float": "cssFloat"
		},
	
		// Get and set the style property on a DOM Node
		style: function( elem, name, value, extra ) {
	
			// Don't set styles on text and comment nodes
			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
				return;
			}
	
			// Make sure that we're working with the right name
			var ret, type, hooks,
				origName = jQuery.camelCase( name ),
				style = elem.style;
	
			name = jQuery.cssProps[ origName ] ||
				( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
	
			// Gets hook for the prefixed version, then unprefixed version
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// Check if we're setting a value
			if ( value !== undefined ) {
				type = typeof value;
	
				// Convert "+=" or "-=" to relative numbers (#7345)
				if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
					value = adjustCSS( elem, name, ret );
	
					// Fixes bug #9237
					type = "number";
				}
	
				// Make sure that null and NaN values aren't set (#7116)
				if ( value == null || value !== value ) {
					return;
				}
	
				// If a number was passed in, add the unit (except for certain CSS properties)
				if ( type === "number" ) {
					value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
				}
	
				// Support: IE9-11+
				// background-* props affect original clone's values
				if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
					style[ name ] = "inherit";
				}
	
				// If a hook was provided, use that value, otherwise just set the specified value
				if ( !hooks || !( "set" in hooks ) ||
					( value = hooks.set( elem, value, extra ) ) !== undefined ) {
	
					style[ name ] = value;
				}
	
			} else {
	
				// If a hook was provided get the non-computed value from there
				if ( hooks && "get" in hooks &&
					( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
	
					return ret;
				}
	
				// Otherwise just get the value from the style object
				return style[ name ];
			}
		},
	
		css: function( elem, name, extra, styles ) {
			var val, num, hooks,
				origName = jQuery.camelCase( name );
	
			// Make sure that we're working with the right name
			name = jQuery.cssProps[ origName ] ||
				( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
	
			// Try prefixed name followed by the unprefixed name
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// If a hook was provided get the computed value from there
			if ( hooks && "get" in hooks ) {
				val = hooks.get( elem, true, extra );
			}
	
			// Otherwise, if a way to get the computed value exists, use that
			if ( val === undefined ) {
				val = curCSS( elem, name, styles );
			}
	
			// Convert "normal" to computed value
			if ( val === "normal" && name in cssNormalTransform ) {
				val = cssNormalTransform[ name ];
			}
	
			// Make numeric if forced or a qualifier was provided and val looks numeric
			if ( extra === "" || extra ) {
				num = parseFloat( val );
				return extra === true || isFinite( num ) ? num || 0 : val;
			}
			return val;
		}
	} );
	
	jQuery.each( [ "height", "width" ], function( i, name ) {
		jQuery.cssHooks[ name ] = {
			get: function( elem, computed, extra ) {
				if ( computed ) {
	
					// Certain elements can have dimension info if we invisibly show them
					// but it must have a current display style that would benefit
					return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
						elem.offsetWidth === 0 ?
							swap( elem, cssShow, function() {
								return getWidthOrHeight( elem, name, extra );
							} ) :
							getWidthOrHeight( elem, name, extra );
				}
			},
	
			set: function( elem, value, extra ) {
				var matches,
					styles = extra && getStyles( elem ),
					subtract = extra && augmentWidthOrHeight(
						elem,
						name,
						extra,
						jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
						styles
					);
	
				// Convert to pixels if value adjustment is needed
				if ( subtract && ( matches = rcssNum.exec( value ) ) &&
					( matches[ 3 ] || "px" ) !== "px" ) {
	
					elem.style[ name ] = value;
					value = jQuery.css( elem, name );
				}
	
				return setPositiveNumber( elem, value, subtract );
			}
		};
	} );
	
	jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
		function( elem, computed ) {
			if ( computed ) {
				return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
					elem.getBoundingClientRect().left -
						swap( elem, { marginLeft: 0 }, function() {
							return elem.getBoundingClientRect().left;
						} )
					) + "px";
			}
		}
	);
	
	// Support: Android 2.3
	jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
		function( elem, computed ) {
			if ( computed ) {
				return swap( elem, { "display": "inline-block" },
					curCSS, [ elem, "marginRight" ] );
			}
		}
	);
	
	// These hooks are used by animate to expand properties
	jQuery.each( {
		margin: "",
		padding: "",
		border: "Width"
	}, function( prefix, suffix ) {
		jQuery.cssHooks[ prefix + suffix ] = {
			expand: function( value ) {
				var i = 0,
					expanded = {},
	
					// Assumes a single number if not a string
					parts = typeof value === "string" ? value.split( " " ) : [ value ];
	
				for ( ; i < 4; i++ ) {
					expanded[ prefix + cssExpand[ i ] + suffix ] =
						parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
				}
	
				return expanded;
			}
		};
	
		if ( !rmargin.test( prefix ) ) {
			jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
		}
	} );
	
	jQuery.fn.extend( {
		css: function( name, value ) {
			return access( this, function( elem, name, value ) {
				var styles, len,
					map = {},
					i = 0;
	
				if ( jQuery.isArray( name ) ) {
					styles = getStyles( elem );
					len = name.length;
	
					for ( ; i < len; i++ ) {
						map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
					}
	
					return map;
				}
	
				return value !== undefined ?
					jQuery.style( elem, name, value ) :
					jQuery.css( elem, name );
			}, name, value, arguments.length > 1 );
		},
		show: function() {
			return showHide( this, true );
		},
		hide: function() {
			return showHide( this );
		},
		toggle: function( state ) {
			if ( typeof state === "boolean" ) {
				return state ? this.show() : this.hide();
			}
	
			return this.each( function() {
				if ( isHidden( this ) ) {
					jQuery( this ).show();
				} else {
					jQuery( this ).hide();
				}
			} );
		}
	} );
	
	
	function Tween( elem, options, prop, end, easing ) {
		return new Tween.prototype.init( elem, options, prop, end, easing );
	}
	jQuery.Tween = Tween;
	
	Tween.prototype = {
		constructor: Tween,
		init: function( elem, options, prop, end, easing, unit ) {
			this.elem = elem;
			this.prop = prop;
			this.easing = easing || jQuery.easing._default;
			this.options = options;
			this.start = this.now = this.cur();
			this.end = end;
			this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
		},
		cur: function() {
			var hooks = Tween.propHooks[ this.prop ];
	
			return hooks && hooks.get ?
				hooks.get( this ) :
				Tween.propHooks._default.get( this );
		},
		run: function( percent ) {
			var eased,
				hooks = Tween.propHooks[ this.prop ];
	
			if ( this.options.duration ) {
				this.pos = eased = jQuery.easing[ this.easing ](
					percent, this.options.duration * percent, 0, 1, this.options.duration
				);
			} else {
				this.pos = eased = percent;
			}
			this.now = ( this.end - this.start ) * eased + this.start;
	
			if ( this.options.step ) {
				this.options.step.call( this.elem, this.now, this );
			}
	
			if ( hooks && hooks.set ) {
				hooks.set( this );
			} else {
				Tween.propHooks._default.set( this );
			}
			return this;
		}
	};
	
	Tween.prototype.init.prototype = Tween.prototype;
	
	Tween.propHooks = {
		_default: {
			get: function( tween ) {
				var result;
	
				// Use a property on the element directly when it is not a DOM element,
				// or when there is no matching style property that exists.
				if ( tween.elem.nodeType !== 1 ||
					tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
					return tween.elem[ tween.prop ];
				}
	
				// Passing an empty string as a 3rd parameter to .css will automatically
				// attempt a parseFloat and fallback to a string if the parse fails.
				// Simple values such as "10px" are parsed to Float;
				// complex values such as "rotate(1rad)" are returned as-is.
				result = jQuery.css( tween.elem, tween.prop, "" );
	
				// Empty strings, null, undefined and "auto" are converted to 0.
				return !result || result === "auto" ? 0 : result;
			},
			set: function( tween ) {
	
				// Use step hook for back compat.
				// Use cssHook if its there.
				// Use .style if available and use plain properties where available.
				if ( jQuery.fx.step[ tween.prop ] ) {
					jQuery.fx.step[ tween.prop ]( tween );
				} else if ( tween.elem.nodeType === 1 &&
					( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
						jQuery.cssHooks[ tween.prop ] ) ) {
					jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
				} else {
					tween.elem[ tween.prop ] = tween.now;
				}
			}
		}
	};
	
	// Support: IE9
	// Panic based approach to setting things on disconnected nodes
	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
		set: function( tween ) {
			if ( tween.elem.nodeType && tween.elem.parentNode ) {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	};
	
	jQuery.easing = {
		linear: function( p ) {
			return p;
		},
		swing: function( p ) {
			return 0.5 - Math.cos( p * Math.PI ) / 2;
		},
		_default: "swing"
	};
	
	jQuery.fx = Tween.prototype.init;
	
	// Back Compat <1.8 extension point
	jQuery.fx.step = {};
	
	
	
	
	var
		fxNow, timerId,
		rfxtypes = /^(?:toggle|show|hide)$/,
		rrun = /queueHooks$/;
	
	// Animations created synchronously will run synchronously
	function createFxNow() {
		window.setTimeout( function() {
			fxNow = undefined;
		} );
		return ( fxNow = jQuery.now() );
	}
	
	// Generate parameters to create a standard animation
	function genFx( type, includeWidth ) {
		var which,
			i = 0,
			attrs = { height: type };
	
		// If we include width, step value is 1 to do all cssExpand values,
		// otherwise step value is 2 to skip over Left and Right
		includeWidth = includeWidth ? 1 : 0;
		for ( ; i < 4 ; i += 2 - includeWidth ) {
			which = cssExpand[ i ];
			attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
		}
	
		if ( includeWidth ) {
			attrs.opacity = attrs.width = type;
		}
	
		return attrs;
	}
	
	function createTween( value, prop, animation ) {
		var tween,
			collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
			index = 0,
			length = collection.length;
		for ( ; index < length; index++ ) {
			if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
	
				// We're done with this property
				return tween;
			}
		}
	}
	
	function defaultPrefilter( elem, props, opts ) {
		/* jshint validthis: true */
		var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
			anim = this,
			orig = {},
			style = elem.style,
			hidden = elem.nodeType && isHidden( elem ),
			dataShow = dataPriv.get( elem, "fxshow" );
	
		// Handle queue: false promises
		if ( !opts.queue ) {
			hooks = jQuery._queueHooks( elem, "fx" );
			if ( hooks.unqueued == null ) {
				hooks.unqueued = 0;
				oldfire = hooks.empty.fire;
				hooks.empty.fire = function() {
					if ( !hooks.unqueued ) {
						oldfire();
					}
				};
			}
			hooks.unqueued++;
	
			anim.always( function() {
	
				// Ensure the complete handler is called before this completes
				anim.always( function() {
					hooks.unqueued--;
					if ( !jQuery.queue( elem, "fx" ).length ) {
						hooks.empty.fire();
					}
				} );
			} );
		}
	
		// Height/width overflow pass
		if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
	
			// Make sure that nothing sneaks out
			// Record all 3 overflow attributes because IE9-10 do not
			// change the overflow attribute when overflowX and
			// overflowY are set to the same value
			opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
	
			// Set display property to inline-block for height/width
			// animations on inline elements that are having width/height animated
			display = jQuery.css( elem, "display" );
	
			// Test default display if display is currently "none"
			checkDisplay = display === "none" ?
				dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
	
			if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
				style.display = "inline-block";
			}
		}
	
		if ( opts.overflow ) {
			style.overflow = "hidden";
			anim.always( function() {
				style.overflow = opts.overflow[ 0 ];
				style.overflowX = opts.overflow[ 1 ];
				style.overflowY = opts.overflow[ 2 ];
			} );
		}
	
		// show/hide pass
		for ( prop in props ) {
			value = props[ prop ];
			if ( rfxtypes.exec( value ) ) {
				delete props[ prop ];
				toggle = toggle || value === "toggle";
				if ( value === ( hidden ? "hide" : "show" ) ) {
	
					// If there is dataShow left over from a stopped hide or show
					// and we are going to proceed with show, we should pretend to be hidden
					if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
						hidden = true;
					} else {
						continue;
					}
				}
				orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
	
			// Any non-fx value stops us from restoring the original display value
			} else {
				display = undefined;
			}
		}
	
		if ( !jQuery.isEmptyObject( orig ) ) {
			if ( dataShow ) {
				if ( "hidden" in dataShow ) {
					hidden = dataShow.hidden;
				}
			} else {
				dataShow = dataPriv.access( elem, "fxshow", {} );
			}
	
			// Store state if its toggle - enables .stop().toggle() to "reverse"
			if ( toggle ) {
				dataShow.hidden = !hidden;
			}
			if ( hidden ) {
				jQuery( elem ).show();
			} else {
				anim.done( function() {
					jQuery( elem ).hide();
				} );
			}
			anim.done( function() {
				var prop;
	
				dataPriv.remove( elem, "fxshow" );
				for ( prop in orig ) {
					jQuery.style( elem, prop, orig[ prop ] );
				}
			} );
			for ( prop in orig ) {
				tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
	
				if ( !( prop in dataShow ) ) {
					dataShow[ prop ] = tween.start;
					if ( hidden ) {
						tween.end = tween.start;
						tween.start = prop === "width" || prop === "height" ? 1 : 0;
					}
				}
			}
	
		// If this is a noop like .hide().hide(), restore an overwritten display value
		} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
			style.display = display;
		}
	}
	
	function propFilter( props, specialEasing ) {
		var index, name, easing, value, hooks;
	
		// camelCase, specialEasing and expand cssHook pass
		for ( index in props ) {
			name = jQuery.camelCase( index );
			easing = specialEasing[ name ];
			value = props[ index ];
			if ( jQuery.isArray( value ) ) {
				easing = value[ 1 ];
				value = props[ index ] = value[ 0 ];
			}
	
			if ( index !== name ) {
				props[ name ] = value;
				delete props[ index ];
			}
	
			hooks = jQuery.cssHooks[ name ];
			if ( hooks && "expand" in hooks ) {
				value = hooks.expand( value );
				delete props[ name ];
	
				// Not quite $.extend, this won't overwrite existing keys.
				// Reusing 'index' because we have the correct "name"
				for ( index in value ) {
					if ( !( index in props ) ) {
						props[ index ] = value[ index ];
						specialEasing[ index ] = easing;
					}
				}
			} else {
				specialEasing[ name ] = easing;
			}
		}
	}
	
	function Animation( elem, properties, options ) {
		var result,
			stopped,
			index = 0,
			length = Animation.prefilters.length,
			deferred = jQuery.Deferred().always( function() {
	
				// Don't match elem in the :animated selector
				delete tick.elem;
			} ),
			tick = function() {
				if ( stopped ) {
					return false;
				}
				var currentTime = fxNow || createFxNow(),
					remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
	
					// Support: Android 2.3
					// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
					temp = remaining / animation.duration || 0,
					percent = 1 - temp,
					index = 0,
					length = animation.tweens.length;
	
				for ( ; index < length ; index++ ) {
					animation.tweens[ index ].run( percent );
				}
	
				deferred.notifyWith( elem, [ animation, percent, remaining ] );
	
				if ( percent < 1 && length ) {
					return remaining;
				} else {
					deferred.resolveWith( elem, [ animation ] );
					return false;
				}
			},
			animation = deferred.promise( {
				elem: elem,
				props: jQuery.extend( {}, properties ),
				opts: jQuery.extend( true, {
					specialEasing: {},
					easing: jQuery.easing._default
				}, options ),
				originalProperties: properties,
				originalOptions: options,
				startTime: fxNow || createFxNow(),
				duration: options.duration,
				tweens: [],
				createTween: function( prop, end ) {
					var tween = jQuery.Tween( elem, animation.opts, prop, end,
							animation.opts.specialEasing[ prop ] || animation.opts.easing );
					animation.tweens.push( tween );
					return tween;
				},
				stop: function( gotoEnd ) {
					var index = 0,
	
						// If we are going to the end, we want to run all the tweens
						// otherwise we skip this part
						length = gotoEnd ? animation.tweens.length : 0;
					if ( stopped ) {
						return this;
					}
					stopped = true;
					for ( ; index < length ; index++ ) {
						animation.tweens[ index ].run( 1 );
					}
	
					// Resolve when we played the last frame; otherwise, reject
					if ( gotoEnd ) {
						deferred.notifyWith( elem, [ animation, 1, 0 ] );
						deferred.resolveWith( elem, [ animation, gotoEnd ] );
					} else {
						deferred.rejectWith( elem, [ animation, gotoEnd ] );
					}
					return this;
				}
			} ),
			props = animation.props;
	
		propFilter( props, animation.opts.specialEasing );
	
		for ( ; index < length ; index++ ) {
			result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
			if ( result ) {
				if ( jQuery.isFunction( result.stop ) ) {
					jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
						jQuery.proxy( result.stop, result );
				}
				return result;
			}
		}
	
		jQuery.map( props, createTween, animation );
	
		if ( jQuery.isFunction( animation.opts.start ) ) {
			animation.opts.start.call( elem, animation );
		}
	
		jQuery.fx.timer(
			jQuery.extend( tick, {
				elem: elem,
				anim: animation,
				queue: animation.opts.queue
			} )
		);
	
		// attach callbacks from options
		return animation.progress( animation.opts.progress )
			.done( animation.opts.done, animation.opts.complete )
			.fail( animation.opts.fail )
			.always( animation.opts.always );
	}
	
	jQuery.Animation = jQuery.extend( Animation, {
		tweeners: {
			"*": [ function( prop, value ) {
				var tween = this.createTween( prop, value );
				adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
				return tween;
			} ]
		},
	
		tweener: function( props, callback ) {
			if ( jQuery.isFunction( props ) ) {
				callback = props;
				props = [ "*" ];
			} else {
				props = props.match( rnotwhite );
			}
	
			var prop,
				index = 0,
				length = props.length;
	
			for ( ; index < length ; index++ ) {
				prop = props[ index ];
				Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
				Animation.tweeners[ prop ].unshift( callback );
			}
		},
	
		prefilters: [ defaultPrefilter ],
	
		prefilter: function( callback, prepend ) {
			if ( prepend ) {
				Animation.prefilters.unshift( callback );
			} else {
				Animation.prefilters.push( callback );
			}
		}
	} );
	
	jQuery.speed = function( speed, easing, fn ) {
		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
			complete: fn || !fn && easing ||
				jQuery.isFunction( speed ) && speed,
			duration: speed,
			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
		};
	
		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
			opt.duration : opt.duration in jQuery.fx.speeds ?
				jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
	
		// Normalize opt.queue - true/undefined/null -> "fx"
		if ( opt.queue == null || opt.queue === true ) {
			opt.queue = "fx";
		}
	
		// Queueing
		opt.old = opt.complete;
	
		opt.complete = function() {
			if ( jQuery.isFunction( opt.old ) ) {
				opt.old.call( this );
			}
	
			if ( opt.queue ) {
				jQuery.dequeue( this, opt.queue );
			}
		};
	
		return opt;
	};
	
	jQuery.fn.extend( {
		fadeTo: function( speed, to, easing, callback ) {
	
			// Show any hidden elements after setting opacity to 0
			return this.filter( isHidden ).css( "opacity", 0 ).show()
	
				// Animate to the value specified
				.end().animate( { opacity: to }, speed, easing, callback );
		},
		animate: function( prop, speed, easing, callback ) {
			var empty = jQuery.isEmptyObject( prop ),
				optall = jQuery.speed( speed, easing, callback ),
				doAnimation = function() {
	
					// Operate on a copy of prop so per-property easing won't be lost
					var anim = Animation( this, jQuery.extend( {}, prop ), optall );
	
					// Empty animations, or finishing resolves immediately
					if ( empty || dataPriv.get( this, "finish" ) ) {
						anim.stop( true );
					}
				};
				doAnimation.finish = doAnimation;
	
			return empty || optall.queue === false ?
				this.each( doAnimation ) :
				this.queue( optall.queue, doAnimation );
		},
		stop: function( type, clearQueue, gotoEnd ) {
			var stopQueue = function( hooks ) {
				var stop = hooks.stop;
				delete hooks.stop;
				stop( gotoEnd );
			};
	
			if ( typeof type !== "string" ) {
				gotoEnd = clearQueue;
				clearQueue = type;
				type = undefined;
			}
			if ( clearQueue && type !== false ) {
				this.queue( type || "fx", [] );
			}
	
			return this.each( function() {
				var dequeue = true,
					index = type != null && type + "queueHooks",
					timers = jQuery.timers,
					data = dataPriv.get( this );
	
				if ( index ) {
					if ( data[ index ] && data[ index ].stop ) {
						stopQueue( data[ index ] );
					}
				} else {
					for ( index in data ) {
						if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
							stopQueue( data[ index ] );
						}
					}
				}
	
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this &&
						( type == null || timers[ index ].queue === type ) ) {
	
						timers[ index ].anim.stop( gotoEnd );
						dequeue = false;
						timers.splice( index, 1 );
					}
				}
	
				// Start the next in the queue if the last step wasn't forced.
				// Timers currently will call their complete callbacks, which
				// will dequeue but only if they were gotoEnd.
				if ( dequeue || !gotoEnd ) {
					jQuery.dequeue( this, type );
				}
			} );
		},
		finish: function( type ) {
			if ( type !== false ) {
				type = type || "fx";
			}
			return this.each( function() {
				var index,
					data = dataPriv.get( this ),
					queue = data[ type + "queue" ],
					hooks = data[ type + "queueHooks" ],
					timers = jQuery.timers,
					length = queue ? queue.length : 0;
	
				// Enable finishing flag on private data
				data.finish = true;
	
				// Empty the queue first
				jQuery.queue( this, type, [] );
	
				if ( hooks && hooks.stop ) {
					hooks.stop.call( this, true );
				}
	
				// Look for any active animations, and finish them
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
						timers[ index ].anim.stop( true );
						timers.splice( index, 1 );
					}
				}
	
				// Look for any animations in the old queue and finish them
				for ( index = 0; index < length; index++ ) {
					if ( queue[ index ] && queue[ index ].finish ) {
						queue[ index ].finish.call( this );
					}
				}
	
				// Turn off finishing flag
				delete data.finish;
			} );
		}
	} );
	
	jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
		var cssFn = jQuery.fn[ name ];
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return speed == null || typeof speed === "boolean" ?
				cssFn.apply( this, arguments ) :
				this.animate( genFx( name, true ), speed, easing, callback );
		};
	} );
	
	// Generate shortcuts for custom animations
	jQuery.each( {
		slideDown: genFx( "show" ),
		slideUp: genFx( "hide" ),
		slideToggle: genFx( "toggle" ),
		fadeIn: { opacity: "show" },
		fadeOut: { opacity: "hide" },
		fadeToggle: { opacity: "toggle" }
	}, function( name, props ) {
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return this.animate( props, speed, easing, callback );
		};
	} );
	
	jQuery.timers = [];
	jQuery.fx.tick = function() {
		var timer,
			i = 0,
			timers = jQuery.timers;
	
		fxNow = jQuery.now();
	
		for ( ; i < timers.length; i++ ) {
			timer = timers[ i ];
	
			// Checks the timer has not already been removed
			if ( !timer() && timers[ i ] === timer ) {
				timers.splice( i--, 1 );
			}
		}
	
		if ( !timers.length ) {
			jQuery.fx.stop();
		}
		fxNow = undefined;
	};
	
	jQuery.fx.timer = function( timer ) {
		jQuery.timers.push( timer );
		if ( timer() ) {
			jQuery.fx.start();
		} else {
			jQuery.timers.pop();
		}
	};
	
	jQuery.fx.interval = 13;
	jQuery.fx.start = function() {
		if ( !timerId ) {
			timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
		}
	};
	
	jQuery.fx.stop = function() {
		window.clearInterval( timerId );
	
		timerId = null;
	};
	
	jQuery.fx.speeds = {
		slow: 600,
		fast: 200,
	
		// Default speed
		_default: 400
	};
	
	
	// Based off of the plugin by Clint Helfers, with permission.
	// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
	jQuery.fn.delay = function( time, type ) {
		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
		type = type || "fx";
	
		return this.queue( type, function( next, hooks ) {
			var timeout = window.setTimeout( next, time );
			hooks.stop = function() {
				window.clearTimeout( timeout );
			};
		} );
	};
	
	
	( function() {
		var input = document.createElement( "input" ),
			select = document.createElement( "select" ),
			opt = select.appendChild( document.createElement( "option" ) );
	
		input.type = "checkbox";
	
		// Support: iOS<=5.1, Android<=4.2+
		// Default value for a checkbox should be "on"
		support.checkOn = input.value !== "";
	
		// Support: IE<=11+
		// Must access selectedIndex to make default options select
		support.optSelected = opt.selected;
	
		// Support: Android<=2.3
		// Options inside disabled selects are incorrectly marked as disabled
		select.disabled = true;
		support.optDisabled = !opt.disabled;
	
		// Support: IE<=11+
		// An input loses its value after becoming a radio
		input = document.createElement( "input" );
		input.value = "t";
		input.type = "radio";
		support.radioValue = input.value === "t";
	} )();
	
	
	var boolHook,
		attrHandle = jQuery.expr.attrHandle;
	
	jQuery.fn.extend( {
		attr: function( name, value ) {
			return access( this, jQuery.attr, name, value, arguments.length > 1 );
		},
	
		removeAttr: function( name ) {
			return this.each( function() {
				jQuery.removeAttr( this, name );
			} );
		}
	} );
	
	jQuery.extend( {
		attr: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set attributes on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			// Fallback to prop when attributes are not supported
			if ( typeof elem.getAttribute === "undefined" ) {
				return jQuery.prop( elem, name, value );
			}
	
			// All attributes are lowercase
			// Grab necessary hook if one is defined
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
				name = name.toLowerCase();
				hooks = jQuery.attrHooks[ name ] ||
					( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
			}
	
			if ( value !== undefined ) {
				if ( value === null ) {
					jQuery.removeAttr( elem, name );
					return;
				}
	
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				elem.setAttribute( name, value + "" );
				return value;
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			ret = jQuery.find.attr( elem, name );
	
			// Non-existent attributes return null, we normalize to undefined
			return ret == null ? undefined : ret;
		},
	
		attrHooks: {
			type: {
				set: function( elem, value ) {
					if ( !support.radioValue && value === "radio" &&
						jQuery.nodeName( elem, "input" ) ) {
						var val = elem.value;
						elem.setAttribute( "type", value );
						if ( val ) {
							elem.value = val;
						}
						return value;
					}
				}
			}
		},
	
		removeAttr: function( elem, value ) {
			var name, propName,
				i = 0,
				attrNames = value && value.match( rnotwhite );
	
			if ( attrNames && elem.nodeType === 1 ) {
				while ( ( name = attrNames[ i++ ] ) ) {
					propName = jQuery.propFix[ name ] || name;
	
					// Boolean attributes get special treatment (#10870)
					if ( jQuery.expr.match.bool.test( name ) ) {
	
						// Set corresponding property to false
						elem[ propName ] = false;
					}
	
					elem.removeAttribute( name );
				}
			}
		}
	} );
	
	// Hooks for boolean attributes
	boolHook = {
		set: function( elem, value, name ) {
			if ( value === false ) {
	
				// Remove boolean attributes when set to false
				jQuery.removeAttr( elem, name );
			} else {
				elem.setAttribute( name, name );
			}
			return name;
		}
	};
	jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
		var getter = attrHandle[ name ] || jQuery.find.attr;
	
		attrHandle[ name ] = function( elem, name, isXML ) {
			var ret, handle;
			if ( !isXML ) {
	
				// Avoid an infinite loop by temporarily removing this function from the getter
				handle = attrHandle[ name ];
				attrHandle[ name ] = ret;
				ret = getter( elem, name, isXML ) != null ?
					name.toLowerCase() :
					null;
				attrHandle[ name ] = handle;
			}
			return ret;
		};
	} );
	
	
	
	
	var rfocusable = /^(?:input|select|textarea|button)$/i,
		rclickable = /^(?:a|area)$/i;
	
	jQuery.fn.extend( {
		prop: function( name, value ) {
			return access( this, jQuery.prop, name, value, arguments.length > 1 );
		},
	
		removeProp: function( name ) {
			return this.each( function() {
				delete this[ jQuery.propFix[ name ] || name ];
			} );
		}
	} );
	
	jQuery.extend( {
		prop: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set properties on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
	
				// Fix name and attach hooks
				name = jQuery.propFix[ name ] || name;
				hooks = jQuery.propHooks[ name ];
			}
	
			if ( value !== undefined ) {
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				return ( elem[ name ] = value );
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			return elem[ name ];
		},
	
		propHooks: {
			tabIndex: {
				get: function( elem ) {
	
					// elem.tabIndex doesn't always return the
					// correct value when it hasn't been explicitly set
					// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
					// Use proper attribute retrieval(#12072)
					var tabindex = jQuery.find.attr( elem, "tabindex" );
	
					return tabindex ?
						parseInt( tabindex, 10 ) :
						rfocusable.test( elem.nodeName ) ||
							rclickable.test( elem.nodeName ) && elem.href ?
								0 :
								-1;
				}
			}
		},
	
		propFix: {
			"for": "htmlFor",
			"class": "className"
		}
	} );
	
	// Support: IE <=11 only
	// Accessing the selectedIndex property
	// forces the browser to respect setting selected
	// on the option
	// The getter ensures a default option is selected
	// when in an optgroup
	if ( !support.optSelected ) {
		jQuery.propHooks.selected = {
			get: function( elem ) {
				var parent = elem.parentNode;
				if ( parent && parent.parentNode ) {
					parent.parentNode.selectedIndex;
				}
				return null;
			},
			set: function( elem ) {
				var parent = elem.parentNode;
				if ( parent ) {
					parent.selectedIndex;
	
					if ( parent.parentNode ) {
						parent.parentNode.selectedIndex;
					}
				}
			}
		};
	}
	
	jQuery.each( [
		"tabIndex",
		"readOnly",
		"maxLength",
		"cellSpacing",
		"cellPadding",
		"rowSpan",
		"colSpan",
		"useMap",
		"frameBorder",
		"contentEditable"
	], function() {
		jQuery.propFix[ this.toLowerCase() ] = this;
	} );
	
	
	
	
	var rclass = /[\t\r\n\f]/g;
	
	function getClass( elem ) {
		return elem.getAttribute && elem.getAttribute( "class" ) || "";
	}
	
	jQuery.fn.extend( {
		addClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnotwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
					cur = elem.nodeType === 1 &&
						( " " + curValue + " " ).replace( rclass, " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
							if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
								cur += clazz + " ";
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = jQuery.trim( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		removeClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( !arguments.length ) {
				return this.attr( "class", "" );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnotwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
	
					// This expression is here for better compressibility (see addClass)
					cur = elem.nodeType === 1 &&
						( " " + curValue + " " ).replace( rclass, " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
	
							// Remove *all* instances
							while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
								cur = cur.replace( " " + clazz + " ", " " );
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = jQuery.trim( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		toggleClass: function( value, stateVal ) {
			var type = typeof value;
	
			if ( typeof stateVal === "boolean" && type === "string" ) {
				return stateVal ? this.addClass( value ) : this.removeClass( value );
			}
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( i ) {
					jQuery( this ).toggleClass(
						value.call( this, i, getClass( this ), stateVal ),
						stateVal
					);
				} );
			}
	
			return this.each( function() {
				var className, i, self, classNames;
	
				if ( type === "string" ) {
	
					// Toggle individual class names
					i = 0;
					self = jQuery( this );
					classNames = value.match( rnotwhite ) || [];
	
					while ( ( className = classNames[ i++ ] ) ) {
	
						// Check each className given, space separated list
						if ( self.hasClass( className ) ) {
							self.removeClass( className );
						} else {
							self.addClass( className );
						}
					}
	
				// Toggle whole class name
				} else if ( value === undefined || type === "boolean" ) {
					className = getClass( this );
					if ( className ) {
	
						// Store className if set
						dataPriv.set( this, "__className__", className );
					}
	
					// If the element has a class name or if we're passed `false`,
					// then remove the whole classname (if there was one, the above saved it).
					// Otherwise bring back whatever was previously saved (if anything),
					// falling back to the empty string if nothing was stored.
					if ( this.setAttribute ) {
						this.setAttribute( "class",
							className || value === false ?
							"" :
							dataPriv.get( this, "__className__" ) || ""
						);
					}
				}
			} );
		},
	
		hasClass: function( selector ) {
			var className, elem,
				i = 0;
	
			className = " " + selector + " ";
			while ( ( elem = this[ i++ ] ) ) {
				if ( elem.nodeType === 1 &&
					( " " + getClass( elem ) + " " ).replace( rclass, " " )
						.indexOf( className ) > -1
				) {
					return true;
				}
			}
	
			return false;
		}
	} );
	
	
	
	
	var rreturn = /\r/g,
		rspaces = /[\x20\t\r\n\f]+/g;
	
	jQuery.fn.extend( {
		val: function( value ) {
			var hooks, ret, isFunction,
				elem = this[ 0 ];
	
			if ( !arguments.length ) {
				if ( elem ) {
					hooks = jQuery.valHooks[ elem.type ] ||
						jQuery.valHooks[ elem.nodeName.toLowerCase() ];
	
					if ( hooks &&
						"get" in hooks &&
						( ret = hooks.get( elem, "value" ) ) !== undefined
					) {
						return ret;
					}
	
					ret = elem.value;
	
					return typeof ret === "string" ?
	
						// Handle most common string cases
						ret.replace( rreturn, "" ) :
	
						// Handle cases where value is null/undef or number
						ret == null ? "" : ret;
				}
	
				return;
			}
	
			isFunction = jQuery.isFunction( value );
	
			return this.each( function( i ) {
				var val;
	
				if ( this.nodeType !== 1 ) {
					return;
				}
	
				if ( isFunction ) {
					val = value.call( this, i, jQuery( this ).val() );
				} else {
					val = value;
				}
	
				// Treat null/undefined as ""; convert numbers to string
				if ( val == null ) {
					val = "";
	
				} else if ( typeof val === "number" ) {
					val += "";
	
				} else if ( jQuery.isArray( val ) ) {
					val = jQuery.map( val, function( value ) {
						return value == null ? "" : value + "";
					} );
				}
	
				hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
	
				// If set returns undefined, fall back to normal setting
				if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
					this.value = val;
				}
			} );
		}
	} );
	
	jQuery.extend( {
		valHooks: {
			option: {
				get: function( elem ) {
	
					var val = jQuery.find.attr( elem, "value" );
					return val != null ?
						val :
	
						// Support: IE10-11+
						// option.text throws exceptions (#14686, #14858)
						// Strip and collapse whitespace
						// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
						jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
				}
			},
			select: {
				get: function( elem ) {
					var value, option,
						options = elem.options,
						index = elem.selectedIndex,
						one = elem.type === "select-one" || index < 0,
						values = one ? null : [],
						max = one ? index + 1 : options.length,
						i = index < 0 ?
							max :
							one ? index : 0;
	
					// Loop through all the selected options
					for ( ; i < max; i++ ) {
						option = options[ i ];
	
						// IE8-9 doesn't update selected after form reset (#2551)
						if ( ( option.selected || i === index ) &&
	
								// Don't return options that are disabled or in a disabled optgroup
								( support.optDisabled ?
									!option.disabled : option.getAttribute( "disabled" ) === null ) &&
								( !option.parentNode.disabled ||
									!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
	
							// Get the specific value for the option
							value = jQuery( option ).val();
	
							// We don't need an array for one selects
							if ( one ) {
								return value;
							}
	
							// Multi-Selects return an array
							values.push( value );
						}
					}
	
					return values;
				},
	
				set: function( elem, value ) {
					var optionSet, option,
						options = elem.options,
						values = jQuery.makeArray( value ),
						i = options.length;
	
					while ( i-- ) {
						option = options[ i ];
						if ( option.selected =
							jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
						) {
							optionSet = true;
						}
					}
	
					// Force browsers to behave consistently when non-matching value is set
					if ( !optionSet ) {
						elem.selectedIndex = -1;
					}
					return values;
				}
			}
		}
	} );
	
	// Radios and checkboxes getter/setter
	jQuery.each( [ "radio", "checkbox" ], function() {
		jQuery.valHooks[ this ] = {
			set: function( elem, value ) {
				if ( jQuery.isArray( value ) ) {
					return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
				}
			}
		};
		if ( !support.checkOn ) {
			jQuery.valHooks[ this ].get = function( elem ) {
				return elem.getAttribute( "value" ) === null ? "on" : elem.value;
			};
		}
	} );
	
	
	
	
	// Return jQuery for attributes-only inclusion
	
	
	var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
	
	jQuery.extend( jQuery.event, {
	
		trigger: function( event, data, elem, onlyHandlers ) {
	
			var i, cur, tmp, bubbleType, ontype, handle, special,
				eventPath = [ elem || document ],
				type = hasOwn.call( event, "type" ) ? event.type : event,
				namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
	
			cur = tmp = elem = elem || document;
	
			// Don't do events on text and comment nodes
			if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
				return;
			}
	
			// focus/blur morphs to focusin/out; ensure we're not firing them right now
			if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
				return;
			}
	
			if ( type.indexOf( "." ) > -1 ) {
	
				// Namespaced trigger; create a regexp to match event type in handle()
				namespaces = type.split( "." );
				type = namespaces.shift();
				namespaces.sort();
			}
			ontype = type.indexOf( ":" ) < 0 && "on" + type;
	
			// Caller can pass in a jQuery.Event object, Object, or just an event type string
			event = event[ jQuery.expando ] ?
				event :
				new jQuery.Event( type, typeof event === "object" && event );
	
			// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
			event.isTrigger = onlyHandlers ? 2 : 3;
			event.namespace = namespaces.join( "." );
			event.rnamespace = event.namespace ?
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
				null;
	
			// Clean up the event in case it is being reused
			event.result = undefined;
			if ( !event.target ) {
				event.target = elem;
			}
	
			// Clone any incoming data and prepend the event, creating the handler arg list
			data = data == null ?
				[ event ] :
				jQuery.makeArray( data, [ event ] );
	
			// Allow special events to draw outside the lines
			special = jQuery.event.special[ type ] || {};
			if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
				return;
			}
	
			// Determine event propagation path in advance, per W3C events spec (#9951)
			// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
			if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
	
				bubbleType = special.delegateType || type;
				if ( !rfocusMorph.test( bubbleType + type ) ) {
					cur = cur.parentNode;
				}
				for ( ; cur; cur = cur.parentNode ) {
					eventPath.push( cur );
					tmp = cur;
				}
	
				// Only add window if we got to document (e.g., not plain obj or detached DOM)
				if ( tmp === ( elem.ownerDocument || document ) ) {
					eventPath.push( tmp.defaultView || tmp.parentWindow || window );
				}
			}
	
			// Fire handlers on the event path
			i = 0;
			while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
	
				event.type = i > 1 ?
					bubbleType :
					special.bindType || type;
	
				// jQuery handler
				handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
					dataPriv.get( cur, "handle" );
				if ( handle ) {
					handle.apply( cur, data );
				}
	
				// Native handler
				handle = ontype && cur[ ontype ];
				if ( handle && handle.apply && acceptData( cur ) ) {
					event.result = handle.apply( cur, data );
					if ( event.result === false ) {
						event.preventDefault();
					}
				}
			}
			event.type = type;
	
			// If nobody prevented the default action, do it now
			if ( !onlyHandlers && !event.isDefaultPrevented() ) {
	
				if ( ( !special._default ||
					special._default.apply( eventPath.pop(), data ) === false ) &&
					acceptData( elem ) ) {
	
					// Call a native DOM method on the target with the same name name as the event.
					// Don't do default actions on window, that's where global variables be (#6170)
					if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
	
						// Don't re-trigger an onFOO event when we call its FOO() method
						tmp = elem[ ontype ];
	
						if ( tmp ) {
							elem[ ontype ] = null;
						}
	
						// Prevent re-triggering of the same event, since we already bubbled it above
						jQuery.event.triggered = type;
						elem[ type ]();
						jQuery.event.triggered = undefined;
	
						if ( tmp ) {
							elem[ ontype ] = tmp;
						}
					}
				}
			}
	
			return event.result;
		},
	
		// Piggyback on a donor event to simulate a different one
		// Used only for `focus(in | out)` events
		simulate: function( type, elem, event ) {
			var e = jQuery.extend(
				new jQuery.Event(),
				event,
				{
					type: type,
					isSimulated: true
				}
			);
	
			jQuery.event.trigger( e, null, elem );
		}
	
	} );
	
	jQuery.fn.extend( {
	
		trigger: function( type, data ) {
			return this.each( function() {
				jQuery.event.trigger( type, data, this );
			} );
		},
		triggerHandler: function( type, data ) {
			var elem = this[ 0 ];
			if ( elem ) {
				return jQuery.event.trigger( type, data, elem, true );
			}
		}
	} );
	
	
	jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
		"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
		"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
		function( i, name ) {
	
		// Handle event binding
		jQuery.fn[ name ] = function( data, fn ) {
			return arguments.length > 0 ?
				this.on( name, null, data, fn ) :
				this.trigger( name );
		};
	} );
	
	jQuery.fn.extend( {
		hover: function( fnOver, fnOut ) {
			return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
		}
	} );
	
	
	
	
	support.focusin = "onfocusin" in window;
	
	
	// Support: Firefox
	// Firefox doesn't have focus(in | out) events
	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
	//
	// Support: Chrome, Safari
	// focus(in | out) events fire after focus & blur events,
	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
	// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
	if ( !support.focusin ) {
		jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
	
			// Attach a single capturing handler on the document while someone wants focusin/focusout
			var handler = function( event ) {
				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
			};
	
			jQuery.event.special[ fix ] = {
				setup: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix );
	
					if ( !attaches ) {
						doc.addEventListener( orig, handler, true );
					}
					dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
				},
				teardown: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix ) - 1;
	
					if ( !attaches ) {
						doc.removeEventListener( orig, handler, true );
						dataPriv.remove( doc, fix );
	
					} else {
						dataPriv.access( doc, fix, attaches );
					}
				}
			};
		} );
	}
	var location = window.location;
	
	var nonce = jQuery.now();
	
	var rquery = ( /\?/ );
	
	
	
	// Support: Android 2.3
	// Workaround failure to string-cast null input
	jQuery.parseJSON = function( data ) {
		return JSON.parse( data + "" );
	};
	
	
	// Cross-browser xml parsing
	jQuery.parseXML = function( data ) {
		var xml;
		if ( !data || typeof data !== "string" ) {
			return null;
		}
	
		// Support: IE9
		try {
			xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
		} catch ( e ) {
			xml = undefined;
		}
	
		if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
			jQuery.error( "Invalid XML: " + data );
		}
		return xml;
	};
	
	
	var
		rhash = /#.*$/,
		rts = /([?&])_=[^&]*/,
		rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
	
		// #7653, #8125, #8152: local protocol detection
		rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
		rnoContent = /^(?:GET|HEAD)$/,
		rprotocol = /^\/\//,
	
		/* Prefilters
		 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
		 * 2) These are called:
		 *    - BEFORE asking for a transport
		 *    - AFTER param serialization (s.data is a string if s.processData is true)
		 * 3) key is the dataType
		 * 4) the catchall symbol "*" can be used
		 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
		 */
		prefilters = {},
	
		/* Transports bindings
		 * 1) key is the dataType
		 * 2) the catchall symbol "*" can be used
		 * 3) selection will start with transport dataType and THEN go to "*" if needed
		 */
		transports = {},
	
		// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
		allTypes = "*/".concat( "*" ),
	
		// Anchor tag for parsing the document origin
		originAnchor = document.createElement( "a" );
		originAnchor.href = location.href;
	
	// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
	function addToPrefiltersOrTransports( structure ) {
	
		// dataTypeExpression is optional and defaults to "*"
		return function( dataTypeExpression, func ) {
	
			if ( typeof dataTypeExpression !== "string" ) {
				func = dataTypeExpression;
				dataTypeExpression = "*";
			}
	
			var dataType,
				i = 0,
				dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
	
			if ( jQuery.isFunction( func ) ) {
	
				// For each dataType in the dataTypeExpression
				while ( ( dataType = dataTypes[ i++ ] ) ) {
	
					// Prepend if requested
					if ( dataType[ 0 ] === "+" ) {
						dataType = dataType.slice( 1 ) || "*";
						( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
	
					// Otherwise append
					} else {
						( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
					}
				}
			}
		};
	}
	
	// Base inspection function for prefilters and transports
	function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
	
		var inspected = {},
			seekingTransport = ( structure === transports );
	
		function inspect( dataType ) {
			var selected;
			inspected[ dataType ] = true;
			jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
				var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
				if ( typeof dataTypeOrTransport === "string" &&
					!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
	
					options.dataTypes.unshift( dataTypeOrTransport );
					inspect( dataTypeOrTransport );
					return false;
				} else if ( seekingTransport ) {
					return !( selected = dataTypeOrTransport );
				}
			} );
			return selected;
		}
	
		return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
	}
	
	// A special extend for ajax options
	// that takes "flat" options (not to be deep extended)
	// Fixes #9887
	function ajaxExtend( target, src ) {
		var key, deep,
			flatOptions = jQuery.ajaxSettings.flatOptions || {};
	
		for ( key in src ) {
			if ( src[ key ] !== undefined ) {
				( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
			}
		}
		if ( deep ) {
			jQuery.extend( true, target, deep );
		}
	
		return target;
	}
	
	/* Handles responses to an ajax request:
	 * - finds the right dataType (mediates between content-type and expected dataType)
	 * - returns the corresponding response
	 */
	function ajaxHandleResponses( s, jqXHR, responses ) {
	
		var ct, type, finalDataType, firstDataType,
			contents = s.contents,
			dataTypes = s.dataTypes;
	
		// Remove auto dataType and get content-type in the process
		while ( dataTypes[ 0 ] === "*" ) {
			dataTypes.shift();
			if ( ct === undefined ) {
				ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
			}
		}
	
		// Check if we're dealing with a known content-type
		if ( ct ) {
			for ( type in contents ) {
				if ( contents[ type ] && contents[ type ].test( ct ) ) {
					dataTypes.unshift( type );
					break;
				}
			}
		}
	
		// Check to see if we have a response for the expected dataType
		if ( dataTypes[ 0 ] in responses ) {
			finalDataType = dataTypes[ 0 ];
		} else {
	
			// Try convertible dataTypes
			for ( type in responses ) {
				if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
					finalDataType = type;
					break;
				}
				if ( !firstDataType ) {
					firstDataType = type;
				}
			}
	
			// Or just use first one
			finalDataType = finalDataType || firstDataType;
		}
	
		// If we found a dataType
		// We add the dataType to the list if needed
		// and return the corresponding response
		if ( finalDataType ) {
			if ( finalDataType !== dataTypes[ 0 ] ) {
				dataTypes.unshift( finalDataType );
			}
			return responses[ finalDataType ];
		}
	}
	
	/* Chain conversions given the request and the original response
	 * Also sets the responseXXX fields on the jqXHR instance
	 */
	function ajaxConvert( s, response, jqXHR, isSuccess ) {
		var conv2, current, conv, tmp, prev,
			converters = {},
	
			// Work with a copy of dataTypes in case we need to modify it for conversion
			dataTypes = s.dataTypes.slice();
	
		// Create converters map with lowercased keys
		if ( dataTypes[ 1 ] ) {
			for ( conv in s.converters ) {
				converters[ conv.toLowerCase() ] = s.converters[ conv ];
			}
		}
	
		current = dataTypes.shift();
	
		// Convert to each sequential dataType
		while ( current ) {
	
			if ( s.responseFields[ current ] ) {
				jqXHR[ s.responseFields[ current ] ] = response;
			}
	
			// Apply the dataFilter if provided
			if ( !prev && isSuccess && s.dataFilter ) {
				response = s.dataFilter( response, s.dataType );
			}
	
			prev = current;
			current = dataTypes.shift();
	
			if ( current ) {
	
			// There's only work to do if current dataType is non-auto
				if ( current === "*" ) {
	
					current = prev;
	
				// Convert response if prev dataType is non-auto and differs from current
				} else if ( prev !== "*" && prev !== current ) {
	
					// Seek a direct converter
					conv = converters[ prev + " " + current ] || converters[ "* " + current ];
	
					// If none found, seek a pair
					if ( !conv ) {
						for ( conv2 in converters ) {
	
							// If conv2 outputs current
							tmp = conv2.split( " " );
							if ( tmp[ 1 ] === current ) {
	
								// If prev can be converted to accepted input
								conv = converters[ prev + " " + tmp[ 0 ] ] ||
									converters[ "* " + tmp[ 0 ] ];
								if ( conv ) {
	
									// Condense equivalence converters
									if ( conv === true ) {
										conv = converters[ conv2 ];
	
									// Otherwise, insert the intermediate dataType
									} else if ( converters[ conv2 ] !== true ) {
										current = tmp[ 0 ];
										dataTypes.unshift( tmp[ 1 ] );
									}
									break;
								}
							}
						}
					}
	
					// Apply converter (if not an equivalence)
					if ( conv !== true ) {
	
						// Unless errors are allowed to bubble, catch and return them
						if ( conv && s.throws ) {
							response = conv( response );
						} else {
							try {
								response = conv( response );
							} catch ( e ) {
								return {
									state: "parsererror",
									error: conv ? e : "No conversion from " + prev + " to " + current
								};
							}
						}
					}
				}
			}
		}
	
		return { state: "success", data: response };
	}
	
	jQuery.extend( {
	
		// Counter for holding the number of active queries
		active: 0,
	
		// Last-Modified header cache for next request
		lastModified: {},
		etag: {},
	
		ajaxSettings: {
			url: location.href,
			type: "GET",
			isLocal: rlocalProtocol.test( location.protocol ),
			global: true,
			processData: true,
			async: true,
			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
			/*
			timeout: 0,
			data: null,
			dataType: null,
			username: null,
			password: null,
			cache: null,
			throws: false,
			traditional: false,
			headers: {},
			*/
	
			accepts: {
				"*": allTypes,
				text: "text/plain",
				html: "text/html",
				xml: "application/xml, text/xml",
				json: "application/json, text/javascript"
			},
	
			contents: {
				xml: /\bxml\b/,
				html: /\bhtml/,
				json: /\bjson\b/
			},
	
			responseFields: {
				xml: "responseXML",
				text: "responseText",
				json: "responseJSON"
			},
	
			// Data converters
			// Keys separate source (or catchall "*") and destination types with a single space
			converters: {
	
				// Convert anything to text
				"* text": String,
	
				// Text to html (true = no transformation)
				"text html": true,
	
				// Evaluate text as a json expression
				"text json": jQuery.parseJSON,
	
				// Parse text as xml
				"text xml": jQuery.parseXML
			},
	
			// For options that shouldn't be deep extended:
			// you can add your own custom options here if
			// and when you create one that shouldn't be
			// deep extended (see ajaxExtend)
			flatOptions: {
				url: true,
				context: true
			}
		},
	
		// Creates a full fledged settings object into target
		// with both ajaxSettings and settings fields.
		// If target is omitted, writes into ajaxSettings.
		ajaxSetup: function( target, settings ) {
			return settings ?
	
				// Building a settings object
				ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
	
				// Extending ajaxSettings
				ajaxExtend( jQuery.ajaxSettings, target );
		},
	
		ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
		ajaxTransport: addToPrefiltersOrTransports( transports ),
	
		// Main method
		ajax: function( url, options ) {
	
			// If url is an object, simulate pre-1.5 signature
			if ( typeof url === "object" ) {
				options = url;
				url = undefined;
			}
	
			// Force options to be an object
			options = options || {};
	
			var transport,
	
				// URL without anti-cache param
				cacheURL,
	
				// Response headers
				responseHeadersString,
				responseHeaders,
	
				// timeout handle
				timeoutTimer,
	
				// Url cleanup var
				urlAnchor,
	
				// To know if global events are to be dispatched
				fireGlobals,
	
				// Loop variable
				i,
	
				// Create the final options object
				s = jQuery.ajaxSetup( {}, options ),
	
				// Callbacks context
				callbackContext = s.context || s,
	
				// Context for global events is callbackContext if it is a DOM node or jQuery collection
				globalEventContext = s.context &&
					( callbackContext.nodeType || callbackContext.jquery ) ?
						jQuery( callbackContext ) :
						jQuery.event,
	
				// Deferreds
				deferred = jQuery.Deferred(),
				completeDeferred = jQuery.Callbacks( "once memory" ),
	
				// Status-dependent callbacks
				statusCode = s.statusCode || {},
	
				// Headers (they are sent all at once)
				requestHeaders = {},
				requestHeadersNames = {},
	
				// The jqXHR state
				state = 0,
	
				// Default abort message
				strAbort = "canceled",
	
				// Fake xhr
				jqXHR = {
					readyState: 0,
	
					// Builds headers hashtable if needed
					getResponseHeader: function( key ) {
						var match;
						if ( state === 2 ) {
							if ( !responseHeaders ) {
								responseHeaders = {};
								while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
									responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
								}
							}
							match = responseHeaders[ key.toLowerCase() ];
						}
						return match == null ? null : match;
					},
	
					// Raw string
					getAllResponseHeaders: function() {
						return state === 2 ? responseHeadersString : null;
					},
	
					// Caches the header
					setRequestHeader: function( name, value ) {
						var lname = name.toLowerCase();
						if ( !state ) {
							name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
							requestHeaders[ name ] = value;
						}
						return this;
					},
	
					// Overrides response content-type header
					overrideMimeType: function( type ) {
						if ( !state ) {
							s.mimeType = type;
						}
						return this;
					},
	
					// Status-dependent callbacks
					statusCode: function( map ) {
						var code;
						if ( map ) {
							if ( state < 2 ) {
								for ( code in map ) {
	
									// Lazy-add the new callback in a way that preserves old ones
									statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
								}
							} else {
	
								// Execute the appropriate callbacks
								jqXHR.always( map[ jqXHR.status ] );
							}
						}
						return this;
					},
	
					// Cancel the request
					abort: function( statusText ) {
						var finalText = statusText || strAbort;
						if ( transport ) {
							transport.abort( finalText );
						}
						done( 0, finalText );
						return this;
					}
				};
	
			// Attach deferreds
			deferred.promise( jqXHR ).complete = completeDeferred.add;
			jqXHR.success = jqXHR.done;
			jqXHR.error = jqXHR.fail;
	
			// Remove hash character (#7531: and string promotion)
			// Add protocol if not provided (prefilters might expect it)
			// Handle falsy url in the settings object (#10093: consistency with old signature)
			// We also use the url parameter if available
			s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
				.replace( rprotocol, location.protocol + "//" );
	
			// Alias method option to type as per ticket #12004
			s.type = options.method || options.type || s.method || s.type;
	
			// Extract dataTypes list
			s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
	
			// A cross-domain request is in order when the origin doesn't match the current origin.
			if ( s.crossDomain == null ) {
				urlAnchor = document.createElement( "a" );
	
				// Support: IE8-11+
				// IE throws exception if url is malformed, e.g. http://example.com:80x/
				try {
					urlAnchor.href = s.url;
	
					// Support: IE8-11+
					// Anchor's host property isn't correctly set when s.url is relative
					urlAnchor.href = urlAnchor.href;
					s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
						urlAnchor.protocol + "//" + urlAnchor.host;
				} catch ( e ) {
	
					// If there is an error parsing the URL, assume it is crossDomain,
					// it can be rejected by the transport if it is invalid
					s.crossDomain = true;
				}
			}
	
			// Convert data if not already a string
			if ( s.data && s.processData && typeof s.data !== "string" ) {
				s.data = jQuery.param( s.data, s.traditional );
			}
	
			// Apply prefilters
			inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
	
			// If request was aborted inside a prefilter, stop there
			if ( state === 2 ) {
				return jqXHR;
			}
	
			// We can fire global events as of now if asked to
			// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
			fireGlobals = jQuery.event && s.global;
	
			// Watch for a new set of requests
			if ( fireGlobals && jQuery.active++ === 0 ) {
				jQuery.event.trigger( "ajaxStart" );
			}
	
			// Uppercase the type
			s.type = s.type.toUpperCase();
	
			// Determine if request has content
			s.hasContent = !rnoContent.test( s.type );
	
			// Save the URL in case we're toying with the If-Modified-Since
			// and/or If-None-Match header later on
			cacheURL = s.url;
	
			// More options handling for requests with no content
			if ( !s.hasContent ) {
	
				// If data is available, append data to url
				if ( s.data ) {
					cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
	
					// #9682: remove data so that it's not used in an eventual retry
					delete s.data;
				}
	
				// Add anti-cache in url if needed
				if ( s.cache === false ) {
					s.url = rts.test( cacheURL ) ?
	
						// If there is already a '_' parameter, set its value
						cacheURL.replace( rts, "$1_=" + nonce++ ) :
	
						// Otherwise add one to the end
						cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
				}
			}
	
			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
			if ( s.ifModified ) {
				if ( jQuery.lastModified[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
				}
				if ( jQuery.etag[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
				}
			}
	
			// Set the correct header, if data is being sent
			if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
				jqXHR.setRequestHeader( "Content-Type", s.contentType );
			}
	
			// Set the Accepts header for the server, depending on the dataType
			jqXHR.setRequestHeader(
				"Accept",
				s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
					s.accepts[ s.dataTypes[ 0 ] ] +
						( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
					s.accepts[ "*" ]
			);
	
			// Check for headers option
			for ( i in s.headers ) {
				jqXHR.setRequestHeader( i, s.headers[ i ] );
			}
	
			// Allow custom headers/mimetypes and early abort
			if ( s.beforeSend &&
				( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
	
				// Abort if not done already and return
				return jqXHR.abort();
			}
	
			// Aborting is no longer a cancellation
			strAbort = "abort";
	
			// Install callbacks on deferreds
			for ( i in { success: 1, error: 1, complete: 1 } ) {
				jqXHR[ i ]( s[ i ] );
			}
	
			// Get transport
			transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
	
			// If no transport, we auto-abort
			if ( !transport ) {
				done( -1, "No Transport" );
			} else {
				jqXHR.readyState = 1;
	
				// Send global event
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
				}
	
				// If request was aborted inside ajaxSend, stop there
				if ( state === 2 ) {
					return jqXHR;
				}
	
				// Timeout
				if ( s.async && s.timeout > 0 ) {
					timeoutTimer = window.setTimeout( function() {
						jqXHR.abort( "timeout" );
					}, s.timeout );
				}
	
				try {
					state = 1;
					transport.send( requestHeaders, done );
				} catch ( e ) {
	
					// Propagate exception as error if not done
					if ( state < 2 ) {
						done( -1, e );
	
					// Simply rethrow otherwise
					} else {
						throw e;
					}
				}
			}
	
			// Callback for when everything is done
			function done( status, nativeStatusText, responses, headers ) {
				var isSuccess, success, error, response, modified,
					statusText = nativeStatusText;
	
				// Called once
				if ( state === 2 ) {
					return;
				}
	
				// State is "done" now
				state = 2;
	
				// Clear timeout if it exists
				if ( timeoutTimer ) {
					window.clearTimeout( timeoutTimer );
				}
	
				// Dereference transport for early garbage collection
				// (no matter how long the jqXHR object will be used)
				transport = undefined;
	
				// Cache response headers
				responseHeadersString = headers || "";
	
				// Set readyState
				jqXHR.readyState = status > 0 ? 4 : 0;
	
				// Determine if successful
				isSuccess = status >= 200 && status < 300 || status === 304;
	
				// Get response data
				if ( responses ) {
					response = ajaxHandleResponses( s, jqXHR, responses );
				}
	
				// Convert no matter what (that way responseXXX fields are always set)
				response = ajaxConvert( s, response, jqXHR, isSuccess );
	
				// If successful, handle type chaining
				if ( isSuccess ) {
	
					// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
					if ( s.ifModified ) {
						modified = jqXHR.getResponseHeader( "Last-Modified" );
						if ( modified ) {
							jQuery.lastModified[ cacheURL ] = modified;
						}
						modified = jqXHR.getResponseHeader( "etag" );
						if ( modified ) {
							jQuery.etag[ cacheURL ] = modified;
						}
					}
	
					// if no content
					if ( status === 204 || s.type === "HEAD" ) {
						statusText = "nocontent";
	
					// if not modified
					} else if ( status === 304 ) {
						statusText = "notmodified";
	
					// If we have data, let's convert it
					} else {
						statusText = response.state;
						success = response.data;
						error = response.error;
						isSuccess = !error;
					}
				} else {
	
					// Extract error from statusText and normalize for non-aborts
					error = statusText;
					if ( status || !statusText ) {
						statusText = "error";
						if ( status < 0 ) {
							status = 0;
						}
					}
				}
	
				// Set data for the fake xhr object
				jqXHR.status = status;
				jqXHR.statusText = ( nativeStatusText || statusText ) + "";
	
				// Success/Error
				if ( isSuccess ) {
					deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
				} else {
					deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
				}
	
				// Status-dependent callbacks
				jqXHR.statusCode( statusCode );
				statusCode = undefined;
	
				if ( fireGlobals ) {
					globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
						[ jqXHR, s, isSuccess ? success : error ] );
				}
	
				// Complete
				completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
	
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
	
					// Handle the global AJAX counter
					if ( !( --jQuery.active ) ) {
						jQuery.event.trigger( "ajaxStop" );
					}
				}
			}
	
			return jqXHR;
		},
	
		getJSON: function( url, data, callback ) {
			return jQuery.get( url, data, callback, "json" );
		},
	
		getScript: function( url, callback ) {
			return jQuery.get( url, undefined, callback, "script" );
		}
	} );
	
	jQuery.each( [ "get", "post" ], function( i, method ) {
		jQuery[ method ] = function( url, data, callback, type ) {
	
			// Shift arguments if data argument was omitted
			if ( jQuery.isFunction( data ) ) {
				type = type || callback;
				callback = data;
				data = undefined;
			}
	
			// The url can be an options object (which then must have .url)
			return jQuery.ajax( jQuery.extend( {
				url: url,
				type: method,
				dataType: type,
				data: data,
				success: callback
			}, jQuery.isPlainObject( url ) && url ) );
		};
	} );
	
	
	jQuery._evalUrl = function( url ) {
		return jQuery.ajax( {
			url: url,
	
			// Make this explicit, since user can override this through ajaxSetup (#11264)
			type: "GET",
			dataType: "script",
			async: false,
			global: false,
			"throws": true
		} );
	};
	
	
	jQuery.fn.extend( {
		wrapAll: function( html ) {
			var wrap;
	
			if ( jQuery.isFunction( html ) ) {
				return this.each( function( i ) {
					jQuery( this ).wrapAll( html.call( this, i ) );
				} );
			}
	
			if ( this[ 0 ] ) {
	
				// The elements to wrap the target around
				wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
	
				if ( this[ 0 ].parentNode ) {
					wrap.insertBefore( this[ 0 ] );
				}
	
				wrap.map( function() {
					var elem = this;
	
					while ( elem.firstElementChild ) {
						elem = elem.firstElementChild;
					}
	
					return elem;
				} ).append( this );
			}
	
			return this;
		},
	
		wrapInner: function( html ) {
			if ( jQuery.isFunction( html ) ) {
				return this.each( function( i ) {
					jQuery( this ).wrapInner( html.call( this, i ) );
				} );
			}
	
			return this.each( function() {
				var self = jQuery( this ),
					contents = self.contents();
	
				if ( contents.length ) {
					contents.wrapAll( html );
	
				} else {
					self.append( html );
				}
			} );
		},
	
		wrap: function( html ) {
			var isFunction = jQuery.isFunction( html );
	
			return this.each( function( i ) {
				jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
			} );
		},
	
		unwrap: function() {
			return this.parent().each( function() {
				if ( !jQuery.nodeName( this, "body" ) ) {
					jQuery( this ).replaceWith( this.childNodes );
				}
			} ).end();
		}
	} );
	
	
	jQuery.expr.filters.hidden = function( elem ) {
		return !jQuery.expr.filters.visible( elem );
	};
	jQuery.expr.filters.visible = function( elem ) {
	
		// Support: Opera <= 12.12
		// Opera reports offsetWidths and offsetHeights less than zero on some elements
		// Use OR instead of AND as the element is not visible if either is true
		// See tickets #10406 and #13132
		return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
	};
	
	
	
	
	var r20 = /%20/g,
		rbracket = /\[\]$/,
		rCRLF = /\r?\n/g,
		rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
		rsubmittable = /^(?:input|select|textarea|keygen)/i;
	
	function buildParams( prefix, obj, traditional, add ) {
		var name;
	
		if ( jQuery.isArray( obj ) ) {
	
			// Serialize array item.
			jQuery.each( obj, function( i, v ) {
				if ( traditional || rbracket.test( prefix ) ) {
	
					// Treat each array item as a scalar.
					add( prefix, v );
	
				} else {
	
					// Item is non-scalar (array or object), encode its numeric index.
					buildParams(
						prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
						v,
						traditional,
						add
					);
				}
			} );
	
		} else if ( !traditional && jQuery.type( obj ) === "object" ) {
	
			// Serialize object item.
			for ( name in obj ) {
				buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
			}
	
		} else {
	
			// Serialize scalar item.
			add( prefix, obj );
		}
	}
	
	// Serialize an array of form elements or a set of
	// key/values into a query string
	jQuery.param = function( a, traditional ) {
		var prefix,
			s = [],
			add = function( key, value ) {
	
				// If value is a function, invoke it and return its value
				value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
				s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
			};
	
		// Set traditional to true for jQuery <= 1.3.2 behavior.
		if ( traditional === undefined ) {
			traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
		}
	
		// If an array was passed in, assume that it is an array of form elements.
		if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
	
			// Serialize the form elements
			jQuery.each( a, function() {
				add( this.name, this.value );
			} );
	
		} else {
	
			// If traditional, encode the "old" way (the way 1.3.2 or older
			// did it), otherwise encode params recursively.
			for ( prefix in a ) {
				buildParams( prefix, a[ prefix ], traditional, add );
			}
		}
	
		// Return the resulting serialization
		return s.join( "&" ).replace( r20, "+" );
	};
	
	jQuery.fn.extend( {
		serialize: function() {
			return jQuery.param( this.serializeArray() );
		},
		serializeArray: function() {
			return this.map( function() {
	
				// Can add propHook for "elements" to filter or add form elements
				var elements = jQuery.prop( this, "elements" );
				return elements ? jQuery.makeArray( elements ) : this;
			} )
			.filter( function() {
				var type = this.type;
	
				// Use .is( ":disabled" ) so that fieldset[disabled] works
				return this.name && !jQuery( this ).is( ":disabled" ) &&
					rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
					( this.checked || !rcheckableType.test( type ) );
			} )
			.map( function( i, elem ) {
				var val = jQuery( this ).val();
	
				return val == null ?
					null :
					jQuery.isArray( val ) ?
						jQuery.map( val, function( val ) {
							return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
						} ) :
						{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
			} ).get();
		}
	} );
	
	
	jQuery.ajaxSettings.xhr = function() {
		try {
			return new window.XMLHttpRequest();
		} catch ( e ) {}
	};
	
	var xhrSuccessStatus = {
	
			// File protocol always yields status code 0, assume 200
			0: 200,
	
			// Support: IE9
			// #1450: sometimes IE returns 1223 when it should be 204
			1223: 204
		},
		xhrSupported = jQuery.ajaxSettings.xhr();
	
	support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
	support.ajax = xhrSupported = !!xhrSupported;
	
	jQuery.ajaxTransport( function( options ) {
		var callback, errorCallback;
	
		// Cross domain only allowed if supported through XMLHttpRequest
		if ( support.cors || xhrSupported && !options.crossDomain ) {
			return {
				send: function( headers, complete ) {
					var i,
						xhr = options.xhr();
	
					xhr.open(
						options.type,
						options.url,
						options.async,
						options.username,
						options.password
					);
	
					// Apply custom fields if provided
					if ( options.xhrFields ) {
						for ( i in options.xhrFields ) {
							xhr[ i ] = options.xhrFields[ i ];
						}
					}
	
					// Override mime type if needed
					if ( options.mimeType && xhr.overrideMimeType ) {
						xhr.overrideMimeType( options.mimeType );
					}
	
					// X-Requested-With header
					// For cross-domain requests, seeing as conditions for a preflight are
					// akin to a jigsaw puzzle, we simply never set it to be sure.
					// (it can always be set on a per-request basis or even using ajaxSetup)
					// For same-domain requests, won't change header if already provided.
					if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
						headers[ "X-Requested-With" ] = "XMLHttpRequest";
					}
	
					// Set headers
					for ( i in headers ) {
						xhr.setRequestHeader( i, headers[ i ] );
					}
	
					// Callback
					callback = function( type ) {
						return function() {
							if ( callback ) {
								callback = errorCallback = xhr.onload =
									xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
	
								if ( type === "abort" ) {
									xhr.abort();
								} else if ( type === "error" ) {
	
									// Support: IE9
									// On a manual native abort, IE9 throws
									// errors on any property access that is not readyState
									if ( typeof xhr.status !== "number" ) {
										complete( 0, "error" );
									} else {
										complete(
	
											// File: protocol always yields status 0; see #8605, #14207
											xhr.status,
											xhr.statusText
										);
									}
								} else {
									complete(
										xhrSuccessStatus[ xhr.status ] || xhr.status,
										xhr.statusText,
	
										// Support: IE9 only
										// IE9 has no XHR2 but throws on binary (trac-11426)
										// For XHR2 non-text, let the caller handle it (gh-2498)
										( xhr.responseType || "text" ) !== "text"  ||
										typeof xhr.responseText !== "string" ?
											{ binary: xhr.response } :
											{ text: xhr.responseText },
										xhr.getAllResponseHeaders()
									);
								}
							}
						};
					};
	
					// Listen to events
					xhr.onload = callback();
					errorCallback = xhr.onerror = callback( "error" );
	
					// Support: IE9
					// Use onreadystatechange to replace onabort
					// to handle uncaught aborts
					if ( xhr.onabort !== undefined ) {
						xhr.onabort = errorCallback;
					} else {
						xhr.onreadystatechange = function() {
	
							// Check readyState before timeout as it changes
							if ( xhr.readyState === 4 ) {
	
								// Allow onerror to be called first,
								// but that will not handle a native abort
								// Also, save errorCallback to a variable
								// as xhr.onerror cannot be accessed
								window.setTimeout( function() {
									if ( callback ) {
										errorCallback();
									}
								} );
							}
						};
					}
	
					// Create the abort callback
					callback = callback( "abort" );
	
					try {
	
						// Do send the request (this may raise an exception)
						xhr.send( options.hasContent && options.data || null );
					} catch ( e ) {
	
						// #14683: Only rethrow if this hasn't been notified as an error yet
						if ( callback ) {
							throw e;
						}
					}
				},
	
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	// Install script dataType
	jQuery.ajaxSetup( {
		accepts: {
			script: "text/javascript, application/javascript, " +
				"application/ecmascript, application/x-ecmascript"
		},
		contents: {
			script: /\b(?:java|ecma)script\b/
		},
		converters: {
			"text script": function( text ) {
				jQuery.globalEval( text );
				return text;
			}
		}
	} );
	
	// Handle cache's special case and crossDomain
	jQuery.ajaxPrefilter( "script", function( s ) {
		if ( s.cache === undefined ) {
			s.cache = false;
		}
		if ( s.crossDomain ) {
			s.type = "GET";
		}
	} );
	
	// Bind script tag hack transport
	jQuery.ajaxTransport( "script", function( s ) {
	
		// This transport only deals with cross domain requests
		if ( s.crossDomain ) {
			var script, callback;
			return {
				send: function( _, complete ) {
					script = jQuery( "<script>" ).prop( {
						charset: s.scriptCharset,
						src: s.url
					} ).on(
						"load error",
						callback = function( evt ) {
							script.remove();
							callback = null;
							if ( evt ) {
								complete( evt.type === "error" ? 404 : 200, evt.type );
							}
						}
					);
	
					// Use native DOM manipulation to avoid our domManip AJAX trickery
					document.head.appendChild( script[ 0 ] );
				},
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	var oldCallbacks = [],
		rjsonp = /(=)\?(?=&|$)|\?\?/;
	
	// Default jsonp settings
	jQuery.ajaxSetup( {
		jsonp: "callback",
		jsonpCallback: function() {
			var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
			this[ callback ] = true;
			return callback;
		}
	} );
	
	// Detect, normalize options and install callbacks for jsonp requests
	jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
	
		var callbackName, overwritten, responseContainer,
			jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
				"url" :
				typeof s.data === "string" &&
					( s.contentType || "" )
						.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
					rjsonp.test( s.data ) && "data"
			);
	
		// Handle iff the expected data type is "jsonp" or we have a parameter to set
		if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
	
			// Get callback name, remembering preexisting value associated with it
			callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
				s.jsonpCallback() :
				s.jsonpCallback;
	
			// Insert callback into url or form data
			if ( jsonProp ) {
				s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
			} else if ( s.jsonp !== false ) {
				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
			}
	
			// Use data converter to retrieve json after script execution
			s.converters[ "script json" ] = function() {
				if ( !responseContainer ) {
					jQuery.error( callbackName + " was not called" );
				}
				return responseContainer[ 0 ];
			};
	
			// Force json dataType
			s.dataTypes[ 0 ] = "json";
	
			// Install callback
			overwritten = window[ callbackName ];
			window[ callbackName ] = function() {
				responseContainer = arguments;
			};
	
			// Clean-up function (fires after converters)
			jqXHR.always( function() {
	
				// If previous value didn't exist - remove it
				if ( overwritten === undefined ) {
					jQuery( window ).removeProp( callbackName );
	
				// Otherwise restore preexisting value
				} else {
					window[ callbackName ] = overwritten;
				}
	
				// Save back as free
				if ( s[ callbackName ] ) {
	
					// Make sure that re-using the options doesn't screw things around
					s.jsonpCallback = originalSettings.jsonpCallback;
	
					// Save the callback name for future use
					oldCallbacks.push( callbackName );
				}
	
				// Call if it was a function and we have a response
				if ( responseContainer && jQuery.isFunction( overwritten ) ) {
					overwritten( responseContainer[ 0 ] );
				}
	
				responseContainer = overwritten = undefined;
			} );
	
			// Delegate to script
			return "script";
		}
	} );
	
	
	
	
	// Argument "data" should be string of html
	// context (optional): If specified, the fragment will be created in this context,
	// defaults to document
	// keepScripts (optional): If true, will include scripts passed in the html string
	jQuery.parseHTML = function( data, context, keepScripts ) {
		if ( !data || typeof data !== "string" ) {
			return null;
		}
		if ( typeof context === "boolean" ) {
			keepScripts = context;
			context = false;
		}
		context = context || document;
	
		var parsed = rsingleTag.exec( data ),
			scripts = !keepScripts && [];
	
		// Single tag
		if ( parsed ) {
			return [ context.createElement( parsed[ 1 ] ) ];
		}
	
		parsed = buildFragment( [ data ], context, scripts );
	
		if ( scripts && scripts.length ) {
			jQuery( scripts ).remove();
		}
	
		return jQuery.merge( [], parsed.childNodes );
	};
	
	
	// Keep a copy of the old load method
	var _load = jQuery.fn.load;
	
	/**
	 * Load a url into a page
	 */
	jQuery.fn.load = function( url, params, callback ) {
		if ( typeof url !== "string" && _load ) {
			return _load.apply( this, arguments );
		}
	
		var selector, type, response,
			self = this,
			off = url.indexOf( " " );
	
		if ( off > -1 ) {
			selector = jQuery.trim( url.slice( off ) );
			url = url.slice( 0, off );
		}
	
		// If it's a function
		if ( jQuery.isFunction( params ) ) {
	
			// We assume that it's the callback
			callback = params;
			params = undefined;
	
		// Otherwise, build a param string
		} else if ( params && typeof params === "object" ) {
			type = "POST";
		}
	
		// If we have elements to modify, make the request
		if ( self.length > 0 ) {
			jQuery.ajax( {
				url: url,
	
				// If "type" variable is undefined, then "GET" method will be used.
				// Make value of this field explicit since
				// user can override it through ajaxSetup method
				type: type || "GET",
				dataType: "html",
				data: params
			} ).done( function( responseText ) {
	
				// Save response for use in complete callback
				response = arguments;
	
				self.html( selector ?
	
					// If a selector was specified, locate the right elements in a dummy div
					// Exclude scripts to avoid IE 'Permission Denied' errors
					jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
	
					// Otherwise use the full result
					responseText );
	
			// If the request succeeds, this function gets "data", "status", "jqXHR"
			// but they are ignored because response was set above.
			// If it fails, this function gets "jqXHR", "status", "error"
			} ).always( callback && function( jqXHR, status ) {
				self.each( function() {
					callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
				} );
			} );
		}
	
		return this;
	};
	
	
	
	
	// Attach a bunch of functions for handling common AJAX events
	jQuery.each( [
		"ajaxStart",
		"ajaxStop",
		"ajaxComplete",
		"ajaxError",
		"ajaxSuccess",
		"ajaxSend"
	], function( i, type ) {
		jQuery.fn[ type ] = function( fn ) {
			return this.on( type, fn );
		};
	} );
	
	
	
	
	jQuery.expr.filters.animated = function( elem ) {
		return jQuery.grep( jQuery.timers, function( fn ) {
			return elem === fn.elem;
		} ).length;
	};
	
	
	
	
	/**
	 * Gets a window from an element
	 */
	function getWindow( elem ) {
		return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
	}
	
	jQuery.offset = {
		setOffset: function( elem, options, i ) {
			var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
				position = jQuery.css( elem, "position" ),
				curElem = jQuery( elem ),
				props = {};
	
			// Set position first, in-case top/left are set even on static elem
			if ( position === "static" ) {
				elem.style.position = "relative";
			}
	
			curOffset = curElem.offset();
			curCSSTop = jQuery.css( elem, "top" );
			curCSSLeft = jQuery.css( elem, "left" );
			calculatePosition = ( position === "absolute" || position === "fixed" ) &&
				( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
	
			// Need to be able to calculate position if either
			// top or left is auto and position is either absolute or fixed
			if ( calculatePosition ) {
				curPosition = curElem.position();
				curTop = curPosition.top;
				curLeft = curPosition.left;
	
			} else {
				curTop = parseFloat( curCSSTop ) || 0;
				curLeft = parseFloat( curCSSLeft ) || 0;
			}
	
			if ( jQuery.isFunction( options ) ) {
	
				// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
				options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
			}
	
			if ( options.top != null ) {
				props.top = ( options.top - curOffset.top ) + curTop;
			}
			if ( options.left != null ) {
				props.left = ( options.left - curOffset.left ) + curLeft;
			}
	
			if ( "using" in options ) {
				options.using.call( elem, props );
	
			} else {
				curElem.css( props );
			}
		}
	};
	
	jQuery.fn.extend( {
		offset: function( options ) {
			if ( arguments.length ) {
				return options === undefined ?
					this :
					this.each( function( i ) {
						jQuery.offset.setOffset( this, options, i );
					} );
			}
	
			var docElem, win,
				elem = this[ 0 ],
				box = { top: 0, left: 0 },
				doc = elem && elem.ownerDocument;
	
			if ( !doc ) {
				return;
			}
	
			docElem = doc.documentElement;
	
			// Make sure it's not a disconnected DOM node
			if ( !jQuery.contains( docElem, elem ) ) {
				return box;
			}
	
			box = elem.getBoundingClientRect();
			win = getWindow( doc );
			return {
				top: box.top + win.pageYOffset - docElem.clientTop,
				left: box.left + win.pageXOffset - docElem.clientLeft
			};
		},
	
		position: function() {
			if ( !this[ 0 ] ) {
				return;
			}
	
			var offsetParent, offset,
				elem = this[ 0 ],
				parentOffset = { top: 0, left: 0 };
	
			// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
			// because it is its only offset parent
			if ( jQuery.css( elem, "position" ) === "fixed" ) {
	
				// Assume getBoundingClientRect is there when computed position is fixed
				offset = elem.getBoundingClientRect();
	
			} else {
	
				// Get *real* offsetParent
				offsetParent = this.offsetParent();
	
				// Get correct offsets
				offset = this.offset();
				if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
					parentOffset = offsetParent.offset();
				}
	
				// Add offsetParent borders
				parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
				parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
			}
	
			// Subtract parent offsets and element margins
			return {
				top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
				left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
			};
		},
	
		// This method will return documentElement in the following cases:
		// 1) For the element inside the iframe without offsetParent, this method will return
		//    documentElement of the parent window
		// 2) For the hidden or detached element
		// 3) For body or html element, i.e. in case of the html node - it will return itself
		//
		// but those exceptions were never presented as a real life use-cases
		// and might be considered as more preferable results.
		//
		// This logic, however, is not guaranteed and can change at any point in the future
		offsetParent: function() {
			return this.map( function() {
				var offsetParent = this.offsetParent;
	
				while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
					offsetParent = offsetParent.offsetParent;
				}
	
				return offsetParent || documentElement;
			} );
		}
	} );
	
	// Create scrollLeft and scrollTop methods
	jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
		var top = "pageYOffset" === prop;
	
		jQuery.fn[ method ] = function( val ) {
			return access( this, function( elem, method, val ) {
				var win = getWindow( elem );
	
				if ( val === undefined ) {
					return win ? win[ prop ] : elem[ method ];
				}
	
				if ( win ) {
					win.scrollTo(
						!top ? val : win.pageXOffset,
						top ? val : win.pageYOffset
					);
	
				} else {
					elem[ method ] = val;
				}
			}, method, val, arguments.length );
		};
	} );
	
	// Support: Safari<7-8+, Chrome<37-44+
	// Add the top/left cssHooks using jQuery.fn.position
	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
	// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
	// getComputedStyle returns percent when specified for top/left/bottom/right;
	// rather than make the css module depend on the offset module, just check for it here
	jQuery.each( [ "top", "left" ], function( i, prop ) {
		jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
			function( elem, computed ) {
				if ( computed ) {
					computed = curCSS( elem, prop );
	
					// If curCSS returns percentage, fallback to offset
					return rnumnonpx.test( computed ) ?
						jQuery( elem ).position()[ prop ] + "px" :
						computed;
				}
			}
		);
	} );
	
	
	// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
	jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
		jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
			function( defaultExtra, funcName ) {
	
			// Margin is only for outerHeight, outerWidth
			jQuery.fn[ funcName ] = function( margin, value ) {
				var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
					extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
	
				return access( this, function( elem, type, value ) {
					var doc;
	
					if ( jQuery.isWindow( elem ) ) {
	
						// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
						// isn't a whole lot we can do. See pull request at this URL for discussion:
						// https://github.com/jquery/jquery/pull/764
						return elem.document.documentElement[ "client" + name ];
					}
	
					// Get document width or height
					if ( elem.nodeType === 9 ) {
						doc = elem.documentElement;
	
						// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
						// whichever is greatest
						return Math.max(
							elem.body[ "scroll" + name ], doc[ "scroll" + name ],
							elem.body[ "offset" + name ], doc[ "offset" + name ],
							doc[ "client" + name ]
						);
					}
	
					return value === undefined ?
	
						// Get width or height on the element, requesting but not forcing parseFloat
						jQuery.css( elem, type, extra ) :
	
						// Set width or height on the element
						jQuery.style( elem, type, value, extra );
				}, type, chainable ? margin : undefined, chainable, null );
			};
		} );
	} );
	
	
	jQuery.fn.extend( {
	
		bind: function( types, data, fn ) {
			return this.on( types, null, data, fn );
		},
		unbind: function( types, fn ) {
			return this.off( types, null, fn );
		},
	
		delegate: function( selector, types, data, fn ) {
			return this.on( types, selector, data, fn );
		},
		undelegate: function( selector, types, fn ) {
	
			// ( namespace ) or ( selector, types [, fn] )
			return arguments.length === 1 ?
				this.off( selector, "**" ) :
				this.off( types, selector || "**", fn );
		},
		size: function() {
			return this.length;
		}
	} );
	
	jQuery.fn.andSelf = jQuery.fn.addBack;
	
	
	
	
	// Register as a named AMD module, since jQuery can be concatenated with other
	// files that may use define, but not via a proper concatenation script that
	// understands anonymous AMD modules. A named AMD is safest and most robust
	// way to register. Lowercase jquery is used because AMD module names are
	// derived from file names, and jQuery is normally delivered in a lowercase
	// file name. Do this after creating the global so that if an AMD module wants
	// to call noConflict to hide this version of jQuery, it will work.
	
	// Note that for maximum portability, libraries that are not jQuery should
	// declare themselves as anonymous modules, and avoid setting a global if an
	// AMD loader is present. jQuery is a special case. For more information, see
	// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
	
	if ( true ) {
		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
			return jQuery;
		}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	}
	
	
	
	var
	
		// Map over jQuery in case of overwrite
		_jQuery = window.jQuery,
	
		// Map over the $ in case of overwrite
		_$ = window.$;
	
	jQuery.noConflict = function( deep ) {
		if ( window.$ === jQuery ) {
			window.$ = _$;
		}
	
		if ( deep && window.jQuery === jQuery ) {
			window.jQuery = _jQuery;
		}
	
		return jQuery;
	};
	
	// Expose jQuery and $ identifiers, even in AMD
	// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
	// and CommonJS for browser emulators (#13566)
	if ( !noGlobal ) {
		window.jQuery = window.$ = jQuery;
	}
	
	return jQuery;
	}));
	
})
/** END DEFINE BLOCK for jquery@2.2.4/dist/jquery.js **/


/** START DEFINE BLOCK for jquery@3.2.1/dist/jquery.js **/
jupyter.define('jquery@3.2.1/dist/jquery.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery JavaScript Library v3.2.1
	 * https://jquery.com/
	 *
	 * Includes Sizzle.js
	 * https://sizzlejs.com/
	 *
	 * Copyright JS Foundation and other contributors
	 * Released under the MIT license
	 * https://jquery.org/license
	 *
	 * Date: 2017-03-20T18:59Z
	 */
	( function( global, factory ) {
	
		"use strict";
	
		if ( typeof module === "object" && typeof module.exports === "object" ) {
	
			// For CommonJS and CommonJS-like environments where a proper `window`
			// is present, execute the factory and get jQuery.
			// For environments that do not have a `window` with a `document`
			// (such as Node.js), expose a factory as module.exports.
			// This accentuates the need for the creation of a real `window`.
			// e.g. var jQuery = require("jquery")(window);
			// See ticket #14549 for more info.
			module.exports = global.document ?
				factory( global, true ) :
				function( w ) {
					if ( !w.document ) {
						throw new Error( "jQuery requires a window with a document" );
					}
					return factory( w );
				};
		} else {
			factory( global );
		}
	
	// Pass this if window is not defined yet
	} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
	
	// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
	// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
	// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
	// enough that all such attempts are guarded in a try block.
	"use strict";
	
	var arr = [];
	
	var document = window.document;
	
	var getProto = Object.getPrototypeOf;
	
	var slice = arr.slice;
	
	var concat = arr.concat;
	
	var push = arr.push;
	
	var indexOf = arr.indexOf;
	
	var class2type = {};
	
	var toString = class2type.toString;
	
	var hasOwn = class2type.hasOwnProperty;
	
	var fnToString = hasOwn.toString;
	
	var ObjectFunctionString = fnToString.call( Object );
	
	var support = {};
	
	
	
		function DOMEval( code, doc ) {
			doc = doc || document;
	
			var script = doc.createElement( "script" );
	
			script.text = code;
			doc.head.appendChild( script ).parentNode.removeChild( script );
		}
	/* global Symbol */
	// Defining this global in .eslintrc.json would create a danger of using the global
	// unguarded in another place, it seems safer to define global only for this module
	
	
	
	var
		version = "3.2.1",
	
		// Define a local copy of jQuery
		jQuery = function( selector, context ) {
	
			// The jQuery object is actually just the init constructor 'enhanced'
			// Need init if jQuery is called (just allow error to be thrown if not included)
			return new jQuery.fn.init( selector, context );
		},
	
		// Support: Android <=4.0 only
		// Make sure we trim BOM and NBSP
		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
	
		// Matches dashed string for camelizing
		rmsPrefix = /^-ms-/,
		rdashAlpha = /-([a-z])/g,
	
		// Used by jQuery.camelCase as callback to replace()
		fcamelCase = function( all, letter ) {
			return letter.toUpperCase();
		};
	
	jQuery.fn = jQuery.prototype = {
	
		// The current version of jQuery being used
		jquery: version,
	
		constructor: jQuery,
	
		// The default length of a jQuery object is 0
		length: 0,
	
		toArray: function() {
			return slice.call( this );
		},
	
		// Get the Nth element in the matched element set OR
		// Get the whole matched element set as a clean array
		get: function( num ) {
	
			// Return all the elements in a clean array
			if ( num == null ) {
				return slice.call( this );
			}
	
			// Return just the one element from the set
			return num < 0 ? this[ num + this.length ] : this[ num ];
		},
	
		// Take an array of elements and push it onto the stack
		// (returning the new matched element set)
		pushStack: function( elems ) {
	
			// Build a new jQuery matched element set
			var ret = jQuery.merge( this.constructor(), elems );
	
			// Add the old object onto the stack (as a reference)
			ret.prevObject = this;
	
			// Return the newly-formed element set
			return ret;
		},
	
		// Execute a callback for every element in the matched set.
		each: function( callback ) {
			return jQuery.each( this, callback );
		},
	
		map: function( callback ) {
			return this.pushStack( jQuery.map( this, function( elem, i ) {
				return callback.call( elem, i, elem );
			} ) );
		},
	
		slice: function() {
			return this.pushStack( slice.apply( this, arguments ) );
		},
	
		first: function() {
			return this.eq( 0 );
		},
	
		last: function() {
			return this.eq( -1 );
		},
	
		eq: function( i ) {
			var len = this.length,
				j = +i + ( i < 0 ? len : 0 );
			return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
		},
	
		end: function() {
			return this.prevObject || this.constructor();
		},
	
		// For internal use only.
		// Behaves like an Array's method, not like a jQuery method.
		push: push,
		sort: arr.sort,
		splice: arr.splice
	};
	
	jQuery.extend = jQuery.fn.extend = function() {
		var options, name, src, copy, copyIsArray, clone,
			target = arguments[ 0 ] || {},
			i = 1,
			length = arguments.length,
			deep = false;
	
		// Handle a deep copy situation
		if ( typeof target === "boolean" ) {
			deep = target;
	
			// Skip the boolean and the target
			target = arguments[ i ] || {};
			i++;
		}
	
		// Handle case when target is a string or something (possible in deep copy)
		if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
			target = {};
		}
	
		// Extend jQuery itself if only one argument is passed
		if ( i === length ) {
			target = this;
			i--;
		}
	
		for ( ; i < length; i++ ) {
	
			// Only deal with non-null/undefined values
			if ( ( options = arguments[ i ] ) != null ) {
	
				// Extend the base object
				for ( name in options ) {
					src = target[ name ];
					copy = options[ name ];
	
					// Prevent never-ending loop
					if ( target === copy ) {
						continue;
					}
	
					// Recurse if we're merging plain objects or arrays
					if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
						( copyIsArray = Array.isArray( copy ) ) ) ) {
	
						if ( copyIsArray ) {
							copyIsArray = false;
							clone = src && Array.isArray( src ) ? src : [];
	
						} else {
							clone = src && jQuery.isPlainObject( src ) ? src : {};
						}
	
						// Never move original objects, clone them
						target[ name ] = jQuery.extend( deep, clone, copy );
	
					// Don't bring in undefined values
					} else if ( copy !== undefined ) {
						target[ name ] = copy;
					}
				}
			}
		}
	
		// Return the modified object
		return target;
	};
	
	jQuery.extend( {
	
		// Unique for each copy of jQuery on the page
		expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
	
		// Assume jQuery is ready without the ready module
		isReady: true,
	
		error: function( msg ) {
			throw new Error( msg );
		},
	
		noop: function() {},
	
		isFunction: function( obj ) {
			return jQuery.type( obj ) === "function";
		},
	
		isWindow: function( obj ) {
			return obj != null && obj === obj.window;
		},
	
		isNumeric: function( obj ) {
	
			// As of jQuery 3.0, isNumeric is limited to
			// strings and numbers (primitives or objects)
			// that can be coerced to finite numbers (gh-2662)
			var type = jQuery.type( obj );
			return ( type === "number" || type === "string" ) &&
	
				// parseFloat NaNs numeric-cast false positives ("")
				// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
				// subtraction forces infinities to NaN
				!isNaN( obj - parseFloat( obj ) );
		},
	
		isPlainObject: function( obj ) {
			var proto, Ctor;
	
			// Detect obvious negatives
			// Use toString instead of jQuery.type to catch host objects
			if ( !obj || toString.call( obj ) !== "[object Object]" ) {
				return false;
			}
	
			proto = getProto( obj );
	
			// Objects with no prototype (e.g., `Object.create( null )`) are plain
			if ( !proto ) {
				return true;
			}
	
			// Objects with prototype are plain iff they were constructed by a global Object function
			Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
			return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
		},
	
		isEmptyObject: function( obj ) {
	
			/* eslint-disable no-unused-vars */
			// See https://github.com/eslint/eslint/issues/6125
			var name;
	
			for ( name in obj ) {
				return false;
			}
			return true;
		},
	
		type: function( obj ) {
			if ( obj == null ) {
				return obj + "";
			}
	
			// Support: Android <=2.3 only (functionish RegExp)
			return typeof obj === "object" || typeof obj === "function" ?
				class2type[ toString.call( obj ) ] || "object" :
				typeof obj;
		},
	
		// Evaluates a script in a global context
		globalEval: function( code ) {
			DOMEval( code );
		},
	
		// Convert dashed to camelCase; used by the css and data modules
		// Support: IE <=9 - 11, Edge 12 - 13
		// Microsoft forgot to hump their vendor prefix (#9572)
		camelCase: function( string ) {
			return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
		},
	
		each: function( obj, callback ) {
			var length, i = 0;
	
			if ( isArrayLike( obj ) ) {
				length = obj.length;
				for ( ; i < length; i++ ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			}
	
			return obj;
		},
	
		// Support: Android <=4.0 only
		trim: function( text ) {
			return text == null ?
				"" :
				( text + "" ).replace( rtrim, "" );
		},
	
		// results is for internal usage only
		makeArray: function( arr, results ) {
			var ret = results || [];
	
			if ( arr != null ) {
				if ( isArrayLike( Object( arr ) ) ) {
					jQuery.merge( ret,
						typeof arr === "string" ?
						[ arr ] : arr
					);
				} else {
					push.call( ret, arr );
				}
			}
	
			return ret;
		},
	
		inArray: function( elem, arr, i ) {
			return arr == null ? -1 : indexOf.call( arr, elem, i );
		},
	
		// Support: Android <=4.0 only, PhantomJS 1 only
		// push.apply(_, arraylike) throws on ancient WebKit
		merge: function( first, second ) {
			var len = +second.length,
				j = 0,
				i = first.length;
	
			for ( ; j < len; j++ ) {
				first[ i++ ] = second[ j ];
			}
	
			first.length = i;
	
			return first;
		},
	
		grep: function( elems, callback, invert ) {
			var callbackInverse,
				matches = [],
				i = 0,
				length = elems.length,
				callbackExpect = !invert;
	
			// Go through the array, only saving the items
			// that pass the validator function
			for ( ; i < length; i++ ) {
				callbackInverse = !callback( elems[ i ], i );
				if ( callbackInverse !== callbackExpect ) {
					matches.push( elems[ i ] );
				}
			}
	
			return matches;
		},
	
		// arg is for internal usage only
		map: function( elems, callback, arg ) {
			var length, value,
				i = 0,
				ret = [];
	
			// Go through the array, translating each of the items to their new values
			if ( isArrayLike( elems ) ) {
				length = elems.length;
				for ( ; i < length; i++ ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
	
			// Go through every key on the object,
			} else {
				for ( i in elems ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
			}
	
			// Flatten any nested arrays
			return concat.apply( [], ret );
		},
	
		// A global GUID counter for objects
		guid: 1,
	
		// Bind a function to a context, optionally partially applying any
		// arguments.
		proxy: function( fn, context ) {
			var tmp, args, proxy;
	
			if ( typeof context === "string" ) {
				tmp = fn[ context ];
				context = fn;
				fn = tmp;
			}
	
			// Quick check to determine if target is callable, in the spec
			// this throws a TypeError, but we will just return undefined.
			if ( !jQuery.isFunction( fn ) ) {
				return undefined;
			}
	
			// Simulated bind
			args = slice.call( arguments, 2 );
			proxy = function() {
				return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
			};
	
			// Set the guid of unique handler to the same of original handler, so it can be removed
			proxy.guid = fn.guid = fn.guid || jQuery.guid++;
	
			return proxy;
		},
	
		now: Date.now,
	
		// jQuery.support is not used in Core but other projects attach their
		// properties to it so it needs to exist.
		support: support
	} );
	
	if ( typeof Symbol === "function" ) {
		jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
	}
	
	// Populate the class2type map
	jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
	function( i, name ) {
		class2type[ "[object " + name + "]" ] = name.toLowerCase();
	} );
	
	function isArrayLike( obj ) {
	
		// Support: real iOS 8.2 only (not reproducible in simulator)
		// `in` check used to prevent JIT error (gh-2145)
		// hasOwn isn't used here due to false negatives
		// regarding Nodelist length in IE
		var length = !!obj && "length" in obj && obj.length,
			type = jQuery.type( obj );
	
		if ( type === "function" || jQuery.isWindow( obj ) ) {
			return false;
		}
	
		return type === "array" || length === 0 ||
			typeof length === "number" && length > 0 && ( length - 1 ) in obj;
	}
	var Sizzle =
	/*!
	 * Sizzle CSS Selector Engine v2.3.3
	 * https://sizzlejs.com/
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license
	 * http://jquery.org/license
	 *
	 * Date: 2016-08-08
	 */
	(function( window ) {
	
	var i,
		support,
		Expr,
		getText,
		isXML,
		tokenize,
		compile,
		select,
		outermostContext,
		sortInput,
		hasDuplicate,
	
		// Local document vars
		setDocument,
		document,
		docElem,
		documentIsHTML,
		rbuggyQSA,
		rbuggyMatches,
		matches,
		contains,
	
		// Instance-specific data
		expando = "sizzle" + 1 * new Date(),
		preferredDoc = window.document,
		dirruns = 0,
		done = 0,
		classCache = createCache(),
		tokenCache = createCache(),
		compilerCache = createCache(),
		sortOrder = function( a, b ) {
			if ( a === b ) {
				hasDuplicate = true;
			}
			return 0;
		},
	
		// Instance methods
		hasOwn = ({}).hasOwnProperty,
		arr = [],
		pop = arr.pop,
		push_native = arr.push,
		push = arr.push,
		slice = arr.slice,
		// Use a stripped-down indexOf as it's faster than native
		// https://jsperf.com/thor-indexof-vs-for/5
		indexOf = function( list, elem ) {
			var i = 0,
				len = list.length;
			for ( ; i < len; i++ ) {
				if ( list[i] === elem ) {
					return i;
				}
			}
			return -1;
		},
	
		booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
	
		// Regular expressions
	
		// http://www.w3.org/TR/css3-selectors/#whitespace
		whitespace = "[\\x20\\t\\r\\n\\f]",
	
		// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
		identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
	
		// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
		attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
			// Operator (capture 2)
			"*([*^$|!~]?=)" + whitespace +
			// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
			"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
			"*\\]",
	
		pseudos = ":(" + identifier + ")(?:\\((" +
			// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
			// 1. quoted (capture 3; capture 4 or capture 5)
			"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
			// 2. simple (capture 6)
			"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
			// 3. anything else (capture 2)
			".*" +
			")\\)|)",
	
		// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
		rwhitespace = new RegExp( whitespace + "+", "g" ),
		rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
	
		rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
		rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
	
		rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
	
		rpseudo = new RegExp( pseudos ),
		ridentifier = new RegExp( "^" + identifier + "$" ),
	
		matchExpr = {
			"ID": new RegExp( "^#(" + identifier + ")" ),
			"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
			"TAG": new RegExp( "^(" + identifier + "|[*])" ),
			"ATTR": new RegExp( "^" + attributes ),
			"PSEUDO": new RegExp( "^" + pseudos ),
			"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
				"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
				"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
			"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
			// For use in libraries implementing .is()
			// We use this for POS matching in `select`
			"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
				whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
		},
	
		rinputs = /^(?:input|select|textarea|button)$/i,
		rheader = /^h\d$/i,
	
		rnative = /^[^{]+\{\s*\[native \w/,
	
		// Easily-parseable/retrievable ID or TAG or CLASS selectors
		rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
	
		rsibling = /[+~]/,
	
		// CSS escapes
		// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
		runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
		funescape = function( _, escaped, escapedWhitespace ) {
			var high = "0x" + escaped - 0x10000;
			// NaN means non-codepoint
			// Support: Firefox<24
			// Workaround erroneous numeric interpretation of +"0x"
			return high !== high || escapedWhitespace ?
				escaped :
				high < 0 ?
					// BMP codepoint
					String.fromCharCode( high + 0x10000 ) :
					// Supplemental Plane codepoint (surrogate pair)
					String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
		},
	
		// CSS string/identifier serialization
		// https://drafts.csswg.org/cssom/#common-serializing-idioms
		rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
		fcssescape = function( ch, asCodePoint ) {
			if ( asCodePoint ) {
	
				// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
				if ( ch === "\0" ) {
					return "\uFFFD";
				}
	
				// Control characters and (dependent upon position) numbers get escaped as code points
				return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
			}
	
			// Other potentially-special ASCII characters get backslash-escaped
			return "\\" + ch;
		},
	
		// Used for iframes
		// See setDocument()
		// Removing the function wrapper causes a "Permission Denied"
		// error in IE
		unloadHandler = function() {
			setDocument();
		},
	
		disabledAncestor = addCombinator(
			function( elem ) {
				return elem.disabled === true && ("form" in elem || "label" in elem);
			},
			{ dir: "parentNode", next: "legend" }
		);
	
	// Optimize for push.apply( _, NodeList )
	try {
		push.apply(
			(arr = slice.call( preferredDoc.childNodes )),
			preferredDoc.childNodes
		);
		// Support: Android<4.0
		// Detect silently failing push.apply
		arr[ preferredDoc.childNodes.length ].nodeType;
	} catch ( e ) {
		push = { apply: arr.length ?
	
			// Leverage slice if possible
			function( target, els ) {
				push_native.apply( target, slice.call(els) );
			} :
	
			// Support: IE<9
			// Otherwise append directly
			function( target, els ) {
				var j = target.length,
					i = 0;
				// Can't trust NodeList.length
				while ( (target[j++] = els[i++]) ) {}
				target.length = j - 1;
			}
		};
	}
	
	function Sizzle( selector, context, results, seed ) {
		var m, i, elem, nid, match, groups, newSelector,
			newContext = context && context.ownerDocument,
	
			// nodeType defaults to 9, since context defaults to document
			nodeType = context ? context.nodeType : 9;
	
		results = results || [];
	
		// Return early from calls with invalid selector or context
		if ( typeof selector !== "string" || !selector ||
			nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
	
			return results;
		}
	
		// Try to shortcut find operations (as opposed to filters) in HTML documents
		if ( !seed ) {
	
			if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
				setDocument( context );
			}
			context = context || document;
	
			if ( documentIsHTML ) {
	
				// If the selector is sufficiently simple, try using a "get*By*" DOM method
				// (excepting DocumentFragment context, where the methods don't exist)
				if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
	
					// ID selector
					if ( (m = match[1]) ) {
	
						// Document context
						if ( nodeType === 9 ) {
							if ( (elem = context.getElementById( m )) ) {
	
								// Support: IE, Opera, Webkit
								// TODO: identify versions
								// getElementById can match elements by name instead of ID
								if ( elem.id === m ) {
									results.push( elem );
									return results;
								}
							} else {
								return results;
							}
	
						// Element context
						} else {
	
							// Support: IE, Opera, Webkit
							// TODO: identify versions
							// getElementById can match elements by name instead of ID
							if ( newContext && (elem = newContext.getElementById( m )) &&
								contains( context, elem ) &&
								elem.id === m ) {
	
								results.push( elem );
								return results;
							}
						}
	
					// Type selector
					} else if ( match[2] ) {
						push.apply( results, context.getElementsByTagName( selector ) );
						return results;
	
					// Class selector
					} else if ( (m = match[3]) && support.getElementsByClassName &&
						context.getElementsByClassName ) {
	
						push.apply( results, context.getElementsByClassName( m ) );
						return results;
					}
				}
	
				// Take advantage of querySelectorAll
				if ( support.qsa &&
					!compilerCache[ selector + " " ] &&
					(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
	
					if ( nodeType !== 1 ) {
						newContext = context;
						newSelector = selector;
	
					// qSA looks outside Element context, which is not what we want
					// Thanks to Andrew Dupont for this workaround technique
					// Support: IE <=8
					// Exclude object elements
					} else if ( context.nodeName.toLowerCase() !== "object" ) {
	
						// Capture the context ID, setting it first if necessary
						if ( (nid = context.getAttribute( "id" )) ) {
							nid = nid.replace( rcssescape, fcssescape );
						} else {
							context.setAttribute( "id", (nid = expando) );
						}
	
						// Prefix every selector in the list
						groups = tokenize( selector );
						i = groups.length;
						while ( i-- ) {
							groups[i] = "#" + nid + " " + toSelector( groups[i] );
						}
						newSelector = groups.join( "," );
	
						// Expand context for sibling selectors
						newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
							context;
					}
	
					if ( newSelector ) {
						try {
							push.apply( results,
								newContext.querySelectorAll( newSelector )
							);
							return results;
						} catch ( qsaError ) {
						} finally {
							if ( nid === expando ) {
								context.removeAttribute( "id" );
							}
						}
					}
				}
			}
		}
	
		// All others
		return select( selector.replace( rtrim, "$1" ), context, results, seed );
	}
	
	/**
	 * Create key-value caches of limited size
	 * @returns {function(string, object)} Returns the Object data after storing it on itself with
	 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
	 *	deleting the oldest entry
	 */
	function createCache() {
		var keys = [];
	
		function cache( key, value ) {
			// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
			if ( keys.push( key + " " ) > Expr.cacheLength ) {
				// Only keep the most recent entries
				delete cache[ keys.shift() ];
			}
			return (cache[ key + " " ] = value);
		}
		return cache;
	}
	
	/**
	 * Mark a function for special use by Sizzle
	 * @param {Function} fn The function to mark
	 */
	function markFunction( fn ) {
		fn[ expando ] = true;
		return fn;
	}
	
	/**
	 * Support testing using an element
	 * @param {Function} fn Passed the created element and returns a boolean result
	 */
	function assert( fn ) {
		var el = document.createElement("fieldset");
	
		try {
			return !!fn( el );
		} catch (e) {
			return false;
		} finally {
			// Remove from its parent by default
			if ( el.parentNode ) {
				el.parentNode.removeChild( el );
			}
			// release memory in IE
			el = null;
		}
	}
	
	/**
	 * Adds the same handler for all of the specified attrs
	 * @param {String} attrs Pipe-separated list of attributes
	 * @param {Function} handler The method that will be applied
	 */
	function addHandle( attrs, handler ) {
		var arr = attrs.split("|"),
			i = arr.length;
	
		while ( i-- ) {
			Expr.attrHandle[ arr[i] ] = handler;
		}
	}
	
	/**
	 * Checks document order of two siblings
	 * @param {Element} a
	 * @param {Element} b
	 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
	 */
	function siblingCheck( a, b ) {
		var cur = b && a,
			diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
				a.sourceIndex - b.sourceIndex;
	
		// Use IE sourceIndex if available on both nodes
		if ( diff ) {
			return diff;
		}
	
		// Check if b follows a
		if ( cur ) {
			while ( (cur = cur.nextSibling) ) {
				if ( cur === b ) {
					return -1;
				}
			}
		}
	
		return a ? 1 : -1;
	}
	
	/**
	 * Returns a function to use in pseudos for input types
	 * @param {String} type
	 */
	function createInputPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return name === "input" && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for buttons
	 * @param {String} type
	 */
	function createButtonPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return (name === "input" || name === "button") && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for :enabled/:disabled
	 * @param {Boolean} disabled true for :disabled; false for :enabled
	 */
	function createDisabledPseudo( disabled ) {
	
		// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
		return function( elem ) {
	
			// Only certain elements can match :enabled or :disabled
			// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
			// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
			if ( "form" in elem ) {
	
				// Check for inherited disabledness on relevant non-disabled elements:
				// * listed form-associated elements in a disabled fieldset
				//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
				//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
				// * option elements in a disabled optgroup
				//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
				// All such elements have a "form" property.
				if ( elem.parentNode && elem.disabled === false ) {
	
					// Option elements defer to a parent optgroup if present
					if ( "label" in elem ) {
						if ( "label" in elem.parentNode ) {
							return elem.parentNode.disabled === disabled;
						} else {
							return elem.disabled === disabled;
						}
					}
	
					// Support: IE 6 - 11
					// Use the isDisabled shortcut property to check for disabled fieldset ancestors
					return elem.isDisabled === disabled ||
	
						// Where there is no isDisabled, check manually
						/* jshint -W018 */
						elem.isDisabled !== !disabled &&
							disabledAncestor( elem ) === disabled;
				}
	
				return elem.disabled === disabled;
	
			// Try to winnow out elements that can't be disabled before trusting the disabled property.
			// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
			// even exist on them, let alone have a boolean value.
			} else if ( "label" in elem ) {
				return elem.disabled === disabled;
			}
	
			// Remaining elements are neither :enabled nor :disabled
			return false;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for positionals
	 * @param {Function} fn
	 */
	function createPositionalPseudo( fn ) {
		return markFunction(function( argument ) {
			argument = +argument;
			return markFunction(function( seed, matches ) {
				var j,
					matchIndexes = fn( [], seed.length, argument ),
					i = matchIndexes.length;
	
				// Match elements found at the specified indexes
				while ( i-- ) {
					if ( seed[ (j = matchIndexes[i]) ] ) {
						seed[j] = !(matches[j] = seed[j]);
					}
				}
			});
		});
	}
	
	/**
	 * Checks a node for validity as a Sizzle context
	 * @param {Element|Object=} context
	 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
	 */
	function testContext( context ) {
		return context && typeof context.getElementsByTagName !== "undefined" && context;
	}
	
	// Expose support vars for convenience
	support = Sizzle.support = {};
	
	/**
	 * Detects XML nodes
	 * @param {Element|Object} elem An element or a document
	 * @returns {Boolean} True iff elem is a non-HTML XML node
	 */
	isXML = Sizzle.isXML = function( elem ) {
		// documentElement is verified for cases where it doesn't yet exist
		// (such as loading iframes in IE - #4833)
		var documentElement = elem && (elem.ownerDocument || elem).documentElement;
		return documentElement ? documentElement.nodeName !== "HTML" : false;
	};
	
	/**
	 * Sets document-related variables once based on the current document
	 * @param {Element|Object} [doc] An element or document object to use to set the document
	 * @returns {Object} Returns the current document
	 */
	setDocument = Sizzle.setDocument = function( node ) {
		var hasCompare, subWindow,
			doc = node ? node.ownerDocument || node : preferredDoc;
	
		// Return early if doc is invalid or already selected
		if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
			return document;
		}
	
		// Update global variables
		document = doc;
		docElem = document.documentElement;
		documentIsHTML = !isXML( document );
	
		// Support: IE 9-11, Edge
		// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
		if ( preferredDoc !== document &&
			(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
	
			// Support: IE 11, Edge
			if ( subWindow.addEventListener ) {
				subWindow.addEventListener( "unload", unloadHandler, false );
	
			// Support: IE 9 - 10 only
			} else if ( subWindow.attachEvent ) {
				subWindow.attachEvent( "onunload", unloadHandler );
			}
		}
	
		/* Attributes
		---------------------------------------------------------------------- */
	
		// Support: IE<8
		// Verify that getAttribute really returns attributes and not properties
		// (excepting IE8 booleans)
		support.attributes = assert(function( el ) {
			el.className = "i";
			return !el.getAttribute("className");
		});
	
		/* getElement(s)By*
		---------------------------------------------------------------------- */
	
		// Check if getElementsByTagName("*") returns only elements
		support.getElementsByTagName = assert(function( el ) {
			el.appendChild( document.createComment("") );
			return !el.getElementsByTagName("*").length;
		});
	
		// Support: IE<9
		support.getElementsByClassName = rnative.test( document.getElementsByClassName );
	
		// Support: IE<10
		// Check if getElementById returns elements by name
		// The broken getElementById methods don't pick up programmatically-set names,
		// so use a roundabout getElementsByName test
		support.getById = assert(function( el ) {
			docElem.appendChild( el ).id = expando;
			return !document.getElementsByName || !document.getElementsByName( expando ).length;
		});
	
		// ID filter and find
		if ( support.getById ) {
			Expr.filter["ID"] = function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					return elem.getAttribute("id") === attrId;
				};
			};
			Expr.find["ID"] = function( id, context ) {
				if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
					var elem = context.getElementById( id );
					return elem ? [ elem ] : [];
				}
			};
		} else {
			Expr.filter["ID"] =  function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					var node = typeof elem.getAttributeNode !== "undefined" &&
						elem.getAttributeNode("id");
					return node && node.value === attrId;
				};
			};
	
			// Support: IE 6 - 7 only
			// getElementById is not reliable as a find shortcut
			Expr.find["ID"] = function( id, context ) {
				if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
					var node, i, elems,
						elem = context.getElementById( id );
	
					if ( elem ) {
	
						// Verify the id attribute
						node = elem.getAttributeNode("id");
						if ( node && node.value === id ) {
							return [ elem ];
						}
	
						// Fall back on getElementsByName
						elems = context.getElementsByName( id );
						i = 0;
						while ( (elem = elems[i++]) ) {
							node = elem.getAttributeNode("id");
							if ( node && node.value === id ) {
								return [ elem ];
							}
						}
					}
	
					return [];
				}
			};
		}
	
		// Tag
		Expr.find["TAG"] = support.getElementsByTagName ?
			function( tag, context ) {
				if ( typeof context.getElementsByTagName !== "undefined" ) {
					return context.getElementsByTagName( tag );
	
				// DocumentFragment nodes don't have gEBTN
				} else if ( support.qsa ) {
					return context.querySelectorAll( tag );
				}
			} :
	
			function( tag, context ) {
				var elem,
					tmp = [],
					i = 0,
					// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
					results = context.getElementsByTagName( tag );
	
				// Filter out possible comments
				if ( tag === "*" ) {
					while ( (elem = results[i++]) ) {
						if ( elem.nodeType === 1 ) {
							tmp.push( elem );
						}
					}
	
					return tmp;
				}
				return results;
			};
	
		// Class
		Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
			if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
				return context.getElementsByClassName( className );
			}
		};
	
		/* QSA/matchesSelector
		---------------------------------------------------------------------- */
	
		// QSA and matchesSelector support
	
		// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
		rbuggyMatches = [];
	
		// qSa(:focus) reports false when true (Chrome 21)
		// We allow this because of a bug in IE8/9 that throws an error
		// whenever `document.activeElement` is accessed on an iframe
		// So, we allow :focus to pass through QSA all the time to avoid the IE error
		// See https://bugs.jquery.com/ticket/13378
		rbuggyQSA = [];
	
		if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
			// Build QSA regex
			// Regex strategy adopted from Diego Perini
			assert(function( el ) {
				// Select is set to empty string on purpose
				// This is to test IE's treatment of not explicitly
				// setting a boolean content attribute,
				// since its presence should be enough
				// https://bugs.jquery.com/ticket/12359
				docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
					"<select id='" + expando + "-\r\\' msallowcapture=''>" +
					"<option selected=''></option></select>";
	
				// Support: IE8, Opera 11-12.16
				// Nothing should be selected when empty strings follow ^= or $= or *=
				// The test attribute must be unknown in Opera but "safe" for WinRT
				// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
				if ( el.querySelectorAll("[msallowcapture^='']").length ) {
					rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
				}
	
				// Support: IE8
				// Boolean attributes and "value" are not treated correctly
				if ( !el.querySelectorAll("[selected]").length ) {
					rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
				}
	
				// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
				if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
					rbuggyQSA.push("~=");
				}
	
				// Webkit/Opera - :checked should return selected option elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				// IE8 throws error here and will not see later tests
				if ( !el.querySelectorAll(":checked").length ) {
					rbuggyQSA.push(":checked");
				}
	
				// Support: Safari 8+, iOS 8+
				// https://bugs.webkit.org/show_bug.cgi?id=136851
				// In-page `selector#id sibling-combinator selector` fails
				if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
					rbuggyQSA.push(".#.+[+~]");
				}
			});
	
			assert(function( el ) {
				el.innerHTML = "<a href='' disabled='disabled'></a>" +
					"<select disabled='disabled'><option/></select>";
	
				// Support: Windows 8 Native Apps
				// The type and name attributes are restricted during .innerHTML assignment
				var input = document.createElement("input");
				input.setAttribute( "type", "hidden" );
				el.appendChild( input ).setAttribute( "name", "D" );
	
				// Support: IE8
				// Enforce case-sensitivity of name attribute
				if ( el.querySelectorAll("[name=d]").length ) {
					rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
				}
	
				// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
				// IE8 throws error here and will not see later tests
				if ( el.querySelectorAll(":enabled").length !== 2 ) {
					rbuggyQSA.push( ":enabled", ":disabled" );
				}
	
				// Support: IE9-11+
				// IE's :disabled selector does not pick up the children of disabled fieldsets
				docElem.appendChild( el ).disabled = true;
				if ( el.querySelectorAll(":disabled").length !== 2 ) {
					rbuggyQSA.push( ":enabled", ":disabled" );
				}
	
				// Opera 10-11 does not throw on post-comma invalid pseudos
				el.querySelectorAll("*,:x");
				rbuggyQSA.push(",.*:");
			});
		}
	
		if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
			docElem.webkitMatchesSelector ||
			docElem.mozMatchesSelector ||
			docElem.oMatchesSelector ||
			docElem.msMatchesSelector) )) ) {
	
			assert(function( el ) {
				// Check to see if it's possible to do matchesSelector
				// on a disconnected node (IE 9)
				support.disconnectedMatch = matches.call( el, "*" );
	
				// This should fail with an exception
				// Gecko does not error, returns false instead
				matches.call( el, "[s!='']:x" );
				rbuggyMatches.push( "!=", pseudos );
			});
		}
	
		rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
		rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
	
		/* Contains
		---------------------------------------------------------------------- */
		hasCompare = rnative.test( docElem.compareDocumentPosition );
	
		// Element contains another
		// Purposefully self-exclusive
		// As in, an element does not contain itself
		contains = hasCompare || rnative.test( docElem.contains ) ?
			function( a, b ) {
				var adown = a.nodeType === 9 ? a.documentElement : a,
					bup = b && b.parentNode;
				return a === bup || !!( bup && bup.nodeType === 1 && (
					adown.contains ?
						adown.contains( bup ) :
						a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
				));
			} :
			function( a, b ) {
				if ( b ) {
					while ( (b = b.parentNode) ) {
						if ( b === a ) {
							return true;
						}
					}
				}
				return false;
			};
	
		/* Sorting
		---------------------------------------------------------------------- */
	
		// Document order sorting
		sortOrder = hasCompare ?
		function( a, b ) {
	
			// Flag for duplicate removal
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			// Sort on method existence if only one input has compareDocumentPosition
			var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
			if ( compare ) {
				return compare;
			}
	
			// Calculate position if both inputs belong to the same document
			compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
				a.compareDocumentPosition( b ) :
	
				// Otherwise we know they are disconnected
				1;
	
			// Disconnected nodes
			if ( compare & 1 ||
				(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
	
				// Choose the first element that is related to our preferred document
				if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
					return -1;
				}
				if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
					return 1;
				}
	
				// Maintain original order
				return sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
			}
	
			return compare & 4 ? -1 : 1;
		} :
		function( a, b ) {
			// Exit early if the nodes are identical
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			var cur,
				i = 0,
				aup = a.parentNode,
				bup = b.parentNode,
				ap = [ a ],
				bp = [ b ];
	
			// Parentless nodes are either documents or disconnected
			if ( !aup || !bup ) {
				return a === document ? -1 :
					b === document ? 1 :
					aup ? -1 :
					bup ? 1 :
					sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
	
			// If the nodes are siblings, we can do a quick check
			} else if ( aup === bup ) {
				return siblingCheck( a, b );
			}
	
			// Otherwise we need full lists of their ancestors for comparison
			cur = a;
			while ( (cur = cur.parentNode) ) {
				ap.unshift( cur );
			}
			cur = b;
			while ( (cur = cur.parentNode) ) {
				bp.unshift( cur );
			}
	
			// Walk down the tree looking for a discrepancy
			while ( ap[i] === bp[i] ) {
				i++;
			}
	
			return i ?
				// Do a sibling check if the nodes have a common ancestor
				siblingCheck( ap[i], bp[i] ) :
	
				// Otherwise nodes in our document sort first
				ap[i] === preferredDoc ? -1 :
				bp[i] === preferredDoc ? 1 :
				0;
		};
	
		return document;
	};
	
	Sizzle.matches = function( expr, elements ) {
		return Sizzle( expr, null, null, elements );
	};
	
	Sizzle.matchesSelector = function( elem, expr ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		// Make sure that attribute selectors are quoted
		expr = expr.replace( rattributeQuotes, "='$1']" );
	
		if ( support.matchesSelector && documentIsHTML &&
			!compilerCache[ expr + " " ] &&
			( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
			( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
	
			try {
				var ret = matches.call( elem, expr );
	
				// IE 9's matchesSelector returns false on disconnected nodes
				if ( ret || support.disconnectedMatch ||
						// As well, disconnected nodes are said to be in a document
						// fragment in IE 9
						elem.document && elem.document.nodeType !== 11 ) {
					return ret;
				}
			} catch (e) {}
		}
	
		return Sizzle( expr, document, null, [ elem ] ).length > 0;
	};
	
	Sizzle.contains = function( context, elem ) {
		// Set document vars if needed
		if ( ( context.ownerDocument || context ) !== document ) {
			setDocument( context );
		}
		return contains( context, elem );
	};
	
	Sizzle.attr = function( elem, name ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		var fn = Expr.attrHandle[ name.toLowerCase() ],
			// Don't get fooled by Object.prototype properties (jQuery #13807)
			val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
				fn( elem, name, !documentIsHTML ) :
				undefined;
	
		return val !== undefined ?
			val :
			support.attributes || !documentIsHTML ?
				elem.getAttribute( name ) :
				(val = elem.getAttributeNode(name)) && val.specified ?
					val.value :
					null;
	};
	
	Sizzle.escape = function( sel ) {
		return (sel + "").replace( rcssescape, fcssescape );
	};
	
	Sizzle.error = function( msg ) {
		throw new Error( "Syntax error, unrecognized expression: " + msg );
	};
	
	/**
	 * Document sorting and removing duplicates
	 * @param {ArrayLike} results
	 */
	Sizzle.uniqueSort = function( results ) {
		var elem,
			duplicates = [],
			j = 0,
			i = 0;
	
		// Unless we *know* we can detect duplicates, assume their presence
		hasDuplicate = !support.detectDuplicates;
		sortInput = !support.sortStable && results.slice( 0 );
		results.sort( sortOrder );
	
		if ( hasDuplicate ) {
			while ( (elem = results[i++]) ) {
				if ( elem === results[ i ] ) {
					j = duplicates.push( i );
				}
			}
			while ( j-- ) {
				results.splice( duplicates[ j ], 1 );
			}
		}
	
		// Clear input after sorting to release objects
		// See https://github.com/jquery/sizzle/pull/225
		sortInput = null;
	
		return results;
	};
	
	/**
	 * Utility function for retrieving the text value of an array of DOM nodes
	 * @param {Array|Element} elem
	 */
	getText = Sizzle.getText = function( elem ) {
		var node,
			ret = "",
			i = 0,
			nodeType = elem.nodeType;
	
		if ( !nodeType ) {
			// If no nodeType, this is expected to be an array
			while ( (node = elem[i++]) ) {
				// Do not traverse comment nodes
				ret += getText( node );
			}
		} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
			// Use textContent for elements
			// innerText usage removed for consistency of new lines (jQuery #11153)
			if ( typeof elem.textContent === "string" ) {
				return elem.textContent;
			} else {
				// Traverse its children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					ret += getText( elem );
				}
			}
		} else if ( nodeType === 3 || nodeType === 4 ) {
			return elem.nodeValue;
		}
		// Do not include comment or processing instruction nodes
	
		return ret;
	};
	
	Expr = Sizzle.selectors = {
	
		// Can be adjusted by the user
		cacheLength: 50,
	
		createPseudo: markFunction,
	
		match: matchExpr,
	
		attrHandle: {},
	
		find: {},
	
		relative: {
			">": { dir: "parentNode", first: true },
			" ": { dir: "parentNode" },
			"+": { dir: "previousSibling", first: true },
			"~": { dir: "previousSibling" }
		},
	
		preFilter: {
			"ATTR": function( match ) {
				match[1] = match[1].replace( runescape, funescape );
	
				// Move the given value to match[3] whether quoted or unquoted
				match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
	
				if ( match[2] === "~=" ) {
					match[3] = " " + match[3] + " ";
				}
	
				return match.slice( 0, 4 );
			},
	
			"CHILD": function( match ) {
				/* matches from matchExpr["CHILD"]
					1 type (only|nth|...)
					2 what (child|of-type)
					3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
					4 xn-component of xn+y argument ([+-]?\d*n|)
					5 sign of xn-component
					6 x of xn-component
					7 sign of y-component
					8 y of y-component
				*/
				match[1] = match[1].toLowerCase();
	
				if ( match[1].slice( 0, 3 ) === "nth" ) {
					// nth-* requires argument
					if ( !match[3] ) {
						Sizzle.error( match[0] );
					}
	
					// numeric x and y parameters for Expr.filter.CHILD
					// remember that false/true cast respectively to 0/1
					match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
					match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
	
				// other types prohibit arguments
				} else if ( match[3] ) {
					Sizzle.error( match[0] );
				}
	
				return match;
			},
	
			"PSEUDO": function( match ) {
				var excess,
					unquoted = !match[6] && match[2];
	
				if ( matchExpr["CHILD"].test( match[0] ) ) {
					return null;
				}
	
				// Accept quoted arguments as-is
				if ( match[3] ) {
					match[2] = match[4] || match[5] || "";
	
				// Strip excess characters from unquoted arguments
				} else if ( unquoted && rpseudo.test( unquoted ) &&
					// Get excess from tokenize (recursively)
					(excess = tokenize( unquoted, true )) &&
					// advance to the next closing parenthesis
					(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
	
					// excess is a negative index
					match[0] = match[0].slice( 0, excess );
					match[2] = unquoted.slice( 0, excess );
				}
	
				// Return only captures needed by the pseudo filter method (type and argument)
				return match.slice( 0, 3 );
			}
		},
	
		filter: {
	
			"TAG": function( nodeNameSelector ) {
				var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
				return nodeNameSelector === "*" ?
					function() { return true; } :
					function( elem ) {
						return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
					};
			},
	
			"CLASS": function( className ) {
				var pattern = classCache[ className + " " ];
	
				return pattern ||
					(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
					classCache( className, function( elem ) {
						return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
					});
			},
	
			"ATTR": function( name, operator, check ) {
				return function( elem ) {
					var result = Sizzle.attr( elem, name );
	
					if ( result == null ) {
						return operator === "!=";
					}
					if ( !operator ) {
						return true;
					}
	
					result += "";
	
					return operator === "=" ? result === check :
						operator === "!=" ? result !== check :
						operator === "^=" ? check && result.indexOf( check ) === 0 :
						operator === "*=" ? check && result.indexOf( check ) > -1 :
						operator === "$=" ? check && result.slice( -check.length ) === check :
						operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
						operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
						false;
				};
			},
	
			"CHILD": function( type, what, argument, first, last ) {
				var simple = type.slice( 0, 3 ) !== "nth",
					forward = type.slice( -4 ) !== "last",
					ofType = what === "of-type";
	
				return first === 1 && last === 0 ?
	
					// Shortcut for :nth-*(n)
					function( elem ) {
						return !!elem.parentNode;
					} :
	
					function( elem, context, xml ) {
						var cache, uniqueCache, outerCache, node, nodeIndex, start,
							dir = simple !== forward ? "nextSibling" : "previousSibling",
							parent = elem.parentNode,
							name = ofType && elem.nodeName.toLowerCase(),
							useCache = !xml && !ofType,
							diff = false;
	
						if ( parent ) {
	
							// :(first|last|only)-(child|of-type)
							if ( simple ) {
								while ( dir ) {
									node = elem;
									while ( (node = node[ dir ]) ) {
										if ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) {
	
											return false;
										}
									}
									// Reverse direction for :only-* (if we haven't yet done so)
									start = dir = type === "only" && !start && "nextSibling";
								}
								return true;
							}
	
							start = [ forward ? parent.firstChild : parent.lastChild ];
	
							// non-xml :nth-child(...) stores cache data on `parent`
							if ( forward && useCache ) {
	
								// Seek `elem` from a previously-cached index
	
								// ...in a gzip-friendly way
								node = parent;
								outerCache = node[ expando ] || (node[ expando ] = {});
	
								// Support: IE <9 only
								// Defend against cloned attroperties (jQuery gh-1709)
								uniqueCache = outerCache[ node.uniqueID ] ||
									(outerCache[ node.uniqueID ] = {});
	
								cache = uniqueCache[ type ] || [];
								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
								diff = nodeIndex && cache[ 2 ];
								node = nodeIndex && parent.childNodes[ nodeIndex ];
	
								while ( (node = ++nodeIndex && node && node[ dir ] ||
	
									// Fallback to seeking `elem` from the start
									(diff = nodeIndex = 0) || start.pop()) ) {
	
									// When found, cache indexes on `parent` and break
									if ( node.nodeType === 1 && ++diff && node === elem ) {
										uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
										break;
									}
								}
	
							} else {
								// Use previously-cached element index if available
								if ( useCache ) {
									// ...in a gzip-friendly way
									node = elem;
									outerCache = node[ expando ] || (node[ expando ] = {});
	
									// Support: IE <9 only
									// Defend against cloned attroperties (jQuery gh-1709)
									uniqueCache = outerCache[ node.uniqueID ] ||
										(outerCache[ node.uniqueID ] = {});
	
									cache = uniqueCache[ type ] || [];
									nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
									diff = nodeIndex;
								}
	
								// xml :nth-child(...)
								// or :nth-last-child(...) or :nth(-last)?-of-type(...)
								if ( diff === false ) {
									// Use the same loop as above to seek `elem` from the start
									while ( (node = ++nodeIndex && node && node[ dir ] ||
										(diff = nodeIndex = 0) || start.pop()) ) {
	
										if ( ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) &&
											++diff ) {
	
											// Cache the index of each encountered element
											if ( useCache ) {
												outerCache = node[ expando ] || (node[ expando ] = {});
	
												// Support: IE <9 only
												// Defend against cloned attroperties (jQuery gh-1709)
												uniqueCache = outerCache[ node.uniqueID ] ||
													(outerCache[ node.uniqueID ] = {});
	
												uniqueCache[ type ] = [ dirruns, diff ];
											}
	
											if ( node === elem ) {
												break;
											}
										}
									}
								}
							}
	
							// Incorporate the offset, then check against cycle size
							diff -= last;
							return diff === first || ( diff % first === 0 && diff / first >= 0 );
						}
					};
			},
	
			"PSEUDO": function( pseudo, argument ) {
				// pseudo-class names are case-insensitive
				// http://www.w3.org/TR/selectors/#pseudo-classes
				// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
				// Remember that setFilters inherits from pseudos
				var args,
					fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
						Sizzle.error( "unsupported pseudo: " + pseudo );
	
				// The user may use createPseudo to indicate that
				// arguments are needed to create the filter function
				// just as Sizzle does
				if ( fn[ expando ] ) {
					return fn( argument );
				}
	
				// But maintain support for old signatures
				if ( fn.length > 1 ) {
					args = [ pseudo, pseudo, "", argument ];
					return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
						markFunction(function( seed, matches ) {
							var idx,
								matched = fn( seed, argument ),
								i = matched.length;
							while ( i-- ) {
								idx = indexOf( seed, matched[i] );
								seed[ idx ] = !( matches[ idx ] = matched[i] );
							}
						}) :
						function( elem ) {
							return fn( elem, 0, args );
						};
				}
	
				return fn;
			}
		},
	
		pseudos: {
			// Potentially complex pseudos
			"not": markFunction(function( selector ) {
				// Trim the selector passed to compile
				// to avoid treating leading and trailing
				// spaces as combinators
				var input = [],
					results = [],
					matcher = compile( selector.replace( rtrim, "$1" ) );
	
				return matcher[ expando ] ?
					markFunction(function( seed, matches, context, xml ) {
						var elem,
							unmatched = matcher( seed, null, xml, [] ),
							i = seed.length;
	
						// Match elements unmatched by `matcher`
						while ( i-- ) {
							if ( (elem = unmatched[i]) ) {
								seed[i] = !(matches[i] = elem);
							}
						}
					}) :
					function( elem, context, xml ) {
						input[0] = elem;
						matcher( input, null, xml, results );
						// Don't keep the element (issue #299)
						input[0] = null;
						return !results.pop();
					};
			}),
	
			"has": markFunction(function( selector ) {
				return function( elem ) {
					return Sizzle( selector, elem ).length > 0;
				};
			}),
	
			"contains": markFunction(function( text ) {
				text = text.replace( runescape, funescape );
				return function( elem ) {
					return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
				};
			}),
	
			// "Whether an element is represented by a :lang() selector
			// is based solely on the element's language value
			// being equal to the identifier C,
			// or beginning with the identifier C immediately followed by "-".
			// The matching of C against the element's language value is performed case-insensitively.
			// The identifier C does not have to be a valid language name."
			// http://www.w3.org/TR/selectors/#lang-pseudo
			"lang": markFunction( function( lang ) {
				// lang value must be a valid identifier
				if ( !ridentifier.test(lang || "") ) {
					Sizzle.error( "unsupported lang: " + lang );
				}
				lang = lang.replace( runescape, funescape ).toLowerCase();
				return function( elem ) {
					var elemLang;
					do {
						if ( (elemLang = documentIsHTML ?
							elem.lang :
							elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
	
							elemLang = elemLang.toLowerCase();
							return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
						}
					} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
					return false;
				};
			}),
	
			// Miscellaneous
			"target": function( elem ) {
				var hash = window.location && window.location.hash;
				return hash && hash.slice( 1 ) === elem.id;
			},
	
			"root": function( elem ) {
				return elem === docElem;
			},
	
			"focus": function( elem ) {
				return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
			},
	
			// Boolean properties
			"enabled": createDisabledPseudo( false ),
			"disabled": createDisabledPseudo( true ),
	
			"checked": function( elem ) {
				// In CSS3, :checked should return both checked and selected elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				var nodeName = elem.nodeName.toLowerCase();
				return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
			},
	
			"selected": function( elem ) {
				// Accessing this property makes selected-by-default
				// options in Safari work properly
				if ( elem.parentNode ) {
					elem.parentNode.selectedIndex;
				}
	
				return elem.selected === true;
			},
	
			// Contents
			"empty": function( elem ) {
				// http://www.w3.org/TR/selectors/#empty-pseudo
				// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
				//   but not by others (comment: 8; processing instruction: 7; etc.)
				// nodeType < 6 works because attributes (2) do not appear as children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					if ( elem.nodeType < 6 ) {
						return false;
					}
				}
				return true;
			},
	
			"parent": function( elem ) {
				return !Expr.pseudos["empty"]( elem );
			},
	
			// Element/input types
			"header": function( elem ) {
				return rheader.test( elem.nodeName );
			},
	
			"input": function( elem ) {
				return rinputs.test( elem.nodeName );
			},
	
			"button": function( elem ) {
				var name = elem.nodeName.toLowerCase();
				return name === "input" && elem.type === "button" || name === "button";
			},
	
			"text": function( elem ) {
				var attr;
				return elem.nodeName.toLowerCase() === "input" &&
					elem.type === "text" &&
	
					// Support: IE<8
					// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
					( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
			},
	
			// Position-in-collection
			"first": createPositionalPseudo(function() {
				return [ 0 ];
			}),
	
			"last": createPositionalPseudo(function( matchIndexes, length ) {
				return [ length - 1 ];
			}),
	
			"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
				return [ argument < 0 ? argument + length : argument ];
			}),
	
			"even": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 0;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"odd": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 1;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; --i >= 0; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; ++i < length; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			})
		}
	};
	
	Expr.pseudos["nth"] = Expr.pseudos["eq"];
	
	// Add button/input type pseudos
	for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
		Expr.pseudos[ i ] = createInputPseudo( i );
	}
	for ( i in { submit: true, reset: true } ) {
		Expr.pseudos[ i ] = createButtonPseudo( i );
	}
	
	// Easy API for creating new setFilters
	function setFilters() {}
	setFilters.prototype = Expr.filters = Expr.pseudos;
	Expr.setFilters = new setFilters();
	
	tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
		var matched, match, tokens, type,
			soFar, groups, preFilters,
			cached = tokenCache[ selector + " " ];
	
		if ( cached ) {
			return parseOnly ? 0 : cached.slice( 0 );
		}
	
		soFar = selector;
		groups = [];
		preFilters = Expr.preFilter;
	
		while ( soFar ) {
	
			// Comma and first run
			if ( !matched || (match = rcomma.exec( soFar )) ) {
				if ( match ) {
					// Don't consume trailing commas as valid
					soFar = soFar.slice( match[0].length ) || soFar;
				}
				groups.push( (tokens = []) );
			}
	
			matched = false;
	
			// Combinators
			if ( (match = rcombinators.exec( soFar )) ) {
				matched = match.shift();
				tokens.push({
					value: matched,
					// Cast descendant combinators to space
					type: match[0].replace( rtrim, " " )
				});
				soFar = soFar.slice( matched.length );
			}
	
			// Filters
			for ( type in Expr.filter ) {
				if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
					(match = preFilters[ type ]( match ))) ) {
					matched = match.shift();
					tokens.push({
						value: matched,
						type: type,
						matches: match
					});
					soFar = soFar.slice( matched.length );
				}
			}
	
			if ( !matched ) {
				break;
			}
		}
	
		// Return the length of the invalid excess
		// if we're just parsing
		// Otherwise, throw an error or return tokens
		return parseOnly ?
			soFar.length :
			soFar ?
				Sizzle.error( selector ) :
				// Cache the tokens
				tokenCache( selector, groups ).slice( 0 );
	};
	
	function toSelector( tokens ) {
		var i = 0,
			len = tokens.length,
			selector = "";
		for ( ; i < len; i++ ) {
			selector += tokens[i].value;
		}
		return selector;
	}
	
	function addCombinator( matcher, combinator, base ) {
		var dir = combinator.dir,
			skip = combinator.next,
			key = skip || dir,
			checkNonElements = base && key === "parentNode",
			doneName = done++;
	
		return combinator.first ?
			// Check against closest ancestor/preceding element
			function( elem, context, xml ) {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						return matcher( elem, context, xml );
					}
				}
				return false;
			} :
	
			// Check against all ancestor/preceding elements
			function( elem, context, xml ) {
				var oldCache, uniqueCache, outerCache,
					newCache = [ dirruns, doneName ];
	
				// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
				if ( xml ) {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							if ( matcher( elem, context, xml ) ) {
								return true;
							}
						}
					}
				} else {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							outerCache = elem[ expando ] || (elem[ expando ] = {});
	
							// Support: IE <9 only
							// Defend against cloned attroperties (jQuery gh-1709)
							uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
	
							if ( skip && skip === elem.nodeName.toLowerCase() ) {
								elem = elem[ dir ] || elem;
							} else if ( (oldCache = uniqueCache[ key ]) &&
								oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
	
								// Assign to newCache so results back-propagate to previous elements
								return (newCache[ 2 ] = oldCache[ 2 ]);
							} else {
								// Reuse newcache so results back-propagate to previous elements
								uniqueCache[ key ] = newCache;
	
								// A match means we're done; a fail means we have to keep checking
								if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
									return true;
								}
							}
						}
					}
				}
				return false;
			};
	}
	
	function elementMatcher( matchers ) {
		return matchers.length > 1 ?
			function( elem, context, xml ) {
				var i = matchers.length;
				while ( i-- ) {
					if ( !matchers[i]( elem, context, xml ) ) {
						return false;
					}
				}
				return true;
			} :
			matchers[0];
	}
	
	function multipleContexts( selector, contexts, results ) {
		var i = 0,
			len = contexts.length;
		for ( ; i < len; i++ ) {
			Sizzle( selector, contexts[i], results );
		}
		return results;
	}
	
	function condense( unmatched, map, filter, context, xml ) {
		var elem,
			newUnmatched = [],
			i = 0,
			len = unmatched.length,
			mapped = map != null;
	
		for ( ; i < len; i++ ) {
			if ( (elem = unmatched[i]) ) {
				if ( !filter || filter( elem, context, xml ) ) {
					newUnmatched.push( elem );
					if ( mapped ) {
						map.push( i );
					}
				}
			}
		}
	
		return newUnmatched;
	}
	
	function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
		if ( postFilter && !postFilter[ expando ] ) {
			postFilter = setMatcher( postFilter );
		}
		if ( postFinder && !postFinder[ expando ] ) {
			postFinder = setMatcher( postFinder, postSelector );
		}
		return markFunction(function( seed, results, context, xml ) {
			var temp, i, elem,
				preMap = [],
				postMap = [],
				preexisting = results.length,
	
				// Get initial elements from seed or context
				elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
	
				// Prefilter to get matcher input, preserving a map for seed-results synchronization
				matcherIn = preFilter && ( seed || !selector ) ?
					condense( elems, preMap, preFilter, context, xml ) :
					elems,
	
				matcherOut = matcher ?
					// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
					postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
	
						// ...intermediate processing is necessary
						[] :
	
						// ...otherwise use results directly
						results :
					matcherIn;
	
			// Find primary matches
			if ( matcher ) {
				matcher( matcherIn, matcherOut, context, xml );
			}
	
			// Apply postFilter
			if ( postFilter ) {
				temp = condense( matcherOut, postMap );
				postFilter( temp, [], context, xml );
	
				// Un-match failing elements by moving them back to matcherIn
				i = temp.length;
				while ( i-- ) {
					if ( (elem = temp[i]) ) {
						matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
					}
				}
			}
	
			if ( seed ) {
				if ( postFinder || preFilter ) {
					if ( postFinder ) {
						// Get the final matcherOut by condensing this intermediate into postFinder contexts
						temp = [];
						i = matcherOut.length;
						while ( i-- ) {
							if ( (elem = matcherOut[i]) ) {
								// Restore matcherIn since elem is not yet a final match
								temp.push( (matcherIn[i] = elem) );
							}
						}
						postFinder( null, (matcherOut = []), temp, xml );
					}
	
					// Move matched elements from seed to results to keep them synchronized
					i = matcherOut.length;
					while ( i-- ) {
						if ( (elem = matcherOut[i]) &&
							(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
	
							seed[temp] = !(results[temp] = elem);
						}
					}
				}
	
			// Add elements to results, through postFinder if defined
			} else {
				matcherOut = condense(
					matcherOut === results ?
						matcherOut.splice( preexisting, matcherOut.length ) :
						matcherOut
				);
				if ( postFinder ) {
					postFinder( null, results, matcherOut, xml );
				} else {
					push.apply( results, matcherOut );
				}
			}
		});
	}
	
	function matcherFromTokens( tokens ) {
		var checkContext, matcher, j,
			len = tokens.length,
			leadingRelative = Expr.relative[ tokens[0].type ],
			implicitRelative = leadingRelative || Expr.relative[" "],
			i = leadingRelative ? 1 : 0,
	
			// The foundational matcher ensures that elements are reachable from top-level context(s)
			matchContext = addCombinator( function( elem ) {
				return elem === checkContext;
			}, implicitRelative, true ),
			matchAnyContext = addCombinator( function( elem ) {
				return indexOf( checkContext, elem ) > -1;
			}, implicitRelative, true ),
			matchers = [ function( elem, context, xml ) {
				var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
					(checkContext = context).nodeType ?
						matchContext( elem, context, xml ) :
						matchAnyContext( elem, context, xml ) );
				// Avoid hanging onto element (issue #299)
				checkContext = null;
				return ret;
			} ];
	
		for ( ; i < len; i++ ) {
			if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
				matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
			} else {
				matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
	
				// Return special upon seeing a positional matcher
				if ( matcher[ expando ] ) {
					// Find the next relative operator (if any) for proper handling
					j = ++i;
					for ( ; j < len; j++ ) {
						if ( Expr.relative[ tokens[j].type ] ) {
							break;
						}
					}
					return setMatcher(
						i > 1 && elementMatcher( matchers ),
						i > 1 && toSelector(
							// If the preceding token was a descendant combinator, insert an implicit any-element `*`
							tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
						).replace( rtrim, "$1" ),
						matcher,
						i < j && matcherFromTokens( tokens.slice( i, j ) ),
						j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
						j < len && toSelector( tokens )
					);
				}
				matchers.push( matcher );
			}
		}
	
		return elementMatcher( matchers );
	}
	
	function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
		var bySet = setMatchers.length > 0,
			byElement = elementMatchers.length > 0,
			superMatcher = function( seed, context, xml, results, outermost ) {
				var elem, j, matcher,
					matchedCount = 0,
					i = "0",
					unmatched = seed && [],
					setMatched = [],
					contextBackup = outermostContext,
					// We must always have either seed elements or outermost context
					elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
					// Use integer dirruns iff this is the outermost matcher
					dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
					len = elems.length;
	
				if ( outermost ) {
					outermostContext = context === document || context || outermost;
				}
	
				// Add elements passing elementMatchers directly to results
				// Support: IE<9, Safari
				// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
				for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
					if ( byElement && elem ) {
						j = 0;
						if ( !context && elem.ownerDocument !== document ) {
							setDocument( elem );
							xml = !documentIsHTML;
						}
						while ( (matcher = elementMatchers[j++]) ) {
							if ( matcher( elem, context || document, xml) ) {
								results.push( elem );
								break;
							}
						}
						if ( outermost ) {
							dirruns = dirrunsUnique;
						}
					}
	
					// Track unmatched elements for set filters
					if ( bySet ) {
						// They will have gone through all possible matchers
						if ( (elem = !matcher && elem) ) {
							matchedCount--;
						}
	
						// Lengthen the array for every element, matched or not
						if ( seed ) {
							unmatched.push( elem );
						}
					}
				}
	
				// `i` is now the count of elements visited above, and adding it to `matchedCount`
				// makes the latter nonnegative.
				matchedCount += i;
	
				// Apply set filters to unmatched elements
				// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
				// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
				// no element matchers and no seed.
				// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
				// case, which will result in a "00" `matchedCount` that differs from `i` but is also
				// numerically zero.
				if ( bySet && i !== matchedCount ) {
					j = 0;
					while ( (matcher = setMatchers[j++]) ) {
						matcher( unmatched, setMatched, context, xml );
					}
	
					if ( seed ) {
						// Reintegrate element matches to eliminate the need for sorting
						if ( matchedCount > 0 ) {
							while ( i-- ) {
								if ( !(unmatched[i] || setMatched[i]) ) {
									setMatched[i] = pop.call( results );
								}
							}
						}
	
						// Discard index placeholder values to get only actual matches
						setMatched = condense( setMatched );
					}
	
					// Add matches to results
					push.apply( results, setMatched );
	
					// Seedless set matches succeeding multiple successful matchers stipulate sorting
					if ( outermost && !seed && setMatched.length > 0 &&
						( matchedCount + setMatchers.length ) > 1 ) {
	
						Sizzle.uniqueSort( results );
					}
				}
	
				// Override manipulation of globals by nested matchers
				if ( outermost ) {
					dirruns = dirrunsUnique;
					outermostContext = contextBackup;
				}
	
				return unmatched;
			};
	
		return bySet ?
			markFunction( superMatcher ) :
			superMatcher;
	}
	
	compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
		var i,
			setMatchers = [],
			elementMatchers = [],
			cached = compilerCache[ selector + " " ];
	
		if ( !cached ) {
			// Generate a function of recursive functions that can be used to check each element
			if ( !match ) {
				match = tokenize( selector );
			}
			i = match.length;
			while ( i-- ) {
				cached = matcherFromTokens( match[i] );
				if ( cached[ expando ] ) {
					setMatchers.push( cached );
				} else {
					elementMatchers.push( cached );
				}
			}
	
			// Cache the compiled function
			cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
	
			// Save selector and tokenization
			cached.selector = selector;
		}
		return cached;
	};
	
	/**
	 * A low-level selection function that works with Sizzle's compiled
	 *  selector functions
	 * @param {String|Function} selector A selector or a pre-compiled
	 *  selector function built with Sizzle.compile
	 * @param {Element} context
	 * @param {Array} [results]
	 * @param {Array} [seed] A set of elements to match against
	 */
	select = Sizzle.select = function( selector, context, results, seed ) {
		var i, tokens, token, type, find,
			compiled = typeof selector === "function" && selector,
			match = !seed && tokenize( (selector = compiled.selector || selector) );
	
		results = results || [];
	
		// Try to minimize operations if there is only one selector in the list and no seed
		// (the latter of which guarantees us context)
		if ( match.length === 1 ) {
	
			// Reduce context if the leading compound selector is an ID
			tokens = match[0] = match[0].slice( 0 );
			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
					context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
	
				context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
				if ( !context ) {
					return results;
	
				// Precompiled matchers will still verify ancestry, so step up a level
				} else if ( compiled ) {
					context = context.parentNode;
				}
	
				selector = selector.slice( tokens.shift().value.length );
			}
	
			// Fetch a seed set for right-to-left matching
			i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
			while ( i-- ) {
				token = tokens[i];
	
				// Abort if we hit a combinator
				if ( Expr.relative[ (type = token.type) ] ) {
					break;
				}
				if ( (find = Expr.find[ type ]) ) {
					// Search, expanding context for leading sibling combinators
					if ( (seed = find(
						token.matches[0].replace( runescape, funescape ),
						rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
					)) ) {
	
						// If seed is empty or no tokens remain, we can return early
						tokens.splice( i, 1 );
						selector = seed.length && toSelector( tokens );
						if ( !selector ) {
							push.apply( results, seed );
							return results;
						}
	
						break;
					}
				}
			}
		}
	
		// Compile and execute a filtering function if one is not provided
		// Provide `match` to avoid retokenization if we modified the selector above
		( compiled || compile( selector, match ) )(
			seed,
			context,
			!documentIsHTML,
			results,
			!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
		);
		return results;
	};
	
	// One-time assignments
	
	// Sort stability
	support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
	
	// Support: Chrome 14-35+
	// Always assume duplicates if they aren't passed to the comparison function
	support.detectDuplicates = !!hasDuplicate;
	
	// Initialize against the default document
	setDocument();
	
	// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
	// Detached nodes confoundingly follow *each other*
	support.sortDetached = assert(function( el ) {
		// Should return 1, but returns 4 (following)
		return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
	});
	
	// Support: IE<8
	// Prevent attribute/property "interpolation"
	// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
	if ( !assert(function( el ) {
		el.innerHTML = "<a href='#'></a>";
		return el.firstChild.getAttribute("href") === "#" ;
	}) ) {
		addHandle( "type|href|height|width", function( elem, name, isXML ) {
			if ( !isXML ) {
				return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
			}
		});
	}
	
	// Support: IE<9
	// Use defaultValue in place of getAttribute("value")
	if ( !support.attributes || !assert(function( el ) {
		el.innerHTML = "<input/>";
		el.firstChild.setAttribute( "value", "" );
		return el.firstChild.getAttribute( "value" ) === "";
	}) ) {
		addHandle( "value", function( elem, name, isXML ) {
			if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
				return elem.defaultValue;
			}
		});
	}
	
	// Support: IE<9
	// Use getAttributeNode to fetch booleans when getAttribute lies
	if ( !assert(function( el ) {
		return el.getAttribute("disabled") == null;
	}) ) {
		addHandle( booleans, function( elem, name, isXML ) {
			var val;
			if ( !isXML ) {
				return elem[ name ] === true ? name.toLowerCase() :
						(val = elem.getAttributeNode( name )) && val.specified ?
						val.value :
					null;
			}
		});
	}
	
	return Sizzle;
	
	})( window );
	
	
	
	jQuery.find = Sizzle;
	jQuery.expr = Sizzle.selectors;
	
	// Deprecated
	jQuery.expr[ ":" ] = jQuery.expr.pseudos;
	jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
	jQuery.text = Sizzle.getText;
	jQuery.isXMLDoc = Sizzle.isXML;
	jQuery.contains = Sizzle.contains;
	jQuery.escapeSelector = Sizzle.escape;
	
	
	
	
	var dir = function( elem, dir, until ) {
		var matched = [],
			truncate = until !== undefined;
	
		while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
			if ( elem.nodeType === 1 ) {
				if ( truncate && jQuery( elem ).is( until ) ) {
					break;
				}
				matched.push( elem );
			}
		}
		return matched;
	};
	
	
	var siblings = function( n, elem ) {
		var matched = [];
	
		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				matched.push( n );
			}
		}
	
		return matched;
	};
	
	
	var rneedsContext = jQuery.expr.match.needsContext;
	
	
	
	function nodeName( elem, name ) {
	
	  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
	
	};
	var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
	
	
	
	var risSimple = /^.[^:#\[\.,]*$/;
	
	// Implement the identical functionality for filter and not
	function winnow( elements, qualifier, not ) {
		if ( jQuery.isFunction( qualifier ) ) {
			return jQuery.grep( elements, function( elem, i ) {
				return !!qualifier.call( elem, i, elem ) !== not;
			} );
		}
	
		// Single element
		if ( qualifier.nodeType ) {
			return jQuery.grep( elements, function( elem ) {
				return ( elem === qualifier ) !== not;
			} );
		}
	
		// Arraylike of elements (jQuery, arguments, Array)
		if ( typeof qualifier !== "string" ) {
			return jQuery.grep( elements, function( elem ) {
				return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
			} );
		}
	
		// Simple selector that can be filtered directly, removing non-Elements
		if ( risSimple.test( qualifier ) ) {
			return jQuery.filter( qualifier, elements, not );
		}
	
		// Complex selector, compare the two sets, removing non-Elements
		qualifier = jQuery.filter( qualifier, elements );
		return jQuery.grep( elements, function( elem ) {
			return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
		} );
	}
	
	jQuery.filter = function( expr, elems, not ) {
		var elem = elems[ 0 ];
	
		if ( not ) {
			expr = ":not(" + expr + ")";
		}
	
		if ( elems.length === 1 && elem.nodeType === 1 ) {
			return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
		}
	
		return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
			return elem.nodeType === 1;
		} ) );
	};
	
	jQuery.fn.extend( {
		find: function( selector ) {
			var i, ret,
				len = this.length,
				self = this;
	
			if ( typeof selector !== "string" ) {
				return this.pushStack( jQuery( selector ).filter( function() {
					for ( i = 0; i < len; i++ ) {
						if ( jQuery.contains( self[ i ], this ) ) {
							return true;
						}
					}
				} ) );
			}
	
			ret = this.pushStack( [] );
	
			for ( i = 0; i < len; i++ ) {
				jQuery.find( selector, self[ i ], ret );
			}
	
			return len > 1 ? jQuery.uniqueSort( ret ) : ret;
		},
		filter: function( selector ) {
			return this.pushStack( winnow( this, selector || [], false ) );
		},
		not: function( selector ) {
			return this.pushStack( winnow( this, selector || [], true ) );
		},
		is: function( selector ) {
			return !!winnow(
				this,
	
				// If this is a positional/relative selector, check membership in the returned set
				// so $("p:first").is("p:last") won't return true for a doc with two "p".
				typeof selector === "string" && rneedsContext.test( selector ) ?
					jQuery( selector ) :
					selector || [],
				false
			).length;
		}
	} );
	
	
	// Initialize a jQuery object
	
	
	// A central reference to the root jQuery(document)
	var rootjQuery,
	
		// A simple way to check for HTML strings
		// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
		// Strict HTML recognition (#11290: must start with <)
		// Shortcut simple #id case for speed
		rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
	
		init = jQuery.fn.init = function( selector, context, root ) {
			var match, elem;
	
			// HANDLE: $(""), $(null), $(undefined), $(false)
			if ( !selector ) {
				return this;
			}
	
			// Method init() accepts an alternate rootjQuery
			// so migrate can support jQuery.sub (gh-2101)
			root = root || rootjQuery;
	
			// Handle HTML strings
			if ( typeof selector === "string" ) {
				if ( selector[ 0 ] === "<" &&
					selector[ selector.length - 1 ] === ">" &&
					selector.length >= 3 ) {
	
					// Assume that strings that start and end with <> are HTML and skip the regex check
					match = [ null, selector, null ];
	
				} else {
					match = rquickExpr.exec( selector );
				}
	
				// Match html or make sure no context is specified for #id
				if ( match && ( match[ 1 ] || !context ) ) {
	
					// HANDLE: $(html) -> $(array)
					if ( match[ 1 ] ) {
						context = context instanceof jQuery ? context[ 0 ] : context;
	
						// Option to run scripts is true for back-compat
						// Intentionally let the error be thrown if parseHTML is not present
						jQuery.merge( this, jQuery.parseHTML(
							match[ 1 ],
							context && context.nodeType ? context.ownerDocument || context : document,
							true
						) );
	
						// HANDLE: $(html, props)
						if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
							for ( match in context ) {
	
								// Properties of context are called as methods if possible
								if ( jQuery.isFunction( this[ match ] ) ) {
									this[ match ]( context[ match ] );
	
								// ...and otherwise set as attributes
								} else {
									this.attr( match, context[ match ] );
								}
							}
						}
	
						return this;
	
					// HANDLE: $(#id)
					} else {
						elem = document.getElementById( match[ 2 ] );
	
						if ( elem ) {
	
							// Inject the element directly into the jQuery object
							this[ 0 ] = elem;
							this.length = 1;
						}
						return this;
					}
	
				// HANDLE: $(expr, $(...))
				} else if ( !context || context.jquery ) {
					return ( context || root ).find( selector );
	
				// HANDLE: $(expr, context)
				// (which is just equivalent to: $(context).find(expr)
				} else {
					return this.constructor( context ).find( selector );
				}
	
			// HANDLE: $(DOMElement)
			} else if ( selector.nodeType ) {
				this[ 0 ] = selector;
				this.length = 1;
				return this;
	
			// HANDLE: $(function)
			// Shortcut for document ready
			} else if ( jQuery.isFunction( selector ) ) {
				return root.ready !== undefined ?
					root.ready( selector ) :
	
					// Execute immediately if ready is not present
					selector( jQuery );
			}
	
			return jQuery.makeArray( selector, this );
		};
	
	// Give the init function the jQuery prototype for later instantiation
	init.prototype = jQuery.fn;
	
	// Initialize central reference
	rootjQuery = jQuery( document );
	
	
	var rparentsprev = /^(?:parents|prev(?:Until|All))/,
	
		// Methods guaranteed to produce a unique set when starting from a unique set
		guaranteedUnique = {
			children: true,
			contents: true,
			next: true,
			prev: true
		};
	
	jQuery.fn.extend( {
		has: function( target ) {
			var targets = jQuery( target, this ),
				l = targets.length;
	
			return this.filter( function() {
				var i = 0;
				for ( ; i < l; i++ ) {
					if ( jQuery.contains( this, targets[ i ] ) ) {
						return true;
					}
				}
			} );
		},
	
		closest: function( selectors, context ) {
			var cur,
				i = 0,
				l = this.length,
				matched = [],
				targets = typeof selectors !== "string" && jQuery( selectors );
	
			// Positional selectors never match, since there's no _selection_ context
			if ( !rneedsContext.test( selectors ) ) {
				for ( ; i < l; i++ ) {
					for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
	
						// Always skip document fragments
						if ( cur.nodeType < 11 && ( targets ?
							targets.index( cur ) > -1 :
	
							// Don't pass non-elements to Sizzle
							cur.nodeType === 1 &&
								jQuery.find.matchesSelector( cur, selectors ) ) ) {
	
							matched.push( cur );
							break;
						}
					}
				}
			}
	
			return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
		},
	
		// Determine the position of an element within the set
		index: function( elem ) {
	
			// No argument, return index in parent
			if ( !elem ) {
				return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
			}
	
			// Index in selector
			if ( typeof elem === "string" ) {
				return indexOf.call( jQuery( elem ), this[ 0 ] );
			}
	
			// Locate the position of the desired element
			return indexOf.call( this,
	
				// If it receives a jQuery object, the first element is used
				elem.jquery ? elem[ 0 ] : elem
			);
		},
	
		add: function( selector, context ) {
			return this.pushStack(
				jQuery.uniqueSort(
					jQuery.merge( this.get(), jQuery( selector, context ) )
				)
			);
		},
	
		addBack: function( selector ) {
			return this.add( selector == null ?
				this.prevObject : this.prevObject.filter( selector )
			);
		}
	} );
	
	function sibling( cur, dir ) {
		while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
		return cur;
	}
	
	jQuery.each( {
		parent: function( elem ) {
			var parent = elem.parentNode;
			return parent && parent.nodeType !== 11 ? parent : null;
		},
		parents: function( elem ) {
			return dir( elem, "parentNode" );
		},
		parentsUntil: function( elem, i, until ) {
			return dir( elem, "parentNode", until );
		},
		next: function( elem ) {
			return sibling( elem, "nextSibling" );
		},
		prev: function( elem ) {
			return sibling( elem, "previousSibling" );
		},
		nextAll: function( elem ) {
			return dir( elem, "nextSibling" );
		},
		prevAll: function( elem ) {
			return dir( elem, "previousSibling" );
		},
		nextUntil: function( elem, i, until ) {
			return dir( elem, "nextSibling", until );
		},
		prevUntil: function( elem, i, until ) {
			return dir( elem, "previousSibling", until );
		},
		siblings: function( elem ) {
			return siblings( ( elem.parentNode || {} ).firstChild, elem );
		},
		children: function( elem ) {
			return siblings( elem.firstChild );
		},
		contents: function( elem ) {
	        if ( nodeName( elem, "iframe" ) ) {
	            return elem.contentDocument;
	        }
	
	        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
	        // Treat the template element as a regular one in browsers that
	        // don't support it.
	        if ( nodeName( elem, "template" ) ) {
	            elem = elem.content || elem;
	        }
	
	        return jQuery.merge( [], elem.childNodes );
		}
	}, function( name, fn ) {
		jQuery.fn[ name ] = function( until, selector ) {
			var matched = jQuery.map( this, fn, until );
	
			if ( name.slice( -5 ) !== "Until" ) {
				selector = until;
			}
	
			if ( selector && typeof selector === "string" ) {
				matched = jQuery.filter( selector, matched );
			}
	
			if ( this.length > 1 ) {
	
				// Remove duplicates
				if ( !guaranteedUnique[ name ] ) {
					jQuery.uniqueSort( matched );
				}
	
				// Reverse order for parents* and prev-derivatives
				if ( rparentsprev.test( name ) ) {
					matched.reverse();
				}
			}
	
			return this.pushStack( matched );
		};
	} );
	var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
	
	
	
	// Convert String-formatted options into Object-formatted ones
	function createOptions( options ) {
		var object = {};
		jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
			object[ flag ] = true;
		} );
		return object;
	}
	
	/*
	 * Create a callback list using the following parameters:
	 *
	 *	options: an optional list of space-separated options that will change how
	 *			the callback list behaves or a more traditional option object
	 *
	 * By default a callback list will act like an event callback list and can be
	 * "fired" multiple times.
	 *
	 * Possible options:
	 *
	 *	once:			will ensure the callback list can only be fired once (like a Deferred)
	 *
	 *	memory:			will keep track of previous values and will call any callback added
	 *					after the list has been fired right away with the latest "memorized"
	 *					values (like a Deferred)
	 *
	 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
	 *
	 *	stopOnFalse:	interrupt callings when a callback returns false
	 *
	 */
	jQuery.Callbacks = function( options ) {
	
		// Convert options from String-formatted to Object-formatted if needed
		// (we check in cache first)
		options = typeof options === "string" ?
			createOptions( options ) :
			jQuery.extend( {}, options );
	
		var // Flag to know if list is currently firing
			firing,
	
			// Last fire value for non-forgettable lists
			memory,
	
			// Flag to know if list was already fired
			fired,
	
			// Flag to prevent firing
			locked,
	
			// Actual callback list
			list = [],
	
			// Queue of execution data for repeatable lists
			queue = [],
	
			// Index of currently firing callback (modified by add/remove as needed)
			firingIndex = -1,
	
			// Fire callbacks
			fire = function() {
	
				// Enforce single-firing
				locked = locked || options.once;
	
				// Execute callbacks for all pending executions,
				// respecting firingIndex overrides and runtime changes
				fired = firing = true;
				for ( ; queue.length; firingIndex = -1 ) {
					memory = queue.shift();
					while ( ++firingIndex < list.length ) {
	
						// Run callback and check for early termination
						if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
							options.stopOnFalse ) {
	
							// Jump to end and forget the data so .add doesn't re-fire
							firingIndex = list.length;
							memory = false;
						}
					}
				}
	
				// Forget the data if we're done with it
				if ( !options.memory ) {
					memory = false;
				}
	
				firing = false;
	
				// Clean up if we're done firing for good
				if ( locked ) {
	
					// Keep an empty list if we have data for future add calls
					if ( memory ) {
						list = [];
	
					// Otherwise, this object is spent
					} else {
						list = "";
					}
				}
			},
	
			// Actual Callbacks object
			self = {
	
				// Add a callback or a collection of callbacks to the list
				add: function() {
					if ( list ) {
	
						// If we have memory from a past run, we should fire after adding
						if ( memory && !firing ) {
							firingIndex = list.length - 1;
							queue.push( memory );
						}
	
						( function add( args ) {
							jQuery.each( args, function( _, arg ) {
								if ( jQuery.isFunction( arg ) ) {
									if ( !options.unique || !self.has( arg ) ) {
										list.push( arg );
									}
								} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
	
									// Inspect recursively
									add( arg );
								}
							} );
						} )( arguments );
	
						if ( memory && !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Remove a callback from the list
				remove: function() {
					jQuery.each( arguments, function( _, arg ) {
						var index;
						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
							list.splice( index, 1 );
	
							// Handle firing indexes
							if ( index <= firingIndex ) {
								firingIndex--;
							}
						}
					} );
					return this;
				},
	
				// Check if a given callback is in the list.
				// If no argument is given, return whether or not list has callbacks attached.
				has: function( fn ) {
					return fn ?
						jQuery.inArray( fn, list ) > -1 :
						list.length > 0;
				},
	
				// Remove all callbacks from the list
				empty: function() {
					if ( list ) {
						list = [];
					}
					return this;
				},
	
				// Disable .fire and .add
				// Abort any current/pending executions
				// Clear all callbacks and values
				disable: function() {
					locked = queue = [];
					list = memory = "";
					return this;
				},
				disabled: function() {
					return !list;
				},
	
				// Disable .fire
				// Also disable .add unless we have memory (since it would have no effect)
				// Abort any pending executions
				lock: function() {
					locked = queue = [];
					if ( !memory && !firing ) {
						list = memory = "";
					}
					return this;
				},
				locked: function() {
					return !!locked;
				},
	
				// Call all callbacks with the given context and arguments
				fireWith: function( context, args ) {
					if ( !locked ) {
						args = args || [];
						args = [ context, args.slice ? args.slice() : args ];
						queue.push( args );
						if ( !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Call all the callbacks with the given arguments
				fire: function() {
					self.fireWith( this, arguments );
					return this;
				},
	
				// To know if the callbacks have already been called at least once
				fired: function() {
					return !!fired;
				}
			};
	
		return self;
	};
	
	
	function Identity( v ) {
		return v;
	}
	function Thrower( ex ) {
		throw ex;
	}
	
	function adoptValue( value, resolve, reject, noValue ) {
		var method;
	
		try {
	
			// Check for promise aspect first to privilege synchronous behavior
			if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
				method.call( value ).done( resolve ).fail( reject );
	
			// Other thenables
			} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
				method.call( value, resolve, reject );
	
			// Other non-thenables
			} else {
	
				// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
				// * false: [ value ].slice( 0 ) => resolve( value )
				// * true: [ value ].slice( 1 ) => resolve()
				resolve.apply( undefined, [ value ].slice( noValue ) );
			}
	
		// For Promises/A+, convert exceptions into rejections
		// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
		// Deferred#then to conditionally suppress rejection.
		} catch ( value ) {
	
			// Support: Android 4.0 only
			// Strict mode functions invoked without .call/.apply get global-object context
			reject.apply( undefined, [ value ] );
		}
	}
	
	jQuery.extend( {
	
		Deferred: function( func ) {
			var tuples = [
	
					// action, add listener, callbacks,
					// ... .then handlers, argument index, [final state]
					[ "notify", "progress", jQuery.Callbacks( "memory" ),
						jQuery.Callbacks( "memory" ), 2 ],
					[ "resolve", "done", jQuery.Callbacks( "once memory" ),
						jQuery.Callbacks( "once memory" ), 0, "resolved" ],
					[ "reject", "fail", jQuery.Callbacks( "once memory" ),
						jQuery.Callbacks( "once memory" ), 1, "rejected" ]
				],
				state = "pending",
				promise = {
					state: function() {
						return state;
					},
					always: function() {
						deferred.done( arguments ).fail( arguments );
						return this;
					},
					"catch": function( fn ) {
						return promise.then( null, fn );
					},
	
					// Keep pipe for back-compat
					pipe: function( /* fnDone, fnFail, fnProgress */ ) {
						var fns = arguments;
	
						return jQuery.Deferred( function( newDefer ) {
							jQuery.each( tuples, function( i, tuple ) {
	
								// Map tuples (progress, done, fail) to arguments (done, fail, progress)
								var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
	
								// deferred.progress(function() { bind to newDefer or newDefer.notify })
								// deferred.done(function() { bind to newDefer or newDefer.resolve })
								// deferred.fail(function() { bind to newDefer or newDefer.reject })
								deferred[ tuple[ 1 ] ]( function() {
									var returned = fn && fn.apply( this, arguments );
									if ( returned && jQuery.isFunction( returned.promise ) ) {
										returned.promise()
											.progress( newDefer.notify )
											.done( newDefer.resolve )
											.fail( newDefer.reject );
									} else {
										newDefer[ tuple[ 0 ] + "With" ](
											this,
											fn ? [ returned ] : arguments
										);
									}
								} );
							} );
							fns = null;
						} ).promise();
					},
					then: function( onFulfilled, onRejected, onProgress ) {
						var maxDepth = 0;
						function resolve( depth, deferred, handler, special ) {
							return function() {
								var that = this,
									args = arguments,
									mightThrow = function() {
										var returned, then;
	
										// Support: Promises/A+ section 2.3.3.3.3
										// https://promisesaplus.com/#point-59
										// Ignore double-resolution attempts
										if ( depth < maxDepth ) {
											return;
										}
	
										returned = handler.apply( that, args );
	
										// Support: Promises/A+ section 2.3.1
										// https://promisesaplus.com/#point-48
										if ( returned === deferred.promise() ) {
											throw new TypeError( "Thenable self-resolution" );
										}
	
										// Support: Promises/A+ sections 2.3.3.1, 3.5
										// https://promisesaplus.com/#point-54
										// https://promisesaplus.com/#point-75
										// Retrieve `then` only once
										then = returned &&
	
											// Support: Promises/A+ section 2.3.4
											// https://promisesaplus.com/#point-64
											// Only check objects and functions for thenability
											( typeof returned === "object" ||
												typeof returned === "function" ) &&
											returned.then;
	
										// Handle a returned thenable
										if ( jQuery.isFunction( then ) ) {
	
											// Special processors (notify) just wait for resolution
											if ( special ) {
												then.call(
													returned,
													resolve( maxDepth, deferred, Identity, special ),
													resolve( maxDepth, deferred, Thrower, special )
												);
	
											// Normal processors (resolve) also hook into progress
											} else {
	
												// ...and disregard older resolution values
												maxDepth++;
	
												then.call(
													returned,
													resolve( maxDepth, deferred, Identity, special ),
													resolve( maxDepth, deferred, Thrower, special ),
													resolve( maxDepth, deferred, Identity,
														deferred.notifyWith )
												);
											}
	
										// Handle all other returned values
										} else {
	
											// Only substitute handlers pass on context
											// and multiple values (non-spec behavior)
											if ( handler !== Identity ) {
												that = undefined;
												args = [ returned ];
											}
	
											// Process the value(s)
											// Default process is resolve
											( special || deferred.resolveWith )( that, args );
										}
									},
	
									// Only normal processors (resolve) catch and reject exceptions
									process = special ?
										mightThrow :
										function() {
											try {
												mightThrow();
											} catch ( e ) {
	
												if ( jQuery.Deferred.exceptionHook ) {
													jQuery.Deferred.exceptionHook( e,
														process.stackTrace );
												}
	
												// Support: Promises/A+ section 2.3.3.3.4.1
												// https://promisesaplus.com/#point-61
												// Ignore post-resolution exceptions
												if ( depth + 1 >= maxDepth ) {
	
													// Only substitute handlers pass on context
													// and multiple values (non-spec behavior)
													if ( handler !== Thrower ) {
														that = undefined;
														args = [ e ];
													}
	
													deferred.rejectWith( that, args );
												}
											}
										};
	
								// Support: Promises/A+ section 2.3.3.3.1
								// https://promisesaplus.com/#point-57
								// Re-resolve promises immediately to dodge false rejection from
								// subsequent errors
								if ( depth ) {
									process();
								} else {
	
									// Call an optional hook to record the stack, in case of exception
									// since it's otherwise lost when execution goes async
									if ( jQuery.Deferred.getStackHook ) {
										process.stackTrace = jQuery.Deferred.getStackHook();
									}
									window.setTimeout( process );
								}
							};
						}
	
						return jQuery.Deferred( function( newDefer ) {
	
							// progress_handlers.add( ... )
							tuples[ 0 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onProgress ) ?
										onProgress :
										Identity,
									newDefer.notifyWith
								)
							);
	
							// fulfilled_handlers.add( ... )
							tuples[ 1 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onFulfilled ) ?
										onFulfilled :
										Identity
								)
							);
	
							// rejected_handlers.add( ... )
							tuples[ 2 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onRejected ) ?
										onRejected :
										Thrower
								)
							);
						} ).promise();
					},
	
					// Get a promise for this deferred
					// If obj is provided, the promise aspect is added to the object
					promise: function( obj ) {
						return obj != null ? jQuery.extend( obj, promise ) : promise;
					}
				},
				deferred = {};
	
			// Add list-specific methods
			jQuery.each( tuples, function( i, tuple ) {
				var list = tuple[ 2 ],
					stateString = tuple[ 5 ];
	
				// promise.progress = list.add
				// promise.done = list.add
				// promise.fail = list.add
				promise[ tuple[ 1 ] ] = list.add;
	
				// Handle state
				if ( stateString ) {
					list.add(
						function() {
	
							// state = "resolved" (i.e., fulfilled)
							// state = "rejected"
							state = stateString;
						},
	
						// rejected_callbacks.disable
						// fulfilled_callbacks.disable
						tuples[ 3 - i ][ 2 ].disable,
	
						// progress_callbacks.lock
						tuples[ 0 ][ 2 ].lock
					);
				}
	
				// progress_handlers.fire
				// fulfilled_handlers.fire
				// rejected_handlers.fire
				list.add( tuple[ 3 ].fire );
	
				// deferred.notify = function() { deferred.notifyWith(...) }
				// deferred.resolve = function() { deferred.resolveWith(...) }
				// deferred.reject = function() { deferred.rejectWith(...) }
				deferred[ tuple[ 0 ] ] = function() {
					deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
					return this;
				};
	
				// deferred.notifyWith = list.fireWith
				// deferred.resolveWith = list.fireWith
				// deferred.rejectWith = list.fireWith
				deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
			} );
	
			// Make the deferred a promise
			promise.promise( deferred );
	
			// Call given func if any
			if ( func ) {
				func.call( deferred, deferred );
			}
	
			// All done!
			return deferred;
		},
	
		// Deferred helper
		when: function( singleValue ) {
			var
	
				// count of uncompleted subordinates
				remaining = arguments.length,
	
				// count of unprocessed arguments
				i = remaining,
	
				// subordinate fulfillment data
				resolveContexts = Array( i ),
				resolveValues = slice.call( arguments ),
	
				// the master Deferred
				master = jQuery.Deferred(),
	
				// subordinate callback factory
				updateFunc = function( i ) {
					return function( value ) {
						resolveContexts[ i ] = this;
						resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
						if ( !( --remaining ) ) {
							master.resolveWith( resolveContexts, resolveValues );
						}
					};
				};
	
			// Single- and empty arguments are adopted like Promise.resolve
			if ( remaining <= 1 ) {
				adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
					!remaining );
	
				// Use .then() to unwrap secondary thenables (cf. gh-3000)
				if ( master.state() === "pending" ||
					jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
	
					return master.then();
				}
			}
	
			// Multiple arguments are aggregated like Promise.all array elements
			while ( i-- ) {
				adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
			}
	
			return master.promise();
		}
	} );
	
	
	// These usually indicate a programmer mistake during development,
	// warn about them ASAP rather than swallowing them by default.
	var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
	
	jQuery.Deferred.exceptionHook = function( error, stack ) {
	
		// Support: IE 8 - 9 only
		// Console exists when dev tools are open, which can happen at any time
		if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
			window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
		}
	};
	
	
	
	
	jQuery.readyException = function( error ) {
		window.setTimeout( function() {
			throw error;
		} );
	};
	
	
	
	
	// The deferred used on DOM ready
	var readyList = jQuery.Deferred();
	
	jQuery.fn.ready = function( fn ) {
	
		readyList
			.then( fn )
	
			// Wrap jQuery.readyException in a function so that the lookup
			// happens at the time of error handling instead of callback
			// registration.
			.catch( function( error ) {
				jQuery.readyException( error );
			} );
	
		return this;
	};
	
	jQuery.extend( {
	
		// Is the DOM ready to be used? Set to true once it occurs.
		isReady: false,
	
		// A counter to track how many items to wait for before
		// the ready event fires. See #6781
		readyWait: 1,
	
		// Handle when the DOM is ready
		ready: function( wait ) {
	
			// Abort if there are pending holds or we're already ready
			if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
				return;
			}
	
			// Remember that the DOM is ready
			jQuery.isReady = true;
	
			// If a normal DOM Ready event fired, decrement, and wait if need be
			if ( wait !== true && --jQuery.readyWait > 0 ) {
				return;
			}
	
			// If there are functions bound, to execute
			readyList.resolveWith( document, [ jQuery ] );
		}
	} );
	
	jQuery.ready.then = readyList.then;
	
	// The ready event handler and self cleanup method
	function completed() {
		document.removeEventListener( "DOMContentLoaded", completed );
		window.removeEventListener( "load", completed );
		jQuery.ready();
	}
	
	// Catch cases where $(document).ready() is called
	// after the browser event has already occurred.
	// Support: IE <=9 - 10 only
	// Older IE sometimes signals "interactive" too soon
	if ( document.readyState === "complete" ||
		( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
	
		// Handle it asynchronously to allow scripts the opportunity to delay ready
		window.setTimeout( jQuery.ready );
	
	} else {
	
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", completed );
	
		// A fallback to window.onload, that will always work
		window.addEventListener( "load", completed );
	}
	
	
	
	
	// Multifunctional method to get and set values of a collection
	// The value/s can optionally be executed if it's a function
	var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
		var i = 0,
			len = elems.length,
			bulk = key == null;
	
		// Sets many values
		if ( jQuery.type( key ) === "object" ) {
			chainable = true;
			for ( i in key ) {
				access( elems, fn, i, key[ i ], true, emptyGet, raw );
			}
	
		// Sets one value
		} else if ( value !== undefined ) {
			chainable = true;
	
			if ( !jQuery.isFunction( value ) ) {
				raw = true;
			}
	
			if ( bulk ) {
	
				// Bulk operations run against the entire set
				if ( raw ) {
					fn.call( elems, value );
					fn = null;
	
				// ...except when executing function values
				} else {
					bulk = fn;
					fn = function( elem, key, value ) {
						return bulk.call( jQuery( elem ), value );
					};
				}
			}
	
			if ( fn ) {
				for ( ; i < len; i++ ) {
					fn(
						elems[ i ], key, raw ?
						value :
						value.call( elems[ i ], i, fn( elems[ i ], key ) )
					);
				}
			}
		}
	
		if ( chainable ) {
			return elems;
		}
	
		// Gets
		if ( bulk ) {
			return fn.call( elems );
		}
	
		return len ? fn( elems[ 0 ], key ) : emptyGet;
	};
	var acceptData = function( owner ) {
	
		// Accepts only:
		//  - Node
		//    - Node.ELEMENT_NODE
		//    - Node.DOCUMENT_NODE
		//  - Object
		//    - Any
		return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
	};
	
	
	
	
	function Data() {
		this.expando = jQuery.expando + Data.uid++;
	}
	
	Data.uid = 1;
	
	Data.prototype = {
	
		cache: function( owner ) {
	
			// Check if the owner object already has a cache
			var value = owner[ this.expando ];
	
			// If not, create one
			if ( !value ) {
				value = {};
	
				// We can accept data for non-element nodes in modern browsers,
				// but we should not, see #8335.
				// Always return an empty object.
				if ( acceptData( owner ) ) {
	
					// If it is a node unlikely to be stringify-ed or looped over
					// use plain assignment
					if ( owner.nodeType ) {
						owner[ this.expando ] = value;
	
					// Otherwise secure it in a non-enumerable property
					// configurable must be true to allow the property to be
					// deleted when data is removed
					} else {
						Object.defineProperty( owner, this.expando, {
							value: value,
							configurable: true
						} );
					}
				}
			}
	
			return value;
		},
		set: function( owner, data, value ) {
			var prop,
				cache = this.cache( owner );
	
			// Handle: [ owner, key, value ] args
			// Always use camelCase key (gh-2257)
			if ( typeof data === "string" ) {
				cache[ jQuery.camelCase( data ) ] = value;
	
			// Handle: [ owner, { properties } ] args
			} else {
	
				// Copy the properties one-by-one to the cache object
				for ( prop in data ) {
					cache[ jQuery.camelCase( prop ) ] = data[ prop ];
				}
			}
			return cache;
		},
		get: function( owner, key ) {
			return key === undefined ?
				this.cache( owner ) :
	
				// Always use camelCase key (gh-2257)
				owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
		},
		access: function( owner, key, value ) {
	
			// In cases where either:
			//
			//   1. No key was specified
			//   2. A string key was specified, but no value provided
			//
			// Take the "read" path and allow the get method to determine
			// which value to return, respectively either:
			//
			//   1. The entire cache object
			//   2. The data stored at the key
			//
			if ( key === undefined ||
					( ( key && typeof key === "string" ) && value === undefined ) ) {
	
				return this.get( owner, key );
			}
	
			// When the key is not a string, or both a key and value
			// are specified, set or extend (existing objects) with either:
			//
			//   1. An object of properties
			//   2. A key and value
			//
			this.set( owner, key, value );
	
			// Since the "set" path can have two possible entry points
			// return the expected data based on which path was taken[*]
			return value !== undefined ? value : key;
		},
		remove: function( owner, key ) {
			var i,
				cache = owner[ this.expando ];
	
			if ( cache === undefined ) {
				return;
			}
	
			if ( key !== undefined ) {
	
				// Support array or space separated string of keys
				if ( Array.isArray( key ) ) {
	
					// If key is an array of keys...
					// We always set camelCase keys, so remove that.
					key = key.map( jQuery.camelCase );
				} else {
					key = jQuery.camelCase( key );
	
					// If a key with the spaces exists, use it.
					// Otherwise, create an array by matching non-whitespace
					key = key in cache ?
						[ key ] :
						( key.match( rnothtmlwhite ) || [] );
				}
	
				i = key.length;
	
				while ( i-- ) {
					delete cache[ key[ i ] ];
				}
			}
	
			// Remove the expando if there's no more data
			if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
	
				// Support: Chrome <=35 - 45
				// Webkit & Blink performance suffers when deleting properties
				// from DOM nodes, so set to undefined instead
				// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
				if ( owner.nodeType ) {
					owner[ this.expando ] = undefined;
				} else {
					delete owner[ this.expando ];
				}
			}
		},
		hasData: function( owner ) {
			var cache = owner[ this.expando ];
			return cache !== undefined && !jQuery.isEmptyObject( cache );
		}
	};
	var dataPriv = new Data();
	
	var dataUser = new Data();
	
	
	
	//	Implementation Summary
	//
	//	1. Enforce API surface and semantic compatibility with 1.9.x branch
	//	2. Improve the module's maintainability by reducing the storage
	//		paths to a single mechanism.
	//	3. Use the same single mechanism to support "private" and "user" data.
	//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
	//	5. Avoid exposing implementation details on user objects (eg. expando properties)
	//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
	
	var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
		rmultiDash = /[A-Z]/g;
	
	function getData( data ) {
		if ( data === "true" ) {
			return true;
		}
	
		if ( data === "false" ) {
			return false;
		}
	
		if ( data === "null" ) {
			return null;
		}
	
		// Only convert to a number if it doesn't change the string
		if ( data === +data + "" ) {
			return +data;
		}
	
		if ( rbrace.test( data ) ) {
			return JSON.parse( data );
		}
	
		return data;
	}
	
	function dataAttr( elem, key, data ) {
		var name;
	
		// If nothing was found internally, try to fetch any
		// data from the HTML5 data-* attribute
		if ( data === undefined && elem.nodeType === 1 ) {
			name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
			data = elem.getAttribute( name );
	
			if ( typeof data === "string" ) {
				try {
					data = getData( data );
				} catch ( e ) {}
	
				// Make sure we set the data so it isn't changed later
				dataUser.set( elem, key, data );
			} else {
				data = undefined;
			}
		}
		return data;
	}
	
	jQuery.extend( {
		hasData: function( elem ) {
			return dataUser.hasData( elem ) || dataPriv.hasData( elem );
		},
	
		data: function( elem, name, data ) {
			return dataUser.access( elem, name, data );
		},
	
		removeData: function( elem, name ) {
			dataUser.remove( elem, name );
		},
	
		// TODO: Now that all calls to _data and _removeData have been replaced
		// with direct calls to dataPriv methods, these can be deprecated.
		_data: function( elem, name, data ) {
			return dataPriv.access( elem, name, data );
		},
	
		_removeData: function( elem, name ) {
			dataPriv.remove( elem, name );
		}
	} );
	
	jQuery.fn.extend( {
		data: function( key, value ) {
			var i, name, data,
				elem = this[ 0 ],
				attrs = elem && elem.attributes;
	
			// Gets all values
			if ( key === undefined ) {
				if ( this.length ) {
					data = dataUser.get( elem );
	
					if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
						i = attrs.length;
						while ( i-- ) {
	
							// Support: IE 11 only
							// The attrs elements can be null (#14894)
							if ( attrs[ i ] ) {
								name = attrs[ i ].name;
								if ( name.indexOf( "data-" ) === 0 ) {
									name = jQuery.camelCase( name.slice( 5 ) );
									dataAttr( elem, name, data[ name ] );
								}
							}
						}
						dataPriv.set( elem, "hasDataAttrs", true );
					}
				}
	
				return data;
			}
	
			// Sets multiple values
			if ( typeof key === "object" ) {
				return this.each( function() {
					dataUser.set( this, key );
				} );
			}
	
			return access( this, function( value ) {
				var data;
	
				// The calling jQuery object (element matches) is not empty
				// (and therefore has an element appears at this[ 0 ]) and the
				// `value` parameter was not undefined. An empty jQuery object
				// will result in `undefined` for elem = this[ 0 ] which will
				// throw an exception if an attempt to read a data cache is made.
				if ( elem && value === undefined ) {
	
					// Attempt to get data from the cache
					// The key will always be camelCased in Data
					data = dataUser.get( elem, key );
					if ( data !== undefined ) {
						return data;
					}
	
					// Attempt to "discover" the data in
					// HTML5 custom data-* attrs
					data = dataAttr( elem, key );
					if ( data !== undefined ) {
						return data;
					}
	
					// We tried really hard, but the data doesn't exist.
					return;
				}
	
				// Set the data...
				this.each( function() {
	
					// We always store the camelCased key
					dataUser.set( this, key, value );
				} );
			}, null, value, arguments.length > 1, null, true );
		},
	
		removeData: function( key ) {
			return this.each( function() {
				dataUser.remove( this, key );
			} );
		}
	} );
	
	
	jQuery.extend( {
		queue: function( elem, type, data ) {
			var queue;
	
			if ( elem ) {
				type = ( type || "fx" ) + "queue";
				queue = dataPriv.get( elem, type );
	
				// Speed up dequeue by getting out quickly if this is just a lookup
				if ( data ) {
					if ( !queue || Array.isArray( data ) ) {
						queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
					} else {
						queue.push( data );
					}
				}
				return queue || [];
			}
		},
	
		dequeue: function( elem, type ) {
			type = type || "fx";
	
			var queue = jQuery.queue( elem, type ),
				startLength = queue.length,
				fn = queue.shift(),
				hooks = jQuery._queueHooks( elem, type ),
				next = function() {
					jQuery.dequeue( elem, type );
				};
	
			// If the fx queue is dequeued, always remove the progress sentinel
			if ( fn === "inprogress" ) {
				fn = queue.shift();
				startLength--;
			}
	
			if ( fn ) {
	
				// Add a progress sentinel to prevent the fx queue from being
				// automatically dequeued
				if ( type === "fx" ) {
					queue.unshift( "inprogress" );
				}
	
				// Clear up the last queue stop function
				delete hooks.stop;
				fn.call( elem, next, hooks );
			}
	
			if ( !startLength && hooks ) {
				hooks.empty.fire();
			}
		},
	
		// Not public - generate a queueHooks object, or return the current one
		_queueHooks: function( elem, type ) {
			var key = type + "queueHooks";
			return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
				empty: jQuery.Callbacks( "once memory" ).add( function() {
					dataPriv.remove( elem, [ type + "queue", key ] );
				} )
			} );
		}
	} );
	
	jQuery.fn.extend( {
		queue: function( type, data ) {
			var setter = 2;
	
			if ( typeof type !== "string" ) {
				data = type;
				type = "fx";
				setter--;
			}
	
			if ( arguments.length < setter ) {
				return jQuery.queue( this[ 0 ], type );
			}
	
			return data === undefined ?
				this :
				this.each( function() {
					var queue = jQuery.queue( this, type, data );
	
					// Ensure a hooks for this queue
					jQuery._queueHooks( this, type );
	
					if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
						jQuery.dequeue( this, type );
					}
				} );
		},
		dequeue: function( type ) {
			return this.each( function() {
				jQuery.dequeue( this, type );
			} );
		},
		clearQueue: function( type ) {
			return this.queue( type || "fx", [] );
		},
	
		// Get a promise resolved when queues of a certain type
		// are emptied (fx is the type by default)
		promise: function( type, obj ) {
			var tmp,
				count = 1,
				defer = jQuery.Deferred(),
				elements = this,
				i = this.length,
				resolve = function() {
					if ( !( --count ) ) {
						defer.resolveWith( elements, [ elements ] );
					}
				};
	
			if ( typeof type !== "string" ) {
				obj = type;
				type = undefined;
			}
			type = type || "fx";
	
			while ( i-- ) {
				tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
				if ( tmp && tmp.empty ) {
					count++;
					tmp.empty.add( resolve );
				}
			}
			resolve();
			return defer.promise( obj );
		}
	} );
	var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
	
	var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
	
	
	var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
	
	var isHiddenWithinTree = function( elem, el ) {
	
			// isHiddenWithinTree might be called from jQuery#filter function;
			// in that case, element will be second argument
			elem = el || elem;
	
			// Inline style trumps all
			return elem.style.display === "none" ||
				elem.style.display === "" &&
	
				// Otherwise, check computed style
				// Support: Firefox <=43 - 45
				// Disconnected elements can have computed display: none, so first confirm that elem is
				// in the document.
				jQuery.contains( elem.ownerDocument, elem ) &&
	
				jQuery.css( elem, "display" ) === "none";
		};
	
	var swap = function( elem, options, callback, args ) {
		var ret, name,
			old = {};
	
		// Remember the old values, and insert the new ones
		for ( name in options ) {
			old[ name ] = elem.style[ name ];
			elem.style[ name ] = options[ name ];
		}
	
		ret = callback.apply( elem, args || [] );
	
		// Revert the old values
		for ( name in options ) {
			elem.style[ name ] = old[ name ];
		}
	
		return ret;
	};
	
	
	
	
	function adjustCSS( elem, prop, valueParts, tween ) {
		var adjusted,
			scale = 1,
			maxIterations = 20,
			currentValue = tween ?
				function() {
					return tween.cur();
				} :
				function() {
					return jQuery.css( elem, prop, "" );
				},
			initial = currentValue(),
			unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
	
			// Starting value computation is required for potential unit mismatches
			initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
				rcssNum.exec( jQuery.css( elem, prop ) );
	
		if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
	
			// Trust units reported by jQuery.css
			unit = unit || initialInUnit[ 3 ];
	
			// Make sure we update the tween properties later on
			valueParts = valueParts || [];
	
			// Iteratively approximate from a nonzero starting point
			initialInUnit = +initial || 1;
	
			do {
	
				// If previous iteration zeroed out, double until we get *something*.
				// Use string for doubling so we don't accidentally see scale as unchanged below
				scale = scale || ".5";
	
				// Adjust and apply
				initialInUnit = initialInUnit / scale;
				jQuery.style( elem, prop, initialInUnit + unit );
	
			// Update scale, tolerating zero or NaN from tween.cur()
			// Break the loop if scale is unchanged or perfect, or if we've just had enough.
			} while (
				scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
			);
		}
	
		if ( valueParts ) {
			initialInUnit = +initialInUnit || +initial || 0;
	
			// Apply relative offset (+=/-=) if specified
			adjusted = valueParts[ 1 ] ?
				initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
				+valueParts[ 2 ];
			if ( tween ) {
				tween.unit = unit;
				tween.start = initialInUnit;
				tween.end = adjusted;
			}
		}
		return adjusted;
	}
	
	
	var defaultDisplayMap = {};
	
	function getDefaultDisplay( elem ) {
		var temp,
			doc = elem.ownerDocument,
			nodeName = elem.nodeName,
			display = defaultDisplayMap[ nodeName ];
	
		if ( display ) {
			return display;
		}
	
		temp = doc.body.appendChild( doc.createElement( nodeName ) );
		display = jQuery.css( temp, "display" );
	
		temp.parentNode.removeChild( temp );
	
		if ( display === "none" ) {
			display = "block";
		}
		defaultDisplayMap[ nodeName ] = display;
	
		return display;
	}
	
	function showHide( elements, show ) {
		var display, elem,
			values = [],
			index = 0,
			length = elements.length;
	
		// Determine new display value for elements that need to change
		for ( ; index < length; index++ ) {
			elem = elements[ index ];
			if ( !elem.style ) {
				continue;
			}
	
			display = elem.style.display;
			if ( show ) {
	
				// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
				// check is required in this first loop unless we have a nonempty display value (either
				// inline or about-to-be-restored)
				if ( display === "none" ) {
					values[ index ] = dataPriv.get( elem, "display" ) || null;
					if ( !values[ index ] ) {
						elem.style.display = "";
					}
				}
				if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
					values[ index ] = getDefaultDisplay( elem );
				}
			} else {
				if ( display !== "none" ) {
					values[ index ] = "none";
	
					// Remember what we're overwriting
					dataPriv.set( elem, "display", display );
				}
			}
		}
	
		// Set the display of the elements in a second loop to avoid constant reflow
		for ( index = 0; index < length; index++ ) {
			if ( values[ index ] != null ) {
				elements[ index ].style.display = values[ index ];
			}
		}
	
		return elements;
	}
	
	jQuery.fn.extend( {
		show: function() {
			return showHide( this, true );
		},
		hide: function() {
			return showHide( this );
		},
		toggle: function( state ) {
			if ( typeof state === "boolean" ) {
				return state ? this.show() : this.hide();
			}
	
			return this.each( function() {
				if ( isHiddenWithinTree( this ) ) {
					jQuery( this ).show();
				} else {
					jQuery( this ).hide();
				}
			} );
		}
	} );
	var rcheckableType = ( /^(?:checkbox|radio)$/i );
	
	var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
	
	var rscriptType = ( /^$|\/(?:java|ecma)script/i );
	
	
	
	// We have to close these tags to support XHTML (#13200)
	var wrapMap = {
	
		// Support: IE <=9 only
		option: [ 1, "<select multiple='multiple'>", "</select>" ],
	
		// XHTML parsers do not magically insert elements in the
		// same way that tag soup parsers do. So we cannot shorten
		// this by omitting <tbody> or other required elements.
		thead: [ 1, "<table>", "</table>" ],
		col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
	
		_default: [ 0, "", "" ]
	};
	
	// Support: IE <=9 only
	wrapMap.optgroup = wrapMap.option;
	
	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
	wrapMap.th = wrapMap.td;
	
	
	function getAll( context, tag ) {
	
		// Support: IE <=9 - 11 only
		// Use typeof to avoid zero-argument method invocation on host objects (#15151)
		var ret;
	
		if ( typeof context.getElementsByTagName !== "undefined" ) {
			ret = context.getElementsByTagName( tag || "*" );
	
		} else if ( typeof context.querySelectorAll !== "undefined" ) {
			ret = context.querySelectorAll( tag || "*" );
	
		} else {
			ret = [];
		}
	
		if ( tag === undefined || tag && nodeName( context, tag ) ) {
			return jQuery.merge( [ context ], ret );
		}
	
		return ret;
	}
	
	
	// Mark scripts as having already been evaluated
	function setGlobalEval( elems, refElements ) {
		var i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			dataPriv.set(
				elems[ i ],
				"globalEval",
				!refElements || dataPriv.get( refElements[ i ], "globalEval" )
			);
		}
	}
	
	
	var rhtml = /<|&#?\w+;/;
	
	function buildFragment( elems, context, scripts, selection, ignored ) {
		var elem, tmp, tag, wrap, contains, j,
			fragment = context.createDocumentFragment(),
			nodes = [],
			i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			elem = elems[ i ];
	
			if ( elem || elem === 0 ) {
	
				// Add nodes directly
				if ( jQuery.type( elem ) === "object" ) {
	
					// Support: Android <=4.0 only, PhantomJS 1 only
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
	
				// Convert non-html into a text node
				} else if ( !rhtml.test( elem ) ) {
					nodes.push( context.createTextNode( elem ) );
	
				// Convert html into DOM nodes
				} else {
					tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
	
					// Deserialize a standard representation
					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
					wrap = wrapMap[ tag ] || wrapMap._default;
					tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
	
					// Descend through wrappers to the right content
					j = wrap[ 0 ];
					while ( j-- ) {
						tmp = tmp.lastChild;
					}
	
					// Support: Android <=4.0 only, PhantomJS 1 only
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, tmp.childNodes );
	
					// Remember the top-level container
					tmp = fragment.firstChild;
	
					// Ensure the created nodes are orphaned (#12392)
					tmp.textContent = "";
				}
			}
		}
	
		// Remove wrapper from fragment
		fragment.textContent = "";
	
		i = 0;
		while ( ( elem = nodes[ i++ ] ) ) {
	
			// Skip elements already in the context collection (trac-4087)
			if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
				if ( ignored ) {
					ignored.push( elem );
				}
				continue;
			}
	
			contains = jQuery.contains( elem.ownerDocument, elem );
	
			// Append to fragment
			tmp = getAll( fragment.appendChild( elem ), "script" );
	
			// Preserve script evaluation history
			if ( contains ) {
				setGlobalEval( tmp );
			}
	
			// Capture executables
			if ( scripts ) {
				j = 0;
				while ( ( elem = tmp[ j++ ] ) ) {
					if ( rscriptType.test( elem.type || "" ) ) {
						scripts.push( elem );
					}
				}
			}
		}
	
		return fragment;
	}
	
	
	( function() {
		var fragment = document.createDocumentFragment(),
			div = fragment.appendChild( document.createElement( "div" ) ),
			input = document.createElement( "input" );
	
		// Support: Android 4.0 - 4.3 only
		// Check state lost if the name is set (#11217)
		// Support: Windows Web Apps (WWA)
		// `name` and `type` must use .setAttribute for WWA (#14901)
		input.setAttribute( "type", "radio" );
		input.setAttribute( "checked", "checked" );
		input.setAttribute( "name", "t" );
	
		div.appendChild( input );
	
		// Support: Android <=4.1 only
		// Older WebKit doesn't clone checked state correctly in fragments
		support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
	
		// Support: IE <=11 only
		// Make sure textarea (and checkbox) defaultValue is properly cloned
		div.innerHTML = "<textarea>x</textarea>";
		support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
	} )();
	var documentElement = document.documentElement;
	
	
	
	var
		rkeyEvent = /^key/,
		rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
		rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
	
	function returnTrue() {
		return true;
	}
	
	function returnFalse() {
		return false;
	}
	
	// Support: IE <=9 only
	// See #13393 for more info
	function safeActiveElement() {
		try {
			return document.activeElement;
		} catch ( err ) { }
	}
	
	function on( elem, types, selector, data, fn, one ) {
		var origFn, type;
	
		// Types can be a map of types/handlers
		if ( typeof types === "object" ) {
	
			// ( types-Object, selector, data )
			if ( typeof selector !== "string" ) {
	
				// ( types-Object, data )
				data = data || selector;
				selector = undefined;
			}
			for ( type in types ) {
				on( elem, type, selector, data, types[ type ], one );
			}
			return elem;
		}
	
		if ( data == null && fn == null ) {
	
			// ( types, fn )
			fn = selector;
			data = selector = undefined;
		} else if ( fn == null ) {
			if ( typeof selector === "string" ) {
	
				// ( types, selector, fn )
				fn = data;
				data = undefined;
			} else {
	
				// ( types, data, fn )
				fn = data;
				data = selector;
				selector = undefined;
			}
		}
		if ( fn === false ) {
			fn = returnFalse;
		} else if ( !fn ) {
			return elem;
		}
	
		if ( one === 1 ) {
			origFn = fn;
			fn = function( event ) {
	
				// Can use an empty set, since event contains the info
				jQuery().off( event );
				return origFn.apply( this, arguments );
			};
	
			// Use same guid so caller can remove using origFn
			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
		}
		return elem.each( function() {
			jQuery.event.add( this, types, fn, data, selector );
		} );
	}
	
	/*
	 * Helper functions for managing events -- not part of the public interface.
	 * Props to Dean Edwards' addEvent library for many of the ideas.
	 */
	jQuery.event = {
	
		global: {},
	
		add: function( elem, types, handler, data, selector ) {
	
			var handleObjIn, eventHandle, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.get( elem );
	
			// Don't attach events to noData or text/comment nodes (but allow plain objects)
			if ( !elemData ) {
				return;
			}
	
			// Caller can pass in an object of custom data in lieu of the handler
			if ( handler.handler ) {
				handleObjIn = handler;
				handler = handleObjIn.handler;
				selector = handleObjIn.selector;
			}
	
			// Ensure that invalid selectors throw exceptions at attach time
			// Evaluate against documentElement in case elem is a non-element node (e.g., document)
			if ( selector ) {
				jQuery.find.matchesSelector( documentElement, selector );
			}
	
			// Make sure that the handler has a unique ID, used to find/remove it later
			if ( !handler.guid ) {
				handler.guid = jQuery.guid++;
			}
	
			// Init the element's event structure and main handler, if this is the first
			if ( !( events = elemData.events ) ) {
				events = elemData.events = {};
			}
			if ( !( eventHandle = elemData.handle ) ) {
				eventHandle = elemData.handle = function( e ) {
	
					// Discard the second event of a jQuery.event.trigger() and
					// when an event is called after a page has unloaded
					return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
						jQuery.event.dispatch.apply( elem, arguments ) : undefined;
				};
			}
	
			// Handle multiple events separated by a space
			types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// There *must* be a type, no attaching namespace-only handlers
				if ( !type ) {
					continue;
				}
	
				// If event changes its type, use the special event handlers for the changed type
				special = jQuery.event.special[ type ] || {};
	
				// If selector defined, determine special event api type, otherwise given type
				type = ( selector ? special.delegateType : special.bindType ) || type;
	
				// Update special based on newly reset type
				special = jQuery.event.special[ type ] || {};
	
				// handleObj is passed to all event handlers
				handleObj = jQuery.extend( {
					type: type,
					origType: origType,
					data: data,
					handler: handler,
					guid: handler.guid,
					selector: selector,
					needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
					namespace: namespaces.join( "." )
				}, handleObjIn );
	
				// Init the event handler queue if we're the first
				if ( !( handlers = events[ type ] ) ) {
					handlers = events[ type ] = [];
					handlers.delegateCount = 0;
	
					// Only use addEventListener if the special events handler returns false
					if ( !special.setup ||
						special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
	
						if ( elem.addEventListener ) {
							elem.addEventListener( type, eventHandle );
						}
					}
				}
	
				if ( special.add ) {
					special.add.call( elem, handleObj );
	
					if ( !handleObj.handler.guid ) {
						handleObj.handler.guid = handler.guid;
					}
				}
	
				// Add to the element's handler list, delegates in front
				if ( selector ) {
					handlers.splice( handlers.delegateCount++, 0, handleObj );
				} else {
					handlers.push( handleObj );
				}
	
				// Keep track of which events have ever been used, for event optimization
				jQuery.event.global[ type ] = true;
			}
	
		},
	
		// Detach an event or set of events from an element
		remove: function( elem, types, handler, selector, mappedTypes ) {
	
			var j, origCount, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
	
			if ( !elemData || !( events = elemData.events ) ) {
				return;
			}
	
			// Once for each type.namespace in types; type may be omitted
			types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// Unbind all events (on this namespace, if provided) for the element
				if ( !type ) {
					for ( type in events ) {
						jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
					}
					continue;
				}
	
				special = jQuery.event.special[ type ] || {};
				type = ( selector ? special.delegateType : special.bindType ) || type;
				handlers = events[ type ] || [];
				tmp = tmp[ 2 ] &&
					new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
	
				// Remove matching events
				origCount = j = handlers.length;
				while ( j-- ) {
					handleObj = handlers[ j ];
	
					if ( ( mappedTypes || origType === handleObj.origType ) &&
						( !handler || handler.guid === handleObj.guid ) &&
						( !tmp || tmp.test( handleObj.namespace ) ) &&
						( !selector || selector === handleObj.selector ||
							selector === "**" && handleObj.selector ) ) {
						handlers.splice( j, 1 );
	
						if ( handleObj.selector ) {
							handlers.delegateCount--;
						}
						if ( special.remove ) {
							special.remove.call( elem, handleObj );
						}
					}
				}
	
				// Remove generic event handler if we removed something and no more handlers exist
				// (avoids potential for endless recursion during removal of special event handlers)
				if ( origCount && !handlers.length ) {
					if ( !special.teardown ||
						special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
	
						jQuery.removeEvent( elem, type, elemData.handle );
					}
	
					delete events[ type ];
				}
			}
	
			// Remove data and the expando if it's no longer used
			if ( jQuery.isEmptyObject( events ) ) {
				dataPriv.remove( elem, "handle events" );
			}
		},
	
		dispatch: function( nativeEvent ) {
	
			// Make a writable jQuery.Event from the native event object
			var event = jQuery.event.fix( nativeEvent );
	
			var i, j, ret, matched, handleObj, handlerQueue,
				args = new Array( arguments.length ),
				handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
				special = jQuery.event.special[ event.type ] || {};
	
			// Use the fix-ed jQuery.Event rather than the (read-only) native event
			args[ 0 ] = event;
	
			for ( i = 1; i < arguments.length; i++ ) {
				args[ i ] = arguments[ i ];
			}
	
			event.delegateTarget = this;
	
			// Call the preDispatch hook for the mapped type, and let it bail if desired
			if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
				return;
			}
	
			// Determine handlers
			handlerQueue = jQuery.event.handlers.call( this, event, handlers );
	
			// Run delegates first; they may want to stop propagation beneath us
			i = 0;
			while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
				event.currentTarget = matched.elem;
	
				j = 0;
				while ( ( handleObj = matched.handlers[ j++ ] ) &&
					!event.isImmediatePropagationStopped() ) {
	
					// Triggered event must either 1) have no namespace, or 2) have namespace(s)
					// a subset or equal to those in the bound event (both can have no namespace).
					if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
	
						event.handleObj = handleObj;
						event.data = handleObj.data;
	
						ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
							handleObj.handler ).apply( matched.elem, args );
	
						if ( ret !== undefined ) {
							if ( ( event.result = ret ) === false ) {
								event.preventDefault();
								event.stopPropagation();
							}
						}
					}
				}
			}
	
			// Call the postDispatch hook for the mapped type
			if ( special.postDispatch ) {
				special.postDispatch.call( this, event );
			}
	
			return event.result;
		},
	
		handlers: function( event, handlers ) {
			var i, handleObj, sel, matchedHandlers, matchedSelectors,
				handlerQueue = [],
				delegateCount = handlers.delegateCount,
				cur = event.target;
	
			// Find delegate handlers
			if ( delegateCount &&
	
				// Support: IE <=9
				// Black-hole SVG <use> instance trees (trac-13180)
				cur.nodeType &&
	
				// Support: Firefox <=42
				// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
				// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
				// Support: IE 11 only
				// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
				!( event.type === "click" && event.button >= 1 ) ) {
	
				for ( ; cur !== this; cur = cur.parentNode || this ) {
	
					// Don't check non-elements (#13208)
					// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
					if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
						matchedHandlers = [];
						matchedSelectors = {};
						for ( i = 0; i < delegateCount; i++ ) {
							handleObj = handlers[ i ];
	
							// Don't conflict with Object.prototype properties (#13203)
							sel = handleObj.selector + " ";
	
							if ( matchedSelectors[ sel ] === undefined ) {
								matchedSelectors[ sel ] = handleObj.needsContext ?
									jQuery( sel, this ).index( cur ) > -1 :
									jQuery.find( sel, this, null, [ cur ] ).length;
							}
							if ( matchedSelectors[ sel ] ) {
								matchedHandlers.push( handleObj );
							}
						}
						if ( matchedHandlers.length ) {
							handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
						}
					}
				}
			}
	
			// Add the remaining (directly-bound) handlers
			cur = this;
			if ( delegateCount < handlers.length ) {
				handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
			}
	
			return handlerQueue;
		},
	
		addProp: function( name, hook ) {
			Object.defineProperty( jQuery.Event.prototype, name, {
				enumerable: true,
				configurable: true,
	
				get: jQuery.isFunction( hook ) ?
					function() {
						if ( this.originalEvent ) {
								return hook( this.originalEvent );
						}
					} :
					function() {
						if ( this.originalEvent ) {
								return this.originalEvent[ name ];
						}
					},
	
				set: function( value ) {
					Object.defineProperty( this, name, {
						enumerable: true,
						configurable: true,
						writable: true,
						value: value
					} );
				}
			} );
		},
	
		fix: function( originalEvent ) {
			return originalEvent[ jQuery.expando ] ?
				originalEvent :
				new jQuery.Event( originalEvent );
		},
	
		special: {
			load: {
	
				// Prevent triggered image.load events from bubbling to window.load
				noBubble: true
			},
			focus: {
	
				// Fire native event if possible so blur/focus sequence is correct
				trigger: function() {
					if ( this !== safeActiveElement() && this.focus ) {
						this.focus();
						return false;
					}
				},
				delegateType: "focusin"
			},
			blur: {
				trigger: function() {
					if ( this === safeActiveElement() && this.blur ) {
						this.blur();
						return false;
					}
				},
				delegateType: "focusout"
			},
			click: {
	
				// For checkbox, fire native event so checked state will be right
				trigger: function() {
					if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
						this.click();
						return false;
					}
				},
	
				// For cross-browser consistency, don't fire native .click() on links
				_default: function( event ) {
					return nodeName( event.target, "a" );
				}
			},
	
			beforeunload: {
				postDispatch: function( event ) {
	
					// Support: Firefox 20+
					// Firefox doesn't alert if the returnValue field is not set.
					if ( event.result !== undefined && event.originalEvent ) {
						event.originalEvent.returnValue = event.result;
					}
				}
			}
		}
	};
	
	jQuery.removeEvent = function( elem, type, handle ) {
	
		// This "if" is needed for plain objects
		if ( elem.removeEventListener ) {
			elem.removeEventListener( type, handle );
		}
	};
	
	jQuery.Event = function( src, props ) {
	
		// Allow instantiation without the 'new' keyword
		if ( !( this instanceof jQuery.Event ) ) {
			return new jQuery.Event( src, props );
		}
	
		// Event object
		if ( src && src.type ) {
			this.originalEvent = src;
			this.type = src.type;
	
			// Events bubbling up the document may have been marked as prevented
			// by a handler lower down the tree; reflect the correct value.
			this.isDefaultPrevented = src.defaultPrevented ||
					src.defaultPrevented === undefined &&
	
					// Support: Android <=2.3 only
					src.returnValue === false ?
				returnTrue :
				returnFalse;
	
			// Create target properties
			// Support: Safari <=6 - 7 only
			// Target should not be a text node (#504, #13143)
			this.target = ( src.target && src.target.nodeType === 3 ) ?
				src.target.parentNode :
				src.target;
	
			this.currentTarget = src.currentTarget;
			this.relatedTarget = src.relatedTarget;
	
		// Event type
		} else {
			this.type = src;
		}
	
		// Put explicitly provided properties onto the event object
		if ( props ) {
			jQuery.extend( this, props );
		}
	
		// Create a timestamp if incoming event doesn't have one
		this.timeStamp = src && src.timeStamp || jQuery.now();
	
		// Mark it as fixed
		this[ jQuery.expando ] = true;
	};
	
	// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
	// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
	jQuery.Event.prototype = {
		constructor: jQuery.Event,
		isDefaultPrevented: returnFalse,
		isPropagationStopped: returnFalse,
		isImmediatePropagationStopped: returnFalse,
		isSimulated: false,
	
		preventDefault: function() {
			var e = this.originalEvent;
	
			this.isDefaultPrevented = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.preventDefault();
			}
		},
		stopPropagation: function() {
			var e = this.originalEvent;
	
			this.isPropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopPropagation();
			}
		},
		stopImmediatePropagation: function() {
			var e = this.originalEvent;
	
			this.isImmediatePropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopImmediatePropagation();
			}
	
			this.stopPropagation();
		}
	};
	
	// Includes all common event props including KeyEvent and MouseEvent specific props
	jQuery.each( {
		altKey: true,
		bubbles: true,
		cancelable: true,
		changedTouches: true,
		ctrlKey: true,
		detail: true,
		eventPhase: true,
		metaKey: true,
		pageX: true,
		pageY: true,
		shiftKey: true,
		view: true,
		"char": true,
		charCode: true,
		key: true,
		keyCode: true,
		button: true,
		buttons: true,
		clientX: true,
		clientY: true,
		offsetX: true,
		offsetY: true,
		pointerId: true,
		pointerType: true,
		screenX: true,
		screenY: true,
		targetTouches: true,
		toElement: true,
		touches: true,
	
		which: function( event ) {
			var button = event.button;
	
			// Add which for key events
			if ( event.which == null && rkeyEvent.test( event.type ) ) {
				return event.charCode != null ? event.charCode : event.keyCode;
			}
	
			// Add which for click: 1 === left; 2 === middle; 3 === right
			if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
				if ( button & 1 ) {
					return 1;
				}
	
				if ( button & 2 ) {
					return 3;
				}
	
				if ( button & 4 ) {
					return 2;
				}
	
				return 0;
			}
	
			return event.which;
		}
	}, jQuery.event.addProp );
	
	// Create mouseenter/leave events using mouseover/out and event-time checks
	// so that event delegation works in jQuery.
	// Do the same for pointerenter/pointerleave and pointerover/pointerout
	//
	// Support: Safari 7 only
	// Safari sends mouseenter too often; see:
	// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
	// for the description of the bug (it existed in older Chrome versions as well).
	jQuery.each( {
		mouseenter: "mouseover",
		mouseleave: "mouseout",
		pointerenter: "pointerover",
		pointerleave: "pointerout"
	}, function( orig, fix ) {
		jQuery.event.special[ orig ] = {
			delegateType: fix,
			bindType: fix,
	
			handle: function( event ) {
				var ret,
					target = this,
					related = event.relatedTarget,
					handleObj = event.handleObj;
	
				// For mouseenter/leave call the handler if related is outside the target.
				// NB: No relatedTarget if the mouse left/entered the browser window
				if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
					event.type = handleObj.origType;
					ret = handleObj.handler.apply( this, arguments );
					event.type = fix;
				}
				return ret;
			}
		};
	} );
	
	jQuery.fn.extend( {
	
		on: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn );
		},
		one: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn, 1 );
		},
		off: function( types, selector, fn ) {
			var handleObj, type;
			if ( types && types.preventDefault && types.handleObj ) {
	
				// ( event )  dispatched jQuery.Event
				handleObj = types.handleObj;
				jQuery( types.delegateTarget ).off(
					handleObj.namespace ?
						handleObj.origType + "." + handleObj.namespace :
						handleObj.origType,
					handleObj.selector,
					handleObj.handler
				);
				return this;
			}
			if ( typeof types === "object" ) {
	
				// ( types-object [, selector] )
				for ( type in types ) {
					this.off( type, selector, types[ type ] );
				}
				return this;
			}
			if ( selector === false || typeof selector === "function" ) {
	
				// ( types [, fn] )
				fn = selector;
				selector = undefined;
			}
			if ( fn === false ) {
				fn = returnFalse;
			}
			return this.each( function() {
				jQuery.event.remove( this, types, fn, selector );
			} );
		}
	} );
	
	
	var
	
		/* eslint-disable max-len */
	
		// See https://github.com/eslint/eslint/issues/3229
		rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
	
		/* eslint-enable */
	
		// Support: IE <=10 - 11, Edge 12 - 13
		// In IE/Edge using regex groups here causes severe slowdowns.
		// See https://connect.microsoft.com/IE/feedback/details/1736512/
		rnoInnerhtml = /<script|<style|<link/i,
	
		// checked="checked" or checked
		rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
		rscriptTypeMasked = /^true\/(.*)/,
		rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
	
	// Prefer a tbody over its parent table for containing new rows
	function manipulationTarget( elem, content ) {
		if ( nodeName( elem, "table" ) &&
			nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
	
			return jQuery( ">tbody", elem )[ 0 ] || elem;
		}
	
		return elem;
	}
	
	// Replace/restore the type attribute of script elements for safe DOM manipulation
	function disableScript( elem ) {
		elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
		return elem;
	}
	function restoreScript( elem ) {
		var match = rscriptTypeMasked.exec( elem.type );
	
		if ( match ) {
			elem.type = match[ 1 ];
		} else {
			elem.removeAttribute( "type" );
		}
	
		return elem;
	}
	
	function cloneCopyEvent( src, dest ) {
		var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
	
		if ( dest.nodeType !== 1 ) {
			return;
		}
	
		// 1. Copy private data: events, handlers, etc.
		if ( dataPriv.hasData( src ) ) {
			pdataOld = dataPriv.access( src );
			pdataCur = dataPriv.set( dest, pdataOld );
			events = pdataOld.events;
	
			if ( events ) {
				delete pdataCur.handle;
				pdataCur.events = {};
	
				for ( type in events ) {
					for ( i = 0, l = events[ type ].length; i < l; i++ ) {
						jQuery.event.add( dest, type, events[ type ][ i ] );
					}
				}
			}
		}
	
		// 2. Copy user data
		if ( dataUser.hasData( src ) ) {
			udataOld = dataUser.access( src );
			udataCur = jQuery.extend( {}, udataOld );
	
			dataUser.set( dest, udataCur );
		}
	}
	
	// Fix IE bugs, see support tests
	function fixInput( src, dest ) {
		var nodeName = dest.nodeName.toLowerCase();
	
		// Fails to persist the checked state of a cloned checkbox or radio button.
		if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
			dest.checked = src.checked;
	
		// Fails to return the selected option to the default selected state when cloning options
		} else if ( nodeName === "input" || nodeName === "textarea" ) {
			dest.defaultValue = src.defaultValue;
		}
	}
	
	function domManip( collection, args, callback, ignored ) {
	
		// Flatten any nested arrays
		args = concat.apply( [], args );
	
		var fragment, first, scripts, hasScripts, node, doc,
			i = 0,
			l = collection.length,
			iNoClone = l - 1,
			value = args[ 0 ],
			isFunction = jQuery.isFunction( value );
	
		// We can't cloneNode fragments that contain checked, in WebKit
		if ( isFunction ||
				( l > 1 && typeof value === "string" &&
					!support.checkClone && rchecked.test( value ) ) ) {
			return collection.each( function( index ) {
				var self = collection.eq( index );
				if ( isFunction ) {
					args[ 0 ] = value.call( this, index, self.html() );
				}
				domManip( self, args, callback, ignored );
			} );
		}
	
		if ( l ) {
			fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
			first = fragment.firstChild;
	
			if ( fragment.childNodes.length === 1 ) {
				fragment = first;
			}
	
			// Require either new content or an interest in ignored elements to invoke the callback
			if ( first || ignored ) {
				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
				hasScripts = scripts.length;
	
				// Use the original fragment for the last item
				// instead of the first because it can end up
				// being emptied incorrectly in certain situations (#8070).
				for ( ; i < l; i++ ) {
					node = fragment;
	
					if ( i !== iNoClone ) {
						node = jQuery.clone( node, true, true );
	
						// Keep references to cloned scripts for later restoration
						if ( hasScripts ) {
	
							// Support: Android <=4.0 only, PhantomJS 1 only
							// push.apply(_, arraylike) throws on ancient WebKit
							jQuery.merge( scripts, getAll( node, "script" ) );
						}
					}
	
					callback.call( collection[ i ], node, i );
				}
	
				if ( hasScripts ) {
					doc = scripts[ scripts.length - 1 ].ownerDocument;
	
					// Reenable scripts
					jQuery.map( scripts, restoreScript );
	
					// Evaluate executable scripts on first document insertion
					for ( i = 0; i < hasScripts; i++ ) {
						node = scripts[ i ];
						if ( rscriptType.test( node.type || "" ) &&
							!dataPriv.access( node, "globalEval" ) &&
							jQuery.contains( doc, node ) ) {
	
							if ( node.src ) {
	
								// Optional AJAX dependency, but won't run scripts if not present
								if ( jQuery._evalUrl ) {
									jQuery._evalUrl( node.src );
								}
							} else {
								DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
							}
						}
					}
				}
			}
		}
	
		return collection;
	}
	
	function remove( elem, selector, keepData ) {
		var node,
			nodes = selector ? jQuery.filter( selector, elem ) : elem,
			i = 0;
	
		for ( ; ( node = nodes[ i ] ) != null; i++ ) {
			if ( !keepData && node.nodeType === 1 ) {
				jQuery.cleanData( getAll( node ) );
			}
	
			if ( node.parentNode ) {
				if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
					setGlobalEval( getAll( node, "script" ) );
				}
				node.parentNode.removeChild( node );
			}
		}
	
		return elem;
	}
	
	jQuery.extend( {
		htmlPrefilter: function( html ) {
			return html.replace( rxhtmlTag, "<$1></$2>" );
		},
	
		clone: function( elem, dataAndEvents, deepDataAndEvents ) {
			var i, l, srcElements, destElements,
				clone = elem.cloneNode( true ),
				inPage = jQuery.contains( elem.ownerDocument, elem );
	
			// Fix IE cloning issues
			if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
					!jQuery.isXMLDoc( elem ) ) {
	
				// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
				destElements = getAll( clone );
				srcElements = getAll( elem );
	
				for ( i = 0, l = srcElements.length; i < l; i++ ) {
					fixInput( srcElements[ i ], destElements[ i ] );
				}
			}
	
			// Copy the events from the original to the clone
			if ( dataAndEvents ) {
				if ( deepDataAndEvents ) {
					srcElements = srcElements || getAll( elem );
					destElements = destElements || getAll( clone );
	
					for ( i = 0, l = srcElements.length; i < l; i++ ) {
						cloneCopyEvent( srcElements[ i ], destElements[ i ] );
					}
				} else {
					cloneCopyEvent( elem, clone );
				}
			}
	
			// Preserve script evaluation history
			destElements = getAll( clone, "script" );
			if ( destElements.length > 0 ) {
				setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
			}
	
			// Return the cloned set
			return clone;
		},
	
		cleanData: function( elems ) {
			var data, elem, type,
				special = jQuery.event.special,
				i = 0;
	
			for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
				if ( acceptData( elem ) ) {
					if ( ( data = elem[ dataPriv.expando ] ) ) {
						if ( data.events ) {
							for ( type in data.events ) {
								if ( special[ type ] ) {
									jQuery.event.remove( elem, type );
	
								// This is a shortcut to avoid jQuery.event.remove's overhead
								} else {
									jQuery.removeEvent( elem, type, data.handle );
								}
							}
						}
	
						// Support: Chrome <=35 - 45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataPriv.expando ] = undefined;
					}
					if ( elem[ dataUser.expando ] ) {
	
						// Support: Chrome <=35 - 45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataUser.expando ] = undefined;
					}
				}
			}
		}
	} );
	
	jQuery.fn.extend( {
		detach: function( selector ) {
			return remove( this, selector, true );
		},
	
		remove: function( selector ) {
			return remove( this, selector );
		},
	
		text: function( value ) {
			return access( this, function( value ) {
				return value === undefined ?
					jQuery.text( this ) :
					this.empty().each( function() {
						if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
							this.textContent = value;
						}
					} );
			}, null, value, arguments.length );
		},
	
		append: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.appendChild( elem );
				}
			} );
		},
	
		prepend: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.insertBefore( elem, target.firstChild );
				}
			} );
		},
	
		before: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this );
				}
			} );
		},
	
		after: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this.nextSibling );
				}
			} );
		},
	
		empty: function() {
			var elem,
				i = 0;
	
			for ( ; ( elem = this[ i ] ) != null; i++ ) {
				if ( elem.nodeType === 1 ) {
	
					// Prevent memory leaks
					jQuery.cleanData( getAll( elem, false ) );
	
					// Remove any remaining nodes
					elem.textContent = "";
				}
			}
	
			return this;
		},
	
		clone: function( dataAndEvents, deepDataAndEvents ) {
			dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
			deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
	
			return this.map( function() {
				return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
			} );
		},
	
		html: function( value ) {
			return access( this, function( value ) {
				var elem = this[ 0 ] || {},
					i = 0,
					l = this.length;
	
				if ( value === undefined && elem.nodeType === 1 ) {
					return elem.innerHTML;
				}
	
				// See if we can take a shortcut and just use innerHTML
				if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
					!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
	
					value = jQuery.htmlPrefilter( value );
	
					try {
						for ( ; i < l; i++ ) {
							elem = this[ i ] || {};
	
							// Remove element nodes and prevent memory leaks
							if ( elem.nodeType === 1 ) {
								jQuery.cleanData( getAll( elem, false ) );
								elem.innerHTML = value;
							}
						}
	
						elem = 0;
	
					// If using innerHTML throws an exception, use the fallback method
					} catch ( e ) {}
				}
	
				if ( elem ) {
					this.empty().append( value );
				}
			}, null, value, arguments.length );
		},
	
		replaceWith: function() {
			var ignored = [];
	
			// Make the changes, replacing each non-ignored context element with the new content
			return domManip( this, arguments, function( elem ) {
				var parent = this.parentNode;
	
				if ( jQuery.inArray( this, ignored ) < 0 ) {
					jQuery.cleanData( getAll( this ) );
					if ( parent ) {
						parent.replaceChild( elem, this );
					}
				}
	
			// Force callback invocation
			}, ignored );
		}
	} );
	
	jQuery.each( {
		appendTo: "append",
		prependTo: "prepend",
		insertBefore: "before",
		insertAfter: "after",
		replaceAll: "replaceWith"
	}, function( name, original ) {
		jQuery.fn[ name ] = function( selector ) {
			var elems,
				ret = [],
				insert = jQuery( selector ),
				last = insert.length - 1,
				i = 0;
	
			for ( ; i <= last; i++ ) {
				elems = i === last ? this : this.clone( true );
				jQuery( insert[ i ] )[ original ]( elems );
	
				// Support: Android <=4.0 only, PhantomJS 1 only
				// .get() because push.apply(_, arraylike) throws on ancient WebKit
				push.apply( ret, elems.get() );
			}
	
			return this.pushStack( ret );
		};
	} );
	var rmargin = ( /^margin/ );
	
	var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
	
	var getStyles = function( elem ) {
	
			// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
			// IE throws on elements created in popups
			// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
			var view = elem.ownerDocument.defaultView;
	
			if ( !view || !view.opener ) {
				view = window;
			}
	
			return view.getComputedStyle( elem );
		};
	
	
	
	( function() {
	
		// Executing both pixelPosition & boxSizingReliable tests require only one layout
		// so they're executed at the same time to save the second computation.
		function computeStyleTests() {
	
			// This is a singleton, we need to execute it only once
			if ( !div ) {
				return;
			}
	
			div.style.cssText =
				"box-sizing:border-box;" +
				"position:relative;display:block;" +
				"margin:auto;border:1px;padding:1px;" +
				"top:1%;width:50%";
			div.innerHTML = "";
			documentElement.appendChild( container );
	
			var divStyle = window.getComputedStyle( div );
			pixelPositionVal = divStyle.top !== "1%";
	
			// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
			reliableMarginLeftVal = divStyle.marginLeft === "2px";
			boxSizingReliableVal = divStyle.width === "4px";
	
			// Support: Android 4.0 - 4.3 only
			// Some styles come back with percentage values, even though they shouldn't
			div.style.marginRight = "50%";
			pixelMarginRightVal = divStyle.marginRight === "4px";
	
			documentElement.removeChild( container );
	
			// Nullify the div so it wouldn't be stored in the memory and
			// it will also be a sign that checks already performed
			div = null;
		}
	
		var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
			container = document.createElement( "div" ),
			div = document.createElement( "div" );
	
		// Finish early in limited (non-browser) environments
		if ( !div.style ) {
			return;
		}
	
		// Support: IE <=9 - 11 only
		// Style of cloned element affects source element cloned (#8908)
		div.style.backgroundClip = "content-box";
		div.cloneNode( true ).style.backgroundClip = "";
		support.clearCloneStyle = div.style.backgroundClip === "content-box";
	
		container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
			"padding:0;margin-top:1px;position:absolute";
		container.appendChild( div );
	
		jQuery.extend( support, {
			pixelPosition: function() {
				computeStyleTests();
				return pixelPositionVal;
			},
			boxSizingReliable: function() {
				computeStyleTests();
				return boxSizingReliableVal;
			},
			pixelMarginRight: function() {
				computeStyleTests();
				return pixelMarginRightVal;
			},
			reliableMarginLeft: function() {
				computeStyleTests();
				return reliableMarginLeftVal;
			}
		} );
	} )();
	
	
	function curCSS( elem, name, computed ) {
		var width, minWidth, maxWidth, ret,
	
			// Support: Firefox 51+
			// Retrieving style before computed somehow
			// fixes an issue with getting wrong values
			// on detached elements
			style = elem.style;
	
		computed = computed || getStyles( elem );
	
		// getPropertyValue is needed for:
		//   .css('filter') (IE 9 only, #12537)
		//   .css('--customProperty) (#3144)
		if ( computed ) {
			ret = computed.getPropertyValue( name ) || computed[ name ];
	
			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
				ret = jQuery.style( elem, name );
			}
	
			// A tribute to the "awesome hack by Dean Edwards"
			// Android Browser returns percentage for some values,
			// but width seems to be reliably pixels.
			// This is against the CSSOM draft spec:
			// https://drafts.csswg.org/cssom/#resolved-values
			if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
	
				// Remember the original values
				width = style.width;
				minWidth = style.minWidth;
				maxWidth = style.maxWidth;
	
				// Put in the new values to get a computed value out
				style.minWidth = style.maxWidth = style.width = ret;
				ret = computed.width;
	
				// Revert the changed values
				style.width = width;
				style.minWidth = minWidth;
				style.maxWidth = maxWidth;
			}
		}
	
		return ret !== undefined ?
	
			// Support: IE <=9 - 11 only
			// IE returns zIndex value as an integer.
			ret + "" :
			ret;
	}
	
	
	function addGetHookIf( conditionFn, hookFn ) {
	
		// Define the hook, we'll check on the first run if it's really needed.
		return {
			get: function() {
				if ( conditionFn() ) {
	
					// Hook not needed (or it's not possible to use it due
					// to missing dependency), remove it.
					delete this.get;
					return;
				}
	
				// Hook needed; redefine it so that the support test is not executed again.
				return ( this.get = hookFn ).apply( this, arguments );
			}
		};
	}
	
	
	var
	
		// Swappable if display is none or starts with table
		// except "table", "table-cell", or "table-caption"
		// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
		rdisplayswap = /^(none|table(?!-c[ea]).+)/,
		rcustomProp = /^--/,
		cssShow = { position: "absolute", visibility: "hidden", display: "block" },
		cssNormalTransform = {
			letterSpacing: "0",
			fontWeight: "400"
		},
	
		cssPrefixes = [ "Webkit", "Moz", "ms" ],
		emptyStyle = document.createElement( "div" ).style;
	
	// Return a css property mapped to a potentially vendor prefixed property
	function vendorPropName( name ) {
	
		// Shortcut for names that are not vendor prefixed
		if ( name in emptyStyle ) {
			return name;
		}
	
		// Check for vendor prefixed names
		var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
			i = cssPrefixes.length;
	
		while ( i-- ) {
			name = cssPrefixes[ i ] + capName;
			if ( name in emptyStyle ) {
				return name;
			}
		}
	}
	
	// Return a property mapped along what jQuery.cssProps suggests or to
	// a vendor prefixed property.
	function finalPropName( name ) {
		var ret = jQuery.cssProps[ name ];
		if ( !ret ) {
			ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
		}
		return ret;
	}
	
	function setPositiveNumber( elem, value, subtract ) {
	
		// Any relative (+/-) values have already been
		// normalized at this point
		var matches = rcssNum.exec( value );
		return matches ?
	
			// Guard against undefined "subtract", e.g., when used as in cssHooks
			Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
			value;
	}
	
	function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
		var i,
			val = 0;
	
		// If we already have the right measurement, avoid augmentation
		if ( extra === ( isBorderBox ? "border" : "content" ) ) {
			i = 4;
	
		// Otherwise initialize for horizontal or vertical properties
		} else {
			i = name === "width" ? 1 : 0;
		}
	
		for ( ; i < 4; i += 2 ) {
	
			// Both box models exclude margin, so add it if we want it
			if ( extra === "margin" ) {
				val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
			}
	
			if ( isBorderBox ) {
	
				// border-box includes padding, so remove it if we want content
				if ( extra === "content" ) {
					val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
				}
	
				// At this point, extra isn't border nor margin, so remove border
				if ( extra !== "margin" ) {
					val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			} else {
	
				// At this point, extra isn't content, so add padding
				val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
	
				// At this point, extra isn't content nor padding, so add border
				if ( extra !== "padding" ) {
					val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			}
		}
	
		return val;
	}
	
	function getWidthOrHeight( elem, name, extra ) {
	
		// Start with computed style
		var valueIsBorderBox,
			styles = getStyles( elem ),
			val = curCSS( elem, name, styles ),
			isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
	
		// Computed unit is not pixels. Stop here and return.
		if ( rnumnonpx.test( val ) ) {
			return val;
		}
	
		// Check for style in case a browser which returns unreliable values
		// for getComputedStyle silently falls back to the reliable elem.style
		valueIsBorderBox = isBorderBox &&
			( support.boxSizingReliable() || val === elem.style[ name ] );
	
		// Fall back to offsetWidth/Height when value is "auto"
		// This happens for inline elements with no explicit setting (gh-3571)
		if ( val === "auto" ) {
			val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
		}
	
		// Normalize "", auto, and prepare for extra
		val = parseFloat( val ) || 0;
	
		// Use the active box-sizing model to add/subtract irrelevant styles
		return ( val +
			augmentWidthOrHeight(
				elem,
				name,
				extra || ( isBorderBox ? "border" : "content" ),
				valueIsBorderBox,
				styles
			)
		) + "px";
	}
	
	jQuery.extend( {
	
		// Add in style property hooks for overriding the default
		// behavior of getting and setting a style property
		cssHooks: {
			opacity: {
				get: function( elem, computed ) {
					if ( computed ) {
	
						// We should always get a number back from opacity
						var ret = curCSS( elem, "opacity" );
						return ret === "" ? "1" : ret;
					}
				}
			}
		},
	
		// Don't automatically add "px" to these possibly-unitless properties
		cssNumber: {
			"animationIterationCount": true,
			"columnCount": true,
			"fillOpacity": true,
			"flexGrow": true,
			"flexShrink": true,
			"fontWeight": true,
			"lineHeight": true,
			"opacity": true,
			"order": true,
			"orphans": true,
			"widows": true,
			"zIndex": true,
			"zoom": true
		},
	
		// Add in properties whose names you wish to fix before
		// setting or getting the value
		cssProps: {
			"float": "cssFloat"
		},
	
		// Get and set the style property on a DOM Node
		style: function( elem, name, value, extra ) {
	
			// Don't set styles on text and comment nodes
			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
				return;
			}
	
			// Make sure that we're working with the right name
			var ret, type, hooks,
				origName = jQuery.camelCase( name ),
				isCustomProp = rcustomProp.test( name ),
				style = elem.style;
	
			// Make sure that we're working with the right name. We don't
			// want to query the value if it is a CSS custom property
			// since they are user-defined.
			if ( !isCustomProp ) {
				name = finalPropName( origName );
			}
	
			// Gets hook for the prefixed version, then unprefixed version
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// Check if we're setting a value
			if ( value !== undefined ) {
				type = typeof value;
	
				// Convert "+=" or "-=" to relative numbers (#7345)
				if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
					value = adjustCSS( elem, name, ret );
	
					// Fixes bug #9237
					type = "number";
				}
	
				// Make sure that null and NaN values aren't set (#7116)
				if ( value == null || value !== value ) {
					return;
				}
	
				// If a number was passed in, add the unit (except for certain CSS properties)
				if ( type === "number" ) {
					value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
				}
	
				// background-* props affect original clone's values
				if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
					style[ name ] = "inherit";
				}
	
				// If a hook was provided, use that value, otherwise just set the specified value
				if ( !hooks || !( "set" in hooks ) ||
					( value = hooks.set( elem, value, extra ) ) !== undefined ) {
	
					if ( isCustomProp ) {
						style.setProperty( name, value );
					} else {
						style[ name ] = value;
					}
				}
	
			} else {
	
				// If a hook was provided get the non-computed value from there
				if ( hooks && "get" in hooks &&
					( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
	
					return ret;
				}
	
				// Otherwise just get the value from the style object
				return style[ name ];
			}
		},
	
		css: function( elem, name, extra, styles ) {
			var val, num, hooks,
				origName = jQuery.camelCase( name ),
				isCustomProp = rcustomProp.test( name );
	
			// Make sure that we're working with the right name. We don't
			// want to modify the value if it is a CSS custom property
			// since they are user-defined.
			if ( !isCustomProp ) {
				name = finalPropName( origName );
			}
	
			// Try prefixed name followed by the unprefixed name
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// If a hook was provided get the computed value from there
			if ( hooks && "get" in hooks ) {
				val = hooks.get( elem, true, extra );
			}
	
			// Otherwise, if a way to get the computed value exists, use that
			if ( val === undefined ) {
				val = curCSS( elem, name, styles );
			}
	
			// Convert "normal" to computed value
			if ( val === "normal" && name in cssNormalTransform ) {
				val = cssNormalTransform[ name ];
			}
	
			// Make numeric if forced or a qualifier was provided and val looks numeric
			if ( extra === "" || extra ) {
				num = parseFloat( val );
				return extra === true || isFinite( num ) ? num || 0 : val;
			}
	
			return val;
		}
	} );
	
	jQuery.each( [ "height", "width" ], function( i, name ) {
		jQuery.cssHooks[ name ] = {
			get: function( elem, computed, extra ) {
				if ( computed ) {
	
					// Certain elements can have dimension info if we invisibly show them
					// but it must have a current display style that would benefit
					return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
	
						// Support: Safari 8+
						// Table columns in Safari have non-zero offsetWidth & zero
						// getBoundingClientRect().width unless display is changed.
						// Support: IE <=11 only
						// Running getBoundingClientRect on a disconnected node
						// in IE throws an error.
						( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
							swap( elem, cssShow, function() {
								return getWidthOrHeight( elem, name, extra );
							} ) :
							getWidthOrHeight( elem, name, extra );
				}
			},
	
			set: function( elem, value, extra ) {
				var matches,
					styles = extra && getStyles( elem ),
					subtract = extra && augmentWidthOrHeight(
						elem,
						name,
						extra,
						jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
						styles
					);
	
				// Convert to pixels if value adjustment is needed
				if ( subtract && ( matches = rcssNum.exec( value ) ) &&
					( matches[ 3 ] || "px" ) !== "px" ) {
	
					elem.style[ name ] = value;
					value = jQuery.css( elem, name );
				}
	
				return setPositiveNumber( elem, value, subtract );
			}
		};
	} );
	
	jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
		function( elem, computed ) {
			if ( computed ) {
				return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
					elem.getBoundingClientRect().left -
						swap( elem, { marginLeft: 0 }, function() {
							return elem.getBoundingClientRect().left;
						} )
					) + "px";
			}
		}
	);
	
	// These hooks are used by animate to expand properties
	jQuery.each( {
		margin: "",
		padding: "",
		border: "Width"
	}, function( prefix, suffix ) {
		jQuery.cssHooks[ prefix + suffix ] = {
			expand: function( value ) {
				var i = 0,
					expanded = {},
	
					// Assumes a single number if not a string
					parts = typeof value === "string" ? value.split( " " ) : [ value ];
	
				for ( ; i < 4; i++ ) {
					expanded[ prefix + cssExpand[ i ] + suffix ] =
						parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
				}
	
				return expanded;
			}
		};
	
		if ( !rmargin.test( prefix ) ) {
			jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
		}
	} );
	
	jQuery.fn.extend( {
		css: function( name, value ) {
			return access( this, function( elem, name, value ) {
				var styles, len,
					map = {},
					i = 0;
	
				if ( Array.isArray( name ) ) {
					styles = getStyles( elem );
					len = name.length;
	
					for ( ; i < len; i++ ) {
						map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
					}
	
					return map;
				}
	
				return value !== undefined ?
					jQuery.style( elem, name, value ) :
					jQuery.css( elem, name );
			}, name, value, arguments.length > 1 );
		}
	} );
	
	
	function Tween( elem, options, prop, end, easing ) {
		return new Tween.prototype.init( elem, options, prop, end, easing );
	}
	jQuery.Tween = Tween;
	
	Tween.prototype = {
		constructor: Tween,
		init: function( elem, options, prop, end, easing, unit ) {
			this.elem = elem;
			this.prop = prop;
			this.easing = easing || jQuery.easing._default;
			this.options = options;
			this.start = this.now = this.cur();
			this.end = end;
			this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
		},
		cur: function() {
			var hooks = Tween.propHooks[ this.prop ];
	
			return hooks && hooks.get ?
				hooks.get( this ) :
				Tween.propHooks._default.get( this );
		},
		run: function( percent ) {
			var eased,
				hooks = Tween.propHooks[ this.prop ];
	
			if ( this.options.duration ) {
				this.pos = eased = jQuery.easing[ this.easing ](
					percent, this.options.duration * percent, 0, 1, this.options.duration
				);
			} else {
				this.pos = eased = percent;
			}
			this.now = ( this.end - this.start ) * eased + this.start;
	
			if ( this.options.step ) {
				this.options.step.call( this.elem, this.now, this );
			}
	
			if ( hooks && hooks.set ) {
				hooks.set( this );
			} else {
				Tween.propHooks._default.set( this );
			}
			return this;
		}
	};
	
	Tween.prototype.init.prototype = Tween.prototype;
	
	Tween.propHooks = {
		_default: {
			get: function( tween ) {
				var result;
	
				// Use a property on the element directly when it is not a DOM element,
				// or when there is no matching style property that exists.
				if ( tween.elem.nodeType !== 1 ||
					tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
					return tween.elem[ tween.prop ];
				}
	
				// Passing an empty string as a 3rd parameter to .css will automatically
				// attempt a parseFloat and fallback to a string if the parse fails.
				// Simple values such as "10px" are parsed to Float;
				// complex values such as "rotate(1rad)" are returned as-is.
				result = jQuery.css( tween.elem, tween.prop, "" );
	
				// Empty strings, null, undefined and "auto" are converted to 0.
				return !result || result === "auto" ? 0 : result;
			},
			set: function( tween ) {
	
				// Use step hook for back compat.
				// Use cssHook if its there.
				// Use .style if available and use plain properties where available.
				if ( jQuery.fx.step[ tween.prop ] ) {
					jQuery.fx.step[ tween.prop ]( tween );
				} else if ( tween.elem.nodeType === 1 &&
					( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
						jQuery.cssHooks[ tween.prop ] ) ) {
					jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
				} else {
					tween.elem[ tween.prop ] = tween.now;
				}
			}
		}
	};
	
	// Support: IE <=9 only
	// Panic based approach to setting things on disconnected nodes
	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
		set: function( tween ) {
			if ( tween.elem.nodeType && tween.elem.parentNode ) {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	};
	
	jQuery.easing = {
		linear: function( p ) {
			return p;
		},
		swing: function( p ) {
			return 0.5 - Math.cos( p * Math.PI ) / 2;
		},
		_default: "swing"
	};
	
	jQuery.fx = Tween.prototype.init;
	
	// Back compat <1.8 extension point
	jQuery.fx.step = {};
	
	
	
	
	var
		fxNow, inProgress,
		rfxtypes = /^(?:toggle|show|hide)$/,
		rrun = /queueHooks$/;
	
	function schedule() {
		if ( inProgress ) {
			if ( document.hidden === false && window.requestAnimationFrame ) {
				window.requestAnimationFrame( schedule );
			} else {
				window.setTimeout( schedule, jQuery.fx.interval );
			}
	
			jQuery.fx.tick();
		}
	}
	
	// Animations created synchronously will run synchronously
	function createFxNow() {
		window.setTimeout( function() {
			fxNow = undefined;
		} );
		return ( fxNow = jQuery.now() );
	}
	
	// Generate parameters to create a standard animation
	function genFx( type, includeWidth ) {
		var which,
			i = 0,
			attrs = { height: type };
	
		// If we include width, step value is 1 to do all cssExpand values,
		// otherwise step value is 2 to skip over Left and Right
		includeWidth = includeWidth ? 1 : 0;
		for ( ; i < 4; i += 2 - includeWidth ) {
			which = cssExpand[ i ];
			attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
		}
	
		if ( includeWidth ) {
			attrs.opacity = attrs.width = type;
		}
	
		return attrs;
	}
	
	function createTween( value, prop, animation ) {
		var tween,
			collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
			index = 0,
			length = collection.length;
		for ( ; index < length; index++ ) {
			if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
	
				// We're done with this property
				return tween;
			}
		}
	}
	
	function defaultPrefilter( elem, props, opts ) {
		var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
			isBox = "width" in props || "height" in props,
			anim = this,
			orig = {},
			style = elem.style,
			hidden = elem.nodeType && isHiddenWithinTree( elem ),
			dataShow = dataPriv.get( elem, "fxshow" );
	
		// Queue-skipping animations hijack the fx hooks
		if ( !opts.queue ) {
			hooks = jQuery._queueHooks( elem, "fx" );
			if ( hooks.unqueued == null ) {
				hooks.unqueued = 0;
				oldfire = hooks.empty.fire;
				hooks.empty.fire = function() {
					if ( !hooks.unqueued ) {
						oldfire();
					}
				};
			}
			hooks.unqueued++;
	
			anim.always( function() {
	
				// Ensure the complete handler is called before this completes
				anim.always( function() {
					hooks.unqueued--;
					if ( !jQuery.queue( elem, "fx" ).length ) {
						hooks.empty.fire();
					}
				} );
			} );
		}
	
		// Detect show/hide animations
		for ( prop in props ) {
			value = props[ prop ];
			if ( rfxtypes.test( value ) ) {
				delete props[ prop ];
				toggle = toggle || value === "toggle";
				if ( value === ( hidden ? "hide" : "show" ) ) {
	
					// Pretend to be hidden if this is a "show" and
					// there is still data from a stopped show/hide
					if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
						hidden = true;
	
					// Ignore all other no-op show/hide data
					} else {
						continue;
					}
				}
				orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
			}
		}
	
		// Bail out if this is a no-op like .hide().hide()
		propTween = !jQuery.isEmptyObject( props );
		if ( !propTween && jQuery.isEmptyObject( orig ) ) {
			return;
		}
	
		// Restrict "overflow" and "display" styles during box animations
		if ( isBox && elem.nodeType === 1 ) {
	
			// Support: IE <=9 - 11, Edge 12 - 13
			// Record all 3 overflow attributes because IE does not infer the shorthand
			// from identically-valued overflowX and overflowY
			opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
	
			// Identify a display type, preferring old show/hide data over the CSS cascade
			restoreDisplay = dataShow && dataShow.display;
			if ( restoreDisplay == null ) {
				restoreDisplay = dataPriv.get( elem, "display" );
			}
			display = jQuery.css( elem, "display" );
			if ( display === "none" ) {
				if ( restoreDisplay ) {
					display = restoreDisplay;
				} else {
	
					// Get nonempty value(s) by temporarily forcing visibility
					showHide( [ elem ], true );
					restoreDisplay = elem.style.display || restoreDisplay;
					display = jQuery.css( elem, "display" );
					showHide( [ elem ] );
				}
			}
	
			// Animate inline elements as inline-block
			if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
				if ( jQuery.css( elem, "float" ) === "none" ) {
	
					// Restore the original display value at the end of pure show/hide animations
					if ( !propTween ) {
						anim.done( function() {
							style.display = restoreDisplay;
						} );
						if ( restoreDisplay == null ) {
							display = style.display;
							restoreDisplay = display === "none" ? "" : display;
						}
					}
					style.display = "inline-block";
				}
			}
		}
	
		if ( opts.overflow ) {
			style.overflow = "hidden";
			anim.always( function() {
				style.overflow = opts.overflow[ 0 ];
				style.overflowX = opts.overflow[ 1 ];
				style.overflowY = opts.overflow[ 2 ];
			} );
		}
	
		// Implement show/hide animations
		propTween = false;
		for ( prop in orig ) {
	
			// General show/hide setup for this element animation
			if ( !propTween ) {
				if ( dataShow ) {
					if ( "hidden" in dataShow ) {
						hidden = dataShow.hidden;
					}
				} else {
					dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
				}
	
				// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
				if ( toggle ) {
					dataShow.hidden = !hidden;
				}
	
				// Show elements before animating them
				if ( hidden ) {
					showHide( [ elem ], true );
				}
	
				/* eslint-disable no-loop-func */
	
				anim.done( function() {
	
				/* eslint-enable no-loop-func */
	
					// The final step of a "hide" animation is actually hiding the element
					if ( !hidden ) {
						showHide( [ elem ] );
					}
					dataPriv.remove( elem, "fxshow" );
					for ( prop in orig ) {
						jQuery.style( elem, prop, orig[ prop ] );
					}
				} );
			}
	
			// Per-property setup
			propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
			if ( !( prop in dataShow ) ) {
				dataShow[ prop ] = propTween.start;
				if ( hidden ) {
					propTween.end = propTween.start;
					propTween.start = 0;
				}
			}
		}
	}
	
	function propFilter( props, specialEasing ) {
		var index, name, easing, value, hooks;
	
		// camelCase, specialEasing and expand cssHook pass
		for ( index in props ) {
			name = jQuery.camelCase( index );
			easing = specialEasing[ name ];
			value = props[ index ];
			if ( Array.isArray( value ) ) {
				easing = value[ 1 ];
				value = props[ index ] = value[ 0 ];
			}
	
			if ( index !== name ) {
				props[ name ] = value;
				delete props[ index ];
			}
	
			hooks = jQuery.cssHooks[ name ];
			if ( hooks && "expand" in hooks ) {
				value = hooks.expand( value );
				delete props[ name ];
	
				// Not quite $.extend, this won't overwrite existing keys.
				// Reusing 'index' because we have the correct "name"
				for ( index in value ) {
					if ( !( index in props ) ) {
						props[ index ] = value[ index ];
						specialEasing[ index ] = easing;
					}
				}
			} else {
				specialEasing[ name ] = easing;
			}
		}
	}
	
	function Animation( elem, properties, options ) {
		var result,
			stopped,
			index = 0,
			length = Animation.prefilters.length,
			deferred = jQuery.Deferred().always( function() {
	
				// Don't match elem in the :animated selector
				delete tick.elem;
			} ),
			tick = function() {
				if ( stopped ) {
					return false;
				}
				var currentTime = fxNow || createFxNow(),
					remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
	
					// Support: Android 2.3 only
					// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
					temp = remaining / animation.duration || 0,
					percent = 1 - temp,
					index = 0,
					length = animation.tweens.length;
	
				for ( ; index < length; index++ ) {
					animation.tweens[ index ].run( percent );
				}
	
				deferred.notifyWith( elem, [ animation, percent, remaining ] );
	
				// If there's more to do, yield
				if ( percent < 1 && length ) {
					return remaining;
				}
	
				// If this was an empty animation, synthesize a final progress notification
				if ( !length ) {
					deferred.notifyWith( elem, [ animation, 1, 0 ] );
				}
	
				// Resolve the animation and report its conclusion
				deferred.resolveWith( elem, [ animation ] );
				return false;
			},
			animation = deferred.promise( {
				elem: elem,
				props: jQuery.extend( {}, properties ),
				opts: jQuery.extend( true, {
					specialEasing: {},
					easing: jQuery.easing._default
				}, options ),
				originalProperties: properties,
				originalOptions: options,
				startTime: fxNow || createFxNow(),
				duration: options.duration,
				tweens: [],
				createTween: function( prop, end ) {
					var tween = jQuery.Tween( elem, animation.opts, prop, end,
							animation.opts.specialEasing[ prop ] || animation.opts.easing );
					animation.tweens.push( tween );
					return tween;
				},
				stop: function( gotoEnd ) {
					var index = 0,
	
						// If we are going to the end, we want to run all the tweens
						// otherwise we skip this part
						length = gotoEnd ? animation.tweens.length : 0;
					if ( stopped ) {
						return this;
					}
					stopped = true;
					for ( ; index < length; index++ ) {
						animation.tweens[ index ].run( 1 );
					}
	
					// Resolve when we played the last frame; otherwise, reject
					if ( gotoEnd ) {
						deferred.notifyWith( elem, [ animation, 1, 0 ] );
						deferred.resolveWith( elem, [ animation, gotoEnd ] );
					} else {
						deferred.rejectWith( elem, [ animation, gotoEnd ] );
					}
					return this;
				}
			} ),
			props = animation.props;
	
		propFilter( props, animation.opts.specialEasing );
	
		for ( ; index < length; index++ ) {
			result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
			if ( result ) {
				if ( jQuery.isFunction( result.stop ) ) {
					jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
						jQuery.proxy( result.stop, result );
				}
				return result;
			}
		}
	
		jQuery.map( props, createTween, animation );
	
		if ( jQuery.isFunction( animation.opts.start ) ) {
			animation.opts.start.call( elem, animation );
		}
	
		// Attach callbacks from options
		animation
			.progress( animation.opts.progress )
			.done( animation.opts.done, animation.opts.complete )
			.fail( animation.opts.fail )
			.always( animation.opts.always );
	
		jQuery.fx.timer(
			jQuery.extend( tick, {
				elem: elem,
				anim: animation,
				queue: animation.opts.queue
			} )
		);
	
		return animation;
	}
	
	jQuery.Animation = jQuery.extend( Animation, {
	
		tweeners: {
			"*": [ function( prop, value ) {
				var tween = this.createTween( prop, value );
				adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
				return tween;
			} ]
		},
	
		tweener: function( props, callback ) {
			if ( jQuery.isFunction( props ) ) {
				callback = props;
				props = [ "*" ];
			} else {
				props = props.match( rnothtmlwhite );
			}
	
			var prop,
				index = 0,
				length = props.length;
	
			for ( ; index < length; index++ ) {
				prop = props[ index ];
				Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
				Animation.tweeners[ prop ].unshift( callback );
			}
		},
	
		prefilters: [ defaultPrefilter ],
	
		prefilter: function( callback, prepend ) {
			if ( prepend ) {
				Animation.prefilters.unshift( callback );
			} else {
				Animation.prefilters.push( callback );
			}
		}
	} );
	
	jQuery.speed = function( speed, easing, fn ) {
		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
			complete: fn || !fn && easing ||
				jQuery.isFunction( speed ) && speed,
			duration: speed,
			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
		};
	
		// Go to the end state if fx are off
		if ( jQuery.fx.off ) {
			opt.duration = 0;
	
		} else {
			if ( typeof opt.duration !== "number" ) {
				if ( opt.duration in jQuery.fx.speeds ) {
					opt.duration = jQuery.fx.speeds[ opt.duration ];
	
				} else {
					opt.duration = jQuery.fx.speeds._default;
				}
			}
		}
	
		// Normalize opt.queue - true/undefined/null -> "fx"
		if ( opt.queue == null || opt.queue === true ) {
			opt.queue = "fx";
		}
	
		// Queueing
		opt.old = opt.complete;
	
		opt.complete = function() {
			if ( jQuery.isFunction( opt.old ) ) {
				opt.old.call( this );
			}
	
			if ( opt.queue ) {
				jQuery.dequeue( this, opt.queue );
			}
		};
	
		return opt;
	};
	
	jQuery.fn.extend( {
		fadeTo: function( speed, to, easing, callback ) {
	
			// Show any hidden elements after setting opacity to 0
			return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
	
				// Animate to the value specified
				.end().animate( { opacity: to }, speed, easing, callback );
		},
		animate: function( prop, speed, easing, callback ) {
			var empty = jQuery.isEmptyObject( prop ),
				optall = jQuery.speed( speed, easing, callback ),
				doAnimation = function() {
	
					// Operate on a copy of prop so per-property easing won't be lost
					var anim = Animation( this, jQuery.extend( {}, prop ), optall );
	
					// Empty animations, or finishing resolves immediately
					if ( empty || dataPriv.get( this, "finish" ) ) {
						anim.stop( true );
					}
				};
				doAnimation.finish = doAnimation;
	
			return empty || optall.queue === false ?
				this.each( doAnimation ) :
				this.queue( optall.queue, doAnimation );
		},
		stop: function( type, clearQueue, gotoEnd ) {
			var stopQueue = function( hooks ) {
				var stop = hooks.stop;
				delete hooks.stop;
				stop( gotoEnd );
			};
	
			if ( typeof type !== "string" ) {
				gotoEnd = clearQueue;
				clearQueue = type;
				type = undefined;
			}
			if ( clearQueue && type !== false ) {
				this.queue( type || "fx", [] );
			}
	
			return this.each( function() {
				var dequeue = true,
					index = type != null && type + "queueHooks",
					timers = jQuery.timers,
					data = dataPriv.get( this );
	
				if ( index ) {
					if ( data[ index ] && data[ index ].stop ) {
						stopQueue( data[ index ] );
					}
				} else {
					for ( index in data ) {
						if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
							stopQueue( data[ index ] );
						}
					}
				}
	
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this &&
						( type == null || timers[ index ].queue === type ) ) {
	
						timers[ index ].anim.stop( gotoEnd );
						dequeue = false;
						timers.splice( index, 1 );
					}
				}
	
				// Start the next in the queue if the last step wasn't forced.
				// Timers currently will call their complete callbacks, which
				// will dequeue but only if they were gotoEnd.
				if ( dequeue || !gotoEnd ) {
					jQuery.dequeue( this, type );
				}
			} );
		},
		finish: function( type ) {
			if ( type !== false ) {
				type = type || "fx";
			}
			return this.each( function() {
				var index,
					data = dataPriv.get( this ),
					queue = data[ type + "queue" ],
					hooks = data[ type + "queueHooks" ],
					timers = jQuery.timers,
					length = queue ? queue.length : 0;
	
				// Enable finishing flag on private data
				data.finish = true;
	
				// Empty the queue first
				jQuery.queue( this, type, [] );
	
				if ( hooks && hooks.stop ) {
					hooks.stop.call( this, true );
				}
	
				// Look for any active animations, and finish them
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
						timers[ index ].anim.stop( true );
						timers.splice( index, 1 );
					}
				}
	
				// Look for any animations in the old queue and finish them
				for ( index = 0; index < length; index++ ) {
					if ( queue[ index ] && queue[ index ].finish ) {
						queue[ index ].finish.call( this );
					}
				}
	
				// Turn off finishing flag
				delete data.finish;
			} );
		}
	} );
	
	jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
		var cssFn = jQuery.fn[ name ];
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return speed == null || typeof speed === "boolean" ?
				cssFn.apply( this, arguments ) :
				this.animate( genFx( name, true ), speed, easing, callback );
		};
	} );
	
	// Generate shortcuts for custom animations
	jQuery.each( {
		slideDown: genFx( "show" ),
		slideUp: genFx( "hide" ),
		slideToggle: genFx( "toggle" ),
		fadeIn: { opacity: "show" },
		fadeOut: { opacity: "hide" },
		fadeToggle: { opacity: "toggle" }
	}, function( name, props ) {
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return this.animate( props, speed, easing, callback );
		};
	} );
	
	jQuery.timers = [];
	jQuery.fx.tick = function() {
		var timer,
			i = 0,
			timers = jQuery.timers;
	
		fxNow = jQuery.now();
	
		for ( ; i < timers.length; i++ ) {
			timer = timers[ i ];
	
			// Run the timer and safely remove it when done (allowing for external removal)
			if ( !timer() && timers[ i ] === timer ) {
				timers.splice( i--, 1 );
			}
		}
	
		if ( !timers.length ) {
			jQuery.fx.stop();
		}
		fxNow = undefined;
	};
	
	jQuery.fx.timer = function( timer ) {
		jQuery.timers.push( timer );
		jQuery.fx.start();
	};
	
	jQuery.fx.interval = 13;
	jQuery.fx.start = function() {
		if ( inProgress ) {
			return;
		}
	
		inProgress = true;
		schedule();
	};
	
	jQuery.fx.stop = function() {
		inProgress = null;
	};
	
	jQuery.fx.speeds = {
		slow: 600,
		fast: 200,
	
		// Default speed
		_default: 400
	};
	
	
	// Based off of the plugin by Clint Helfers, with permission.
	// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
	jQuery.fn.delay = function( time, type ) {
		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
		type = type || "fx";
	
		return this.queue( type, function( next, hooks ) {
			var timeout = window.setTimeout( next, time );
			hooks.stop = function() {
				window.clearTimeout( timeout );
			};
		} );
	};
	
	
	( function() {
		var input = document.createElement( "input" ),
			select = document.createElement( "select" ),
			opt = select.appendChild( document.createElement( "option" ) );
	
		input.type = "checkbox";
	
		// Support: Android <=4.3 only
		// Default value for a checkbox should be "on"
		support.checkOn = input.value !== "";
	
		// Support: IE <=11 only
		// Must access selectedIndex to make default options select
		support.optSelected = opt.selected;
	
		// Support: IE <=11 only
		// An input loses its value after becoming a radio
		input = document.createElement( "input" );
		input.value = "t";
		input.type = "radio";
		support.radioValue = input.value === "t";
	} )();
	
	
	var boolHook,
		attrHandle = jQuery.expr.attrHandle;
	
	jQuery.fn.extend( {
		attr: function( name, value ) {
			return access( this, jQuery.attr, name, value, arguments.length > 1 );
		},
	
		removeAttr: function( name ) {
			return this.each( function() {
				jQuery.removeAttr( this, name );
			} );
		}
	} );
	
	jQuery.extend( {
		attr: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set attributes on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			// Fallback to prop when attributes are not supported
			if ( typeof elem.getAttribute === "undefined" ) {
				return jQuery.prop( elem, name, value );
			}
	
			// Attribute hooks are determined by the lowercase version
			// Grab necessary hook if one is defined
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
				hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
					( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
			}
	
			if ( value !== undefined ) {
				if ( value === null ) {
					jQuery.removeAttr( elem, name );
					return;
				}
	
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				elem.setAttribute( name, value + "" );
				return value;
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			ret = jQuery.find.attr( elem, name );
	
			// Non-existent attributes return null, we normalize to undefined
			return ret == null ? undefined : ret;
		},
	
		attrHooks: {
			type: {
				set: function( elem, value ) {
					if ( !support.radioValue && value === "radio" &&
						nodeName( elem, "input" ) ) {
						var val = elem.value;
						elem.setAttribute( "type", value );
						if ( val ) {
							elem.value = val;
						}
						return value;
					}
				}
			}
		},
	
		removeAttr: function( elem, value ) {
			var name,
				i = 0,
	
				// Attribute names can contain non-HTML whitespace characters
				// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
				attrNames = value && value.match( rnothtmlwhite );
	
			if ( attrNames && elem.nodeType === 1 ) {
				while ( ( name = attrNames[ i++ ] ) ) {
					elem.removeAttribute( name );
				}
			}
		}
	} );
	
	// Hooks for boolean attributes
	boolHook = {
		set: function( elem, value, name ) {
			if ( value === false ) {
	
				// Remove boolean attributes when set to false
				jQuery.removeAttr( elem, name );
			} else {
				elem.setAttribute( name, name );
			}
			return name;
		}
	};
	
	jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
		var getter = attrHandle[ name ] || jQuery.find.attr;
	
		attrHandle[ name ] = function( elem, name, isXML ) {
			var ret, handle,
				lowercaseName = name.toLowerCase();
	
			if ( !isXML ) {
	
				// Avoid an infinite loop by temporarily removing this function from the getter
				handle = attrHandle[ lowercaseName ];
				attrHandle[ lowercaseName ] = ret;
				ret = getter( elem, name, isXML ) != null ?
					lowercaseName :
					null;
				attrHandle[ lowercaseName ] = handle;
			}
			return ret;
		};
	} );
	
	
	
	
	var rfocusable = /^(?:input|select|textarea|button)$/i,
		rclickable = /^(?:a|area)$/i;
	
	jQuery.fn.extend( {
		prop: function( name, value ) {
			return access( this, jQuery.prop, name, value, arguments.length > 1 );
		},
	
		removeProp: function( name ) {
			return this.each( function() {
				delete this[ jQuery.propFix[ name ] || name ];
			} );
		}
	} );
	
	jQuery.extend( {
		prop: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set properties on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
	
				// Fix name and attach hooks
				name = jQuery.propFix[ name ] || name;
				hooks = jQuery.propHooks[ name ];
			}
	
			if ( value !== undefined ) {
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				return ( elem[ name ] = value );
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			return elem[ name ];
		},
	
		propHooks: {
			tabIndex: {
				get: function( elem ) {
	
					// Support: IE <=9 - 11 only
					// elem.tabIndex doesn't always return the
					// correct value when it hasn't been explicitly set
					// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
					// Use proper attribute retrieval(#12072)
					var tabindex = jQuery.find.attr( elem, "tabindex" );
	
					if ( tabindex ) {
						return parseInt( tabindex, 10 );
					}
	
					if (
						rfocusable.test( elem.nodeName ) ||
						rclickable.test( elem.nodeName ) &&
						elem.href
					) {
						return 0;
					}
	
					return -1;
				}
			}
		},
	
		propFix: {
			"for": "htmlFor",
			"class": "className"
		}
	} );
	
	// Support: IE <=11 only
	// Accessing the selectedIndex property
	// forces the browser to respect setting selected
	// on the option
	// The getter ensures a default option is selected
	// when in an optgroup
	// eslint rule "no-unused-expressions" is disabled for this code
	// since it considers such accessions noop
	if ( !support.optSelected ) {
		jQuery.propHooks.selected = {
			get: function( elem ) {
	
				/* eslint no-unused-expressions: "off" */
	
				var parent = elem.parentNode;
				if ( parent && parent.parentNode ) {
					parent.parentNode.selectedIndex;
				}
				return null;
			},
			set: function( elem ) {
	
				/* eslint no-unused-expressions: "off" */
	
				var parent = elem.parentNode;
				if ( parent ) {
					parent.selectedIndex;
	
					if ( parent.parentNode ) {
						parent.parentNode.selectedIndex;
					}
				}
			}
		};
	}
	
	jQuery.each( [
		"tabIndex",
		"readOnly",
		"maxLength",
		"cellSpacing",
		"cellPadding",
		"rowSpan",
		"colSpan",
		"useMap",
		"frameBorder",
		"contentEditable"
	], function() {
		jQuery.propFix[ this.toLowerCase() ] = this;
	} );
	
	
	
	
		// Strip and collapse whitespace according to HTML spec
		// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
		function stripAndCollapse( value ) {
			var tokens = value.match( rnothtmlwhite ) || [];
			return tokens.join( " " );
		}
	
	
	function getClass( elem ) {
		return elem.getAttribute && elem.getAttribute( "class" ) || "";
	}
	
	jQuery.fn.extend( {
		addClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnothtmlwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
					cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
							if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
								cur += clazz + " ";
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = stripAndCollapse( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		removeClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( !arguments.length ) {
				return this.attr( "class", "" );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnothtmlwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
	
					// This expression is here for better compressibility (see addClass)
					cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
	
							// Remove *all* instances
							while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
								cur = cur.replace( " " + clazz + " ", " " );
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = stripAndCollapse( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		toggleClass: function( value, stateVal ) {
			var type = typeof value;
	
			if ( typeof stateVal === "boolean" && type === "string" ) {
				return stateVal ? this.addClass( value ) : this.removeClass( value );
			}
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( i ) {
					jQuery( this ).toggleClass(
						value.call( this, i, getClass( this ), stateVal ),
						stateVal
					);
				} );
			}
	
			return this.each( function() {
				var className, i, self, classNames;
	
				if ( type === "string" ) {
	
					// Toggle individual class names
					i = 0;
					self = jQuery( this );
					classNames = value.match( rnothtmlwhite ) || [];
	
					while ( ( className = classNames[ i++ ] ) ) {
	
						// Check each className given, space separated list
						if ( self.hasClass( className ) ) {
							self.removeClass( className );
						} else {
							self.addClass( className );
						}
					}
	
				// Toggle whole class name
				} else if ( value === undefined || type === "boolean" ) {
					className = getClass( this );
					if ( className ) {
	
						// Store className if set
						dataPriv.set( this, "__className__", className );
					}
	
					// If the element has a class name or if we're passed `false`,
					// then remove the whole classname (if there was one, the above saved it).
					// Otherwise bring back whatever was previously saved (if anything),
					// falling back to the empty string if nothing was stored.
					if ( this.setAttribute ) {
						this.setAttribute( "class",
							className || value === false ?
							"" :
							dataPriv.get( this, "__className__" ) || ""
						);
					}
				}
			} );
		},
	
		hasClass: function( selector ) {
			var className, elem,
				i = 0;
	
			className = " " + selector + " ";
			while ( ( elem = this[ i++ ] ) ) {
				if ( elem.nodeType === 1 &&
					( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
						return true;
				}
			}
	
			return false;
		}
	} );
	
	
	
	
	var rreturn = /\r/g;
	
	jQuery.fn.extend( {
		val: function( value ) {
			var hooks, ret, isFunction,
				elem = this[ 0 ];
	
			if ( !arguments.length ) {
				if ( elem ) {
					hooks = jQuery.valHooks[ elem.type ] ||
						jQuery.valHooks[ elem.nodeName.toLowerCase() ];
	
					if ( hooks &&
						"get" in hooks &&
						( ret = hooks.get( elem, "value" ) ) !== undefined
					) {
						return ret;
					}
	
					ret = elem.value;
	
					// Handle most common string cases
					if ( typeof ret === "string" ) {
						return ret.replace( rreturn, "" );
					}
	
					// Handle cases where value is null/undef or number
					return ret == null ? "" : ret;
				}
	
				return;
			}
	
			isFunction = jQuery.isFunction( value );
	
			return this.each( function( i ) {
				var val;
	
				if ( this.nodeType !== 1 ) {
					return;
				}
	
				if ( isFunction ) {
					val = value.call( this, i, jQuery( this ).val() );
				} else {
					val = value;
				}
	
				// Treat null/undefined as ""; convert numbers to string
				if ( val == null ) {
					val = "";
	
				} else if ( typeof val === "number" ) {
					val += "";
	
				} else if ( Array.isArray( val ) ) {
					val = jQuery.map( val, function( value ) {
						return value == null ? "" : value + "";
					} );
				}
	
				hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
	
				// If set returns undefined, fall back to normal setting
				if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
					this.value = val;
				}
			} );
		}
	} );
	
	jQuery.extend( {
		valHooks: {
			option: {
				get: function( elem ) {
	
					var val = jQuery.find.attr( elem, "value" );
					return val != null ?
						val :
	
						// Support: IE <=10 - 11 only
						// option.text throws exceptions (#14686, #14858)
						// Strip and collapse whitespace
						// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
						stripAndCollapse( jQuery.text( elem ) );
				}
			},
			select: {
				get: function( elem ) {
					var value, option, i,
						options = elem.options,
						index = elem.selectedIndex,
						one = elem.type === "select-one",
						values = one ? null : [],
						max = one ? index + 1 : options.length;
	
					if ( index < 0 ) {
						i = max;
	
					} else {
						i = one ? index : 0;
					}
	
					// Loop through all the selected options
					for ( ; i < max; i++ ) {
						option = options[ i ];
	
						// Support: IE <=9 only
						// IE8-9 doesn't update selected after form reset (#2551)
						if ( ( option.selected || i === index ) &&
	
								// Don't return options that are disabled or in a disabled optgroup
								!option.disabled &&
								( !option.parentNode.disabled ||
									!nodeName( option.parentNode, "optgroup" ) ) ) {
	
							// Get the specific value for the option
							value = jQuery( option ).val();
	
							// We don't need an array for one selects
							if ( one ) {
								return value;
							}
	
							// Multi-Selects return an array
							values.push( value );
						}
					}
	
					return values;
				},
	
				set: function( elem, value ) {
					var optionSet, option,
						options = elem.options,
						values = jQuery.makeArray( value ),
						i = options.length;
	
					while ( i-- ) {
						option = options[ i ];
	
						/* eslint-disable no-cond-assign */
	
						if ( option.selected =
							jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
						) {
							optionSet = true;
						}
	
						/* eslint-enable no-cond-assign */
					}
	
					// Force browsers to behave consistently when non-matching value is set
					if ( !optionSet ) {
						elem.selectedIndex = -1;
					}
					return values;
				}
			}
		}
	} );
	
	// Radios and checkboxes getter/setter
	jQuery.each( [ "radio", "checkbox" ], function() {
		jQuery.valHooks[ this ] = {
			set: function( elem, value ) {
				if ( Array.isArray( value ) ) {
					return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
				}
			}
		};
		if ( !support.checkOn ) {
			jQuery.valHooks[ this ].get = function( elem ) {
				return elem.getAttribute( "value" ) === null ? "on" : elem.value;
			};
		}
	} );
	
	
	
	
	// Return jQuery for attributes-only inclusion
	
	
	var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
	
	jQuery.extend( jQuery.event, {
	
		trigger: function( event, data, elem, onlyHandlers ) {
	
			var i, cur, tmp, bubbleType, ontype, handle, special,
				eventPath = [ elem || document ],
				type = hasOwn.call( event, "type" ) ? event.type : event,
				namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
	
			cur = tmp = elem = elem || document;
	
			// Don't do events on text and comment nodes
			if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
				return;
			}
	
			// focus/blur morphs to focusin/out; ensure we're not firing them right now
			if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
				return;
			}
	
			if ( type.indexOf( "." ) > -1 ) {
	
				// Namespaced trigger; create a regexp to match event type in handle()
				namespaces = type.split( "." );
				type = namespaces.shift();
				namespaces.sort();
			}
			ontype = type.indexOf( ":" ) < 0 && "on" + type;
	
			// Caller can pass in a jQuery.Event object, Object, or just an event type string
			event = event[ jQuery.expando ] ?
				event :
				new jQuery.Event( type, typeof event === "object" && event );
	
			// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
			event.isTrigger = onlyHandlers ? 2 : 3;
			event.namespace = namespaces.join( "." );
			event.rnamespace = event.namespace ?
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
				null;
	
			// Clean up the event in case it is being reused
			event.result = undefined;
			if ( !event.target ) {
				event.target = elem;
			}
	
			// Clone any incoming data and prepend the event, creating the handler arg list
			data = data == null ?
				[ event ] :
				jQuery.makeArray( data, [ event ] );
	
			// Allow special events to draw outside the lines
			special = jQuery.event.special[ type ] || {};
			if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
				return;
			}
	
			// Determine event propagation path in advance, per W3C events spec (#9951)
			// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
			if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
	
				bubbleType = special.delegateType || type;
				if ( !rfocusMorph.test( bubbleType + type ) ) {
					cur = cur.parentNode;
				}
				for ( ; cur; cur = cur.parentNode ) {
					eventPath.push( cur );
					tmp = cur;
				}
	
				// Only add window if we got to document (e.g., not plain obj or detached DOM)
				if ( tmp === ( elem.ownerDocument || document ) ) {
					eventPath.push( tmp.defaultView || tmp.parentWindow || window );
				}
			}
	
			// Fire handlers on the event path
			i = 0;
			while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
	
				event.type = i > 1 ?
					bubbleType :
					special.bindType || type;
	
				// jQuery handler
				handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
					dataPriv.get( cur, "handle" );
				if ( handle ) {
					handle.apply( cur, data );
				}
	
				// Native handler
				handle = ontype && cur[ ontype ];
				if ( handle && handle.apply && acceptData( cur ) ) {
					event.result = handle.apply( cur, data );
					if ( event.result === false ) {
						event.preventDefault();
					}
				}
			}
			event.type = type;
	
			// If nobody prevented the default action, do it now
			if ( !onlyHandlers && !event.isDefaultPrevented() ) {
	
				if ( ( !special._default ||
					special._default.apply( eventPath.pop(), data ) === false ) &&
					acceptData( elem ) ) {
	
					// Call a native DOM method on the target with the same name as the event.
					// Don't do default actions on window, that's where global variables be (#6170)
					if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
	
						// Don't re-trigger an onFOO event when we call its FOO() method
						tmp = elem[ ontype ];
	
						if ( tmp ) {
							elem[ ontype ] = null;
						}
	
						// Prevent re-triggering of the same event, since we already bubbled it above
						jQuery.event.triggered = type;
						elem[ type ]();
						jQuery.event.triggered = undefined;
	
						if ( tmp ) {
							elem[ ontype ] = tmp;
						}
					}
				}
			}
	
			return event.result;
		},
	
		// Piggyback on a donor event to simulate a different one
		// Used only for `focus(in | out)` events
		simulate: function( type, elem, event ) {
			var e = jQuery.extend(
				new jQuery.Event(),
				event,
				{
					type: type,
					isSimulated: true
				}
			);
	
			jQuery.event.trigger( e, null, elem );
		}
	
	} );
	
	jQuery.fn.extend( {
	
		trigger: function( type, data ) {
			return this.each( function() {
				jQuery.event.trigger( type, data, this );
			} );
		},
		triggerHandler: function( type, data ) {
			var elem = this[ 0 ];
			if ( elem ) {
				return jQuery.event.trigger( type, data, elem, true );
			}
		}
	} );
	
	
	jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
		"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
		"change select submit keydown keypress keyup contextmenu" ).split( " " ),
		function( i, name ) {
	
		// Handle event binding
		jQuery.fn[ name ] = function( data, fn ) {
			return arguments.length > 0 ?
				this.on( name, null, data, fn ) :
				this.trigger( name );
		};
	} );
	
	jQuery.fn.extend( {
		hover: function( fnOver, fnOut ) {
			return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
		}
	} );
	
	
	
	
	support.focusin = "onfocusin" in window;
	
	
	// Support: Firefox <=44
	// Firefox doesn't have focus(in | out) events
	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
	//
	// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
	// focus(in | out) events fire after focus & blur events,
	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
	// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
	if ( !support.focusin ) {
		jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
	
			// Attach a single capturing handler on the document while someone wants focusin/focusout
			var handler = function( event ) {
				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
			};
	
			jQuery.event.special[ fix ] = {
				setup: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix );
	
					if ( !attaches ) {
						doc.addEventListener( orig, handler, true );
					}
					dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
				},
				teardown: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix ) - 1;
	
					if ( !attaches ) {
						doc.removeEventListener( orig, handler, true );
						dataPriv.remove( doc, fix );
	
					} else {
						dataPriv.access( doc, fix, attaches );
					}
				}
			};
		} );
	}
	var location = window.location;
	
	var nonce = jQuery.now();
	
	var rquery = ( /\?/ );
	
	
	
	// Cross-browser xml parsing
	jQuery.parseXML = function( data ) {
		var xml;
		if ( !data || typeof data !== "string" ) {
			return null;
		}
	
		// Support: IE 9 - 11 only
		// IE throws on parseFromString with invalid input.
		try {
			xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
		} catch ( e ) {
			xml = undefined;
		}
	
		if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
			jQuery.error( "Invalid XML: " + data );
		}
		return xml;
	};
	
	
	var
		rbracket = /\[\]$/,
		rCRLF = /\r?\n/g,
		rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
		rsubmittable = /^(?:input|select|textarea|keygen)/i;
	
	function buildParams( prefix, obj, traditional, add ) {
		var name;
	
		if ( Array.isArray( obj ) ) {
	
			// Serialize array item.
			jQuery.each( obj, function( i, v ) {
				if ( traditional || rbracket.test( prefix ) ) {
	
					// Treat each array item as a scalar.
					add( prefix, v );
	
				} else {
	
					// Item is non-scalar (array or object), encode its numeric index.
					buildParams(
						prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
						v,
						traditional,
						add
					);
				}
			} );
	
		} else if ( !traditional && jQuery.type( obj ) === "object" ) {
	
			// Serialize object item.
			for ( name in obj ) {
				buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
			}
	
		} else {
	
			// Serialize scalar item.
			add( prefix, obj );
		}
	}
	
	// Serialize an array of form elements or a set of
	// key/values into a query string
	jQuery.param = function( a, traditional ) {
		var prefix,
			s = [],
			add = function( key, valueOrFunction ) {
	
				// If value is a function, invoke it and use its return value
				var value = jQuery.isFunction( valueOrFunction ) ?
					valueOrFunction() :
					valueOrFunction;
	
				s[ s.length ] = encodeURIComponent( key ) + "=" +
					encodeURIComponent( value == null ? "" : value );
			};
	
		// If an array was passed in, assume that it is an array of form elements.
		if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
	
			// Serialize the form elements
			jQuery.each( a, function() {
				add( this.name, this.value );
			} );
	
		} else {
	
			// If traditional, encode the "old" way (the way 1.3.2 or older
			// did it), otherwise encode params recursively.
			for ( prefix in a ) {
				buildParams( prefix, a[ prefix ], traditional, add );
			}
		}
	
		// Return the resulting serialization
		return s.join( "&" );
	};
	
	jQuery.fn.extend( {
		serialize: function() {
			return jQuery.param( this.serializeArray() );
		},
		serializeArray: function() {
			return this.map( function() {
	
				// Can add propHook for "elements" to filter or add form elements
				var elements = jQuery.prop( this, "elements" );
				return elements ? jQuery.makeArray( elements ) : this;
			} )
			.filter( function() {
				var type = this.type;
	
				// Use .is( ":disabled" ) so that fieldset[disabled] works
				return this.name && !jQuery( this ).is( ":disabled" ) &&
					rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
					( this.checked || !rcheckableType.test( type ) );
			} )
			.map( function( i, elem ) {
				var val = jQuery( this ).val();
	
				if ( val == null ) {
					return null;
				}
	
				if ( Array.isArray( val ) ) {
					return jQuery.map( val, function( val ) {
						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
					} );
				}
	
				return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
			} ).get();
		}
	} );
	
	
	var
		r20 = /%20/g,
		rhash = /#.*$/,
		rantiCache = /([?&])_=[^&]*/,
		rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
	
		// #7653, #8125, #8152: local protocol detection
		rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
		rnoContent = /^(?:GET|HEAD)$/,
		rprotocol = /^\/\//,
	
		/* Prefilters
		 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
		 * 2) These are called:
		 *    - BEFORE asking for a transport
		 *    - AFTER param serialization (s.data is a string if s.processData is true)
		 * 3) key is the dataType
		 * 4) the catchall symbol "*" can be used
		 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
		 */
		prefilters = {},
	
		/* Transports bindings
		 * 1) key is the dataType
		 * 2) the catchall symbol "*" can be used
		 * 3) selection will start with transport dataType and THEN go to "*" if needed
		 */
		transports = {},
	
		// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
		allTypes = "*/".concat( "*" ),
	
		// Anchor tag for parsing the document origin
		originAnchor = document.createElement( "a" );
		originAnchor.href = location.href;
	
	// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
	function addToPrefiltersOrTransports( structure ) {
	
		// dataTypeExpression is optional and defaults to "*"
		return function( dataTypeExpression, func ) {
	
			if ( typeof dataTypeExpression !== "string" ) {
				func = dataTypeExpression;
				dataTypeExpression = "*";
			}
	
			var dataType,
				i = 0,
				dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
	
			if ( jQuery.isFunction( func ) ) {
	
				// For each dataType in the dataTypeExpression
				while ( ( dataType = dataTypes[ i++ ] ) ) {
	
					// Prepend if requested
					if ( dataType[ 0 ] === "+" ) {
						dataType = dataType.slice( 1 ) || "*";
						( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
	
					// Otherwise append
					} else {
						( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
					}
				}
			}
		};
	}
	
	// Base inspection function for prefilters and transports
	function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
	
		var inspected = {},
			seekingTransport = ( structure === transports );
	
		function inspect( dataType ) {
			var selected;
			inspected[ dataType ] = true;
			jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
				var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
				if ( typeof dataTypeOrTransport === "string" &&
					!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
	
					options.dataTypes.unshift( dataTypeOrTransport );
					inspect( dataTypeOrTransport );
					return false;
				} else if ( seekingTransport ) {
					return !( selected = dataTypeOrTransport );
				}
			} );
			return selected;
		}
	
		return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
	}
	
	// A special extend for ajax options
	// that takes "flat" options (not to be deep extended)
	// Fixes #9887
	function ajaxExtend( target, src ) {
		var key, deep,
			flatOptions = jQuery.ajaxSettings.flatOptions || {};
	
		for ( key in src ) {
			if ( src[ key ] !== undefined ) {
				( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
			}
		}
		if ( deep ) {
			jQuery.extend( true, target, deep );
		}
	
		return target;
	}
	
	/* Handles responses to an ajax request:
	 * - finds the right dataType (mediates between content-type and expected dataType)
	 * - returns the corresponding response
	 */
	function ajaxHandleResponses( s, jqXHR, responses ) {
	
		var ct, type, finalDataType, firstDataType,
			contents = s.contents,
			dataTypes = s.dataTypes;
	
		// Remove auto dataType and get content-type in the process
		while ( dataTypes[ 0 ] === "*" ) {
			dataTypes.shift();
			if ( ct === undefined ) {
				ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
			}
		}
	
		// Check if we're dealing with a known content-type
		if ( ct ) {
			for ( type in contents ) {
				if ( contents[ type ] && contents[ type ].test( ct ) ) {
					dataTypes.unshift( type );
					break;
				}
			}
		}
	
		// Check to see if we have a response for the expected dataType
		if ( dataTypes[ 0 ] in responses ) {
			finalDataType = dataTypes[ 0 ];
		} else {
	
			// Try convertible dataTypes
			for ( type in responses ) {
				if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
					finalDataType = type;
					break;
				}
				if ( !firstDataType ) {
					firstDataType = type;
				}
			}
	
			// Or just use first one
			finalDataType = finalDataType || firstDataType;
		}
	
		// If we found a dataType
		// We add the dataType to the list if needed
		// and return the corresponding response
		if ( finalDataType ) {
			if ( finalDataType !== dataTypes[ 0 ] ) {
				dataTypes.unshift( finalDataType );
			}
			return responses[ finalDataType ];
		}
	}
	
	/* Chain conversions given the request and the original response
	 * Also sets the responseXXX fields on the jqXHR instance
	 */
	function ajaxConvert( s, response, jqXHR, isSuccess ) {
		var conv2, current, conv, tmp, prev,
			converters = {},
	
			// Work with a copy of dataTypes in case we need to modify it for conversion
			dataTypes = s.dataTypes.slice();
	
		// Create converters map with lowercased keys
		if ( dataTypes[ 1 ] ) {
			for ( conv in s.converters ) {
				converters[ conv.toLowerCase() ] = s.converters[ conv ];
			}
		}
	
		current = dataTypes.shift();
	
		// Convert to each sequential dataType
		while ( current ) {
	
			if ( s.responseFields[ current ] ) {
				jqXHR[ s.responseFields[ current ] ] = response;
			}
	
			// Apply the dataFilter if provided
			if ( !prev && isSuccess && s.dataFilter ) {
				response = s.dataFilter( response, s.dataType );
			}
	
			prev = current;
			current = dataTypes.shift();
	
			if ( current ) {
	
				// There's only work to do if current dataType is non-auto
				if ( current === "*" ) {
	
					current = prev;
	
				// Convert response if prev dataType is non-auto and differs from current
				} else if ( prev !== "*" && prev !== current ) {
	
					// Seek a direct converter
					conv = converters[ prev + " " + current ] || converters[ "* " + current ];
	
					// If none found, seek a pair
					if ( !conv ) {
						for ( conv2 in converters ) {
	
							// If conv2 outputs current
							tmp = conv2.split( " " );
							if ( tmp[ 1 ] === current ) {
	
								// If prev can be converted to accepted input
								conv = converters[ prev + " " + tmp[ 0 ] ] ||
									converters[ "* " + tmp[ 0 ] ];
								if ( conv ) {
	
									// Condense equivalence converters
									if ( conv === true ) {
										conv = converters[ conv2 ];
	
									// Otherwise, insert the intermediate dataType
									} else if ( converters[ conv2 ] !== true ) {
										current = tmp[ 0 ];
										dataTypes.unshift( tmp[ 1 ] );
									}
									break;
								}
							}
						}
					}
	
					// Apply converter (if not an equivalence)
					if ( conv !== true ) {
	
						// Unless errors are allowed to bubble, catch and return them
						if ( conv && s.throws ) {
							response = conv( response );
						} else {
							try {
								response = conv( response );
							} catch ( e ) {
								return {
									state: "parsererror",
									error: conv ? e : "No conversion from " + prev + " to " + current
								};
							}
						}
					}
				}
			}
		}
	
		return { state: "success", data: response };
	}
	
	jQuery.extend( {
	
		// Counter for holding the number of active queries
		active: 0,
	
		// Last-Modified header cache for next request
		lastModified: {},
		etag: {},
	
		ajaxSettings: {
			url: location.href,
			type: "GET",
			isLocal: rlocalProtocol.test( location.protocol ),
			global: true,
			processData: true,
			async: true,
			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
	
			/*
			timeout: 0,
			data: null,
			dataType: null,
			username: null,
			password: null,
			cache: null,
			throws: false,
			traditional: false,
			headers: {},
			*/
	
			accepts: {
				"*": allTypes,
				text: "text/plain",
				html: "text/html",
				xml: "application/xml, text/xml",
				json: "application/json, text/javascript"
			},
	
			contents: {
				xml: /\bxml\b/,
				html: /\bhtml/,
				json: /\bjson\b/
			},
	
			responseFields: {
				xml: "responseXML",
				text: "responseText",
				json: "responseJSON"
			},
	
			// Data converters
			// Keys separate source (or catchall "*") and destination types with a single space
			converters: {
	
				// Convert anything to text
				"* text": String,
	
				// Text to html (true = no transformation)
				"text html": true,
	
				// Evaluate text as a json expression
				"text json": JSON.parse,
	
				// Parse text as xml
				"text xml": jQuery.parseXML
			},
	
			// For options that shouldn't be deep extended:
			// you can add your own custom options here if
			// and when you create one that shouldn't be
			// deep extended (see ajaxExtend)
			flatOptions: {
				url: true,
				context: true
			}
		},
	
		// Creates a full fledged settings object into target
		// with both ajaxSettings and settings fields.
		// If target is omitted, writes into ajaxSettings.
		ajaxSetup: function( target, settings ) {
			return settings ?
	
				// Building a settings object
				ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
	
				// Extending ajaxSettings
				ajaxExtend( jQuery.ajaxSettings, target );
		},
	
		ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
		ajaxTransport: addToPrefiltersOrTransports( transports ),
	
		// Main method
		ajax: function( url, options ) {
	
			// If url is an object, simulate pre-1.5 signature
			if ( typeof url === "object" ) {
				options = url;
				url = undefined;
			}
	
			// Force options to be an object
			options = options || {};
	
			var transport,
	
				// URL without anti-cache param
				cacheURL,
	
				// Response headers
				responseHeadersString,
				responseHeaders,
	
				// timeout handle
				timeoutTimer,
	
				// Url cleanup var
				urlAnchor,
	
				// Request state (becomes false upon send and true upon completion)
				completed,
	
				// To know if global events are to be dispatched
				fireGlobals,
	
				// Loop variable
				i,
	
				// uncached part of the url
				uncached,
	
				// Create the final options object
				s = jQuery.ajaxSetup( {}, options ),
	
				// Callbacks context
				callbackContext = s.context || s,
	
				// Context for global events is callbackContext if it is a DOM node or jQuery collection
				globalEventContext = s.context &&
					( callbackContext.nodeType || callbackContext.jquery ) ?
						jQuery( callbackContext ) :
						jQuery.event,
	
				// Deferreds
				deferred = jQuery.Deferred(),
				completeDeferred = jQuery.Callbacks( "once memory" ),
	
				// Status-dependent callbacks
				statusCode = s.statusCode || {},
	
				// Headers (they are sent all at once)
				requestHeaders = {},
				requestHeadersNames = {},
	
				// Default abort message
				strAbort = "canceled",
	
				// Fake xhr
				jqXHR = {
					readyState: 0,
	
					// Builds headers hashtable if needed
					getResponseHeader: function( key ) {
						var match;
						if ( completed ) {
							if ( !responseHeaders ) {
								responseHeaders = {};
								while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
									responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
								}
							}
							match = responseHeaders[ key.toLowerCase() ];
						}
						return match == null ? null : match;
					},
	
					// Raw string
					getAllResponseHeaders: function() {
						return completed ? responseHeadersString : null;
					},
	
					// Caches the header
					setRequestHeader: function( name, value ) {
						if ( completed == null ) {
							name = requestHeadersNames[ name.toLowerCase() ] =
								requestHeadersNames[ name.toLowerCase() ] || name;
							requestHeaders[ name ] = value;
						}
						return this;
					},
	
					// Overrides response content-type header
					overrideMimeType: function( type ) {
						if ( completed == null ) {
							s.mimeType = type;
						}
						return this;
					},
	
					// Status-dependent callbacks
					statusCode: function( map ) {
						var code;
						if ( map ) {
							if ( completed ) {
	
								// Execute the appropriate callbacks
								jqXHR.always( map[ jqXHR.status ] );
							} else {
	
								// Lazy-add the new callbacks in a way that preserves old ones
								for ( code in map ) {
									statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
								}
							}
						}
						return this;
					},
	
					// Cancel the request
					abort: function( statusText ) {
						var finalText = statusText || strAbort;
						if ( transport ) {
							transport.abort( finalText );
						}
						done( 0, finalText );
						return this;
					}
				};
	
			// Attach deferreds
			deferred.promise( jqXHR );
	
			// Add protocol if not provided (prefilters might expect it)
			// Handle falsy url in the settings object (#10093: consistency with old signature)
			// We also use the url parameter if available
			s.url = ( ( url || s.url || location.href ) + "" )
				.replace( rprotocol, location.protocol + "//" );
	
			// Alias method option to type as per ticket #12004
			s.type = options.method || options.type || s.method || s.type;
	
			// Extract dataTypes list
			s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
	
			// A cross-domain request is in order when the origin doesn't match the current origin.
			if ( s.crossDomain == null ) {
				urlAnchor = document.createElement( "a" );
	
				// Support: IE <=8 - 11, Edge 12 - 13
				// IE throws exception on accessing the href property if url is malformed,
				// e.g. http://example.com:80x/
				try {
					urlAnchor.href = s.url;
	
					// Support: IE <=8 - 11 only
					// Anchor's host property isn't correctly set when s.url is relative
					urlAnchor.href = urlAnchor.href;
					s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
						urlAnchor.protocol + "//" + urlAnchor.host;
				} catch ( e ) {
	
					// If there is an error parsing the URL, assume it is crossDomain,
					// it can be rejected by the transport if it is invalid
					s.crossDomain = true;
				}
			}
	
			// Convert data if not already a string
			if ( s.data && s.processData && typeof s.data !== "string" ) {
				s.data = jQuery.param( s.data, s.traditional );
			}
	
			// Apply prefilters
			inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
	
			// If request was aborted inside a prefilter, stop there
			if ( completed ) {
				return jqXHR;
			}
	
			// We can fire global events as of now if asked to
			// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
			fireGlobals = jQuery.event && s.global;
	
			// Watch for a new set of requests
			if ( fireGlobals && jQuery.active++ === 0 ) {
				jQuery.event.trigger( "ajaxStart" );
			}
	
			// Uppercase the type
			s.type = s.type.toUpperCase();
	
			// Determine if request has content
			s.hasContent = !rnoContent.test( s.type );
	
			// Save the URL in case we're toying with the If-Modified-Since
			// and/or If-None-Match header later on
			// Remove hash to simplify url manipulation
			cacheURL = s.url.replace( rhash, "" );
	
			// More options handling for requests with no content
			if ( !s.hasContent ) {
	
				// Remember the hash so we can put it back
				uncached = s.url.slice( cacheURL.length );
	
				// If data is available, append data to url
				if ( s.data ) {
					cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
	
					// #9682: remove data so that it's not used in an eventual retry
					delete s.data;
				}
	
				// Add or update anti-cache param if needed
				if ( s.cache === false ) {
					cacheURL = cacheURL.replace( rantiCache, "$1" );
					uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
				}
	
				// Put hash and anti-cache on the URL that will be requested (gh-1732)
				s.url = cacheURL + uncached;
	
			// Change '%20' to '+' if this is encoded form body content (gh-2658)
			} else if ( s.data && s.processData &&
				( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
				s.data = s.data.replace( r20, "+" );
			}
	
			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
			if ( s.ifModified ) {
				if ( jQuery.lastModified[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
				}
				if ( jQuery.etag[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
				}
			}
	
			// Set the correct header, if data is being sent
			if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
				jqXHR.setRequestHeader( "Content-Type", s.contentType );
			}
	
			// Set the Accepts header for the server, depending on the dataType
			jqXHR.setRequestHeader(
				"Accept",
				s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
					s.accepts[ s.dataTypes[ 0 ] ] +
						( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
					s.accepts[ "*" ]
			);
	
			// Check for headers option
			for ( i in s.headers ) {
				jqXHR.setRequestHeader( i, s.headers[ i ] );
			}
	
			// Allow custom headers/mimetypes and early abort
			if ( s.beforeSend &&
				( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
	
				// Abort if not done already and return
				return jqXHR.abort();
			}
	
			// Aborting is no longer a cancellation
			strAbort = "abort";
	
			// Install callbacks on deferreds
			completeDeferred.add( s.complete );
			jqXHR.done( s.success );
			jqXHR.fail( s.error );
	
			// Get transport
			transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
	
			// If no transport, we auto-abort
			if ( !transport ) {
				done( -1, "No Transport" );
			} else {
				jqXHR.readyState = 1;
	
				// Send global event
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
				}
	
				// If request was aborted inside ajaxSend, stop there
				if ( completed ) {
					return jqXHR;
				}
	
				// Timeout
				if ( s.async && s.timeout > 0 ) {
					timeoutTimer = window.setTimeout( function() {
						jqXHR.abort( "timeout" );
					}, s.timeout );
				}
	
				try {
					completed = false;
					transport.send( requestHeaders, done );
				} catch ( e ) {
	
					// Rethrow post-completion exceptions
					if ( completed ) {
						throw e;
					}
	
					// Propagate others as results
					done( -1, e );
				}
			}
	
			// Callback for when everything is done
			function done( status, nativeStatusText, responses, headers ) {
				var isSuccess, success, error, response, modified,
					statusText = nativeStatusText;
	
				// Ignore repeat invocations
				if ( completed ) {
					return;
				}
	
				completed = true;
	
				// Clear timeout if it exists
				if ( timeoutTimer ) {
					window.clearTimeout( timeoutTimer );
				}
	
				// Dereference transport for early garbage collection
				// (no matter how long the jqXHR object will be used)
				transport = undefined;
	
				// Cache response headers
				responseHeadersString = headers || "";
	
				// Set readyState
				jqXHR.readyState = status > 0 ? 4 : 0;
	
				// Determine if successful
				isSuccess = status >= 200 && status < 300 || status === 304;
	
				// Get response data
				if ( responses ) {
					response = ajaxHandleResponses( s, jqXHR, responses );
				}
	
				// Convert no matter what (that way responseXXX fields are always set)
				response = ajaxConvert( s, response, jqXHR, isSuccess );
	
				// If successful, handle type chaining
				if ( isSuccess ) {
	
					// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
					if ( s.ifModified ) {
						modified = jqXHR.getResponseHeader( "Last-Modified" );
						if ( modified ) {
							jQuery.lastModified[ cacheURL ] = modified;
						}
						modified = jqXHR.getResponseHeader( "etag" );
						if ( modified ) {
							jQuery.etag[ cacheURL ] = modified;
						}
					}
	
					// if no content
					if ( status === 204 || s.type === "HEAD" ) {
						statusText = "nocontent";
	
					// if not modified
					} else if ( status === 304 ) {
						statusText = "notmodified";
	
					// If we have data, let's convert it
					} else {
						statusText = response.state;
						success = response.data;
						error = response.error;
						isSuccess = !error;
					}
				} else {
	
					// Extract error from statusText and normalize for non-aborts
					error = statusText;
					if ( status || !statusText ) {
						statusText = "error";
						if ( status < 0 ) {
							status = 0;
						}
					}
				}
	
				// Set data for the fake xhr object
				jqXHR.status = status;
				jqXHR.statusText = ( nativeStatusText || statusText ) + "";
	
				// Success/Error
				if ( isSuccess ) {
					deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
				} else {
					deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
				}
	
				// Status-dependent callbacks
				jqXHR.statusCode( statusCode );
				statusCode = undefined;
	
				if ( fireGlobals ) {
					globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
						[ jqXHR, s, isSuccess ? success : error ] );
				}
	
				// Complete
				completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
	
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
	
					// Handle the global AJAX counter
					if ( !( --jQuery.active ) ) {
						jQuery.event.trigger( "ajaxStop" );
					}
				}
			}
	
			return jqXHR;
		},
	
		getJSON: function( url, data, callback ) {
			return jQuery.get( url, data, callback, "json" );
		},
	
		getScript: function( url, callback ) {
			return jQuery.get( url, undefined, callback, "script" );
		}
	} );
	
	jQuery.each( [ "get", "post" ], function( i, method ) {
		jQuery[ method ] = function( url, data, callback, type ) {
	
			// Shift arguments if data argument was omitted
			if ( jQuery.isFunction( data ) ) {
				type = type || callback;
				callback = data;
				data = undefined;
			}
	
			// The url can be an options object (which then must have .url)
			return jQuery.ajax( jQuery.extend( {
				url: url,
				type: method,
				dataType: type,
				data: data,
				success: callback
			}, jQuery.isPlainObject( url ) && url ) );
		};
	} );
	
	
	jQuery._evalUrl = function( url ) {
		return jQuery.ajax( {
			url: url,
	
			// Make this explicit, since user can override this through ajaxSetup (#11264)
			type: "GET",
			dataType: "script",
			cache: true,
			async: false,
			global: false,
			"throws": true
		} );
	};
	
	
	jQuery.fn.extend( {
		wrapAll: function( html ) {
			var wrap;
	
			if ( this[ 0 ] ) {
				if ( jQuery.isFunction( html ) ) {
					html = html.call( this[ 0 ] );
				}
	
				// The elements to wrap the target around
				wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
	
				if ( this[ 0 ].parentNode ) {
					wrap.insertBefore( this[ 0 ] );
				}
	
				wrap.map( function() {
					var elem = this;
	
					while ( elem.firstElementChild ) {
						elem = elem.firstElementChild;
					}
	
					return elem;
				} ).append( this );
			}
	
			return this;
		},
	
		wrapInner: function( html ) {
			if ( jQuery.isFunction( html ) ) {
				return this.each( function( i ) {
					jQuery( this ).wrapInner( html.call( this, i ) );
				} );
			}
	
			return this.each( function() {
				var self = jQuery( this ),
					contents = self.contents();
	
				if ( contents.length ) {
					contents.wrapAll( html );
	
				} else {
					self.append( html );
				}
			} );
		},
	
		wrap: function( html ) {
			var isFunction = jQuery.isFunction( html );
	
			return this.each( function( i ) {
				jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
			} );
		},
	
		unwrap: function( selector ) {
			this.parent( selector ).not( "body" ).each( function() {
				jQuery( this ).replaceWith( this.childNodes );
			} );
			return this;
		}
	} );
	
	
	jQuery.expr.pseudos.hidden = function( elem ) {
		return !jQuery.expr.pseudos.visible( elem );
	};
	jQuery.expr.pseudos.visible = function( elem ) {
		return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
	};
	
	
	
	
	jQuery.ajaxSettings.xhr = function() {
		try {
			return new window.XMLHttpRequest();
		} catch ( e ) {}
	};
	
	var xhrSuccessStatus = {
	
			// File protocol always yields status code 0, assume 200
			0: 200,
	
			// Support: IE <=9 only
			// #1450: sometimes IE returns 1223 when it should be 204
			1223: 204
		},
		xhrSupported = jQuery.ajaxSettings.xhr();
	
	support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
	support.ajax = xhrSupported = !!xhrSupported;
	
	jQuery.ajaxTransport( function( options ) {
		var callback, errorCallback;
	
		// Cross domain only allowed if supported through XMLHttpRequest
		if ( support.cors || xhrSupported && !options.crossDomain ) {
			return {
				send: function( headers, complete ) {
					var i,
						xhr = options.xhr();
	
					xhr.open(
						options.type,
						options.url,
						options.async,
						options.username,
						options.password
					);
	
					// Apply custom fields if provided
					if ( options.xhrFields ) {
						for ( i in options.xhrFields ) {
							xhr[ i ] = options.xhrFields[ i ];
						}
					}
	
					// Override mime type if needed
					if ( options.mimeType && xhr.overrideMimeType ) {
						xhr.overrideMimeType( options.mimeType );
					}
	
					// X-Requested-With header
					// For cross-domain requests, seeing as conditions for a preflight are
					// akin to a jigsaw puzzle, we simply never set it to be sure.
					// (it can always be set on a per-request basis or even using ajaxSetup)
					// For same-domain requests, won't change header if already provided.
					if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
						headers[ "X-Requested-With" ] = "XMLHttpRequest";
					}
	
					// Set headers
					for ( i in headers ) {
						xhr.setRequestHeader( i, headers[ i ] );
					}
	
					// Callback
					callback = function( type ) {
						return function() {
							if ( callback ) {
								callback = errorCallback = xhr.onload =
									xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
	
								if ( type === "abort" ) {
									xhr.abort();
								} else if ( type === "error" ) {
	
									// Support: IE <=9 only
									// On a manual native abort, IE9 throws
									// errors on any property access that is not readyState
									if ( typeof xhr.status !== "number" ) {
										complete( 0, "error" );
									} else {
										complete(
	
											// File: protocol always yields status 0; see #8605, #14207
											xhr.status,
											xhr.statusText
										);
									}
								} else {
									complete(
										xhrSuccessStatus[ xhr.status ] || xhr.status,
										xhr.statusText,
	
										// Support: IE <=9 only
										// IE9 has no XHR2 but throws on binary (trac-11426)
										// For XHR2 non-text, let the caller handle it (gh-2498)
										( xhr.responseType || "text" ) !== "text"  ||
										typeof xhr.responseText !== "string" ?
											{ binary: xhr.response } :
											{ text: xhr.responseText },
										xhr.getAllResponseHeaders()
									);
								}
							}
						};
					};
	
					// Listen to events
					xhr.onload = callback();
					errorCallback = xhr.onerror = callback( "error" );
	
					// Support: IE 9 only
					// Use onreadystatechange to replace onabort
					// to handle uncaught aborts
					if ( xhr.onabort !== undefined ) {
						xhr.onabort = errorCallback;
					} else {
						xhr.onreadystatechange = function() {
	
							// Check readyState before timeout as it changes
							if ( xhr.readyState === 4 ) {
	
								// Allow onerror to be called first,
								// but that will not handle a native abort
								// Also, save errorCallback to a variable
								// as xhr.onerror cannot be accessed
								window.setTimeout( function() {
									if ( callback ) {
										errorCallback();
									}
								} );
							}
						};
					}
	
					// Create the abort callback
					callback = callback( "abort" );
	
					try {
	
						// Do send the request (this may raise an exception)
						xhr.send( options.hasContent && options.data || null );
					} catch ( e ) {
	
						// #14683: Only rethrow if this hasn't been notified as an error yet
						if ( callback ) {
							throw e;
						}
					}
				},
	
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
	jQuery.ajaxPrefilter( function( s ) {
		if ( s.crossDomain ) {
			s.contents.script = false;
		}
	} );
	
	// Install script dataType
	jQuery.ajaxSetup( {
		accepts: {
			script: "text/javascript, application/javascript, " +
				"application/ecmascript, application/x-ecmascript"
		},
		contents: {
			script: /\b(?:java|ecma)script\b/
		},
		converters: {
			"text script": function( text ) {
				jQuery.globalEval( text );
				return text;
			}
		}
	} );
	
	// Handle cache's special case and crossDomain
	jQuery.ajaxPrefilter( "script", function( s ) {
		if ( s.cache === undefined ) {
			s.cache = false;
		}
		if ( s.crossDomain ) {
			s.type = "GET";
		}
	} );
	
	// Bind script tag hack transport
	jQuery.ajaxTransport( "script", function( s ) {
	
		// This transport only deals with cross domain requests
		if ( s.crossDomain ) {
			var script, callback;
			return {
				send: function( _, complete ) {
					script = jQuery( "<script>" ).prop( {
						charset: s.scriptCharset,
						src: s.url
					} ).on(
						"load error",
						callback = function( evt ) {
							script.remove();
							callback = null;
							if ( evt ) {
								complete( evt.type === "error" ? 404 : 200, evt.type );
							}
						}
					);
	
					// Use native DOM manipulation to avoid our domManip AJAX trickery
					document.head.appendChild( script[ 0 ] );
				},
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	var oldCallbacks = [],
		rjsonp = /(=)\?(?=&|$)|\?\?/;
	
	// Default jsonp settings
	jQuery.ajaxSetup( {
		jsonp: "callback",
		jsonpCallback: function() {
			var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
			this[ callback ] = true;
			return callback;
		}
	} );
	
	// Detect, normalize options and install callbacks for jsonp requests
	jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
	
		var callbackName, overwritten, responseContainer,
			jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
				"url" :
				typeof s.data === "string" &&
					( s.contentType || "" )
						.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
					rjsonp.test( s.data ) && "data"
			);
	
		// Handle iff the expected data type is "jsonp" or we have a parameter to set
		if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
	
			// Get callback name, remembering preexisting value associated with it
			callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
				s.jsonpCallback() :
				s.jsonpCallback;
	
			// Insert callback into url or form data
			if ( jsonProp ) {
				s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
			} else if ( s.jsonp !== false ) {
				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
			}
	
			// Use data converter to retrieve json after script execution
			s.converters[ "script json" ] = function() {
				if ( !responseContainer ) {
					jQuery.error( callbackName + " was not called" );
				}
				return responseContainer[ 0 ];
			};
	
			// Force json dataType
			s.dataTypes[ 0 ] = "json";
	
			// Install callback
			overwritten = window[ callbackName ];
			window[ callbackName ] = function() {
				responseContainer = arguments;
			};
	
			// Clean-up function (fires after converters)
			jqXHR.always( function() {
	
				// If previous value didn't exist - remove it
				if ( overwritten === undefined ) {
					jQuery( window ).removeProp( callbackName );
	
				// Otherwise restore preexisting value
				} else {
					window[ callbackName ] = overwritten;
				}
	
				// Save back as free
				if ( s[ callbackName ] ) {
	
					// Make sure that re-using the options doesn't screw things around
					s.jsonpCallback = originalSettings.jsonpCallback;
	
					// Save the callback name for future use
					oldCallbacks.push( callbackName );
				}
	
				// Call if it was a function and we have a response
				if ( responseContainer && jQuery.isFunction( overwritten ) ) {
					overwritten( responseContainer[ 0 ] );
				}
	
				responseContainer = overwritten = undefined;
			} );
	
			// Delegate to script
			return "script";
		}
	} );
	
	
	
	
	// Support: Safari 8 only
	// In Safari 8 documents created via document.implementation.createHTMLDocument
	// collapse sibling forms: the second one becomes a child of the first one.
	// Because of that, this security measure has to be disabled in Safari 8.
	// https://bugs.webkit.org/show_bug.cgi?id=137337
	support.createHTMLDocument = ( function() {
		var body = document.implementation.createHTMLDocument( "" ).body;
		body.innerHTML = "<form></form><form></form>";
		return body.childNodes.length === 2;
	} )();
	
	
	// Argument "data" should be string of html
	// context (optional): If specified, the fragment will be created in this context,
	// defaults to document
	// keepScripts (optional): If true, will include scripts passed in the html string
	jQuery.parseHTML = function( data, context, keepScripts ) {
		if ( typeof data !== "string" ) {
			return [];
		}
		if ( typeof context === "boolean" ) {
			keepScripts = context;
			context = false;
		}
	
		var base, parsed, scripts;
	
		if ( !context ) {
	
			// Stop scripts or inline event handlers from being executed immediately
			// by using document.implementation
			if ( support.createHTMLDocument ) {
				context = document.implementation.createHTMLDocument( "" );
	
				// Set the base href for the created document
				// so any parsed elements with URLs
				// are based on the document's URL (gh-2965)
				base = context.createElement( "base" );
				base.href = document.location.href;
				context.head.appendChild( base );
			} else {
				context = document;
			}
		}
	
		parsed = rsingleTag.exec( data );
		scripts = !keepScripts && [];
	
		// Single tag
		if ( parsed ) {
			return [ context.createElement( parsed[ 1 ] ) ];
		}
	
		parsed = buildFragment( [ data ], context, scripts );
	
		if ( scripts && scripts.length ) {
			jQuery( scripts ).remove();
		}
	
		return jQuery.merge( [], parsed.childNodes );
	};
	
	
	/**
	 * Load a url into a page
	 */
	jQuery.fn.load = function( url, params, callback ) {
		var selector, type, response,
			self = this,
			off = url.indexOf( " " );
	
		if ( off > -1 ) {
			selector = stripAndCollapse( url.slice( off ) );
			url = url.slice( 0, off );
		}
	
		// If it's a function
		if ( jQuery.isFunction( params ) ) {
	
			// We assume that it's the callback
			callback = params;
			params = undefined;
	
		// Otherwise, build a param string
		} else if ( params && typeof params === "object" ) {
			type = "POST";
		}
	
		// If we have elements to modify, make the request
		if ( self.length > 0 ) {
			jQuery.ajax( {
				url: url,
	
				// If "type" variable is undefined, then "GET" method will be used.
				// Make value of this field explicit since
				// user can override it through ajaxSetup method
				type: type || "GET",
				dataType: "html",
				data: params
			} ).done( function( responseText ) {
	
				// Save response for use in complete callback
				response = arguments;
	
				self.html( selector ?
	
					// If a selector was specified, locate the right elements in a dummy div
					// Exclude scripts to avoid IE 'Permission Denied' errors
					jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
	
					// Otherwise use the full result
					responseText );
	
			// If the request succeeds, this function gets "data", "status", "jqXHR"
			// but they are ignored because response was set above.
			// If it fails, this function gets "jqXHR", "status", "error"
			} ).always( callback && function( jqXHR, status ) {
				self.each( function() {
					callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
				} );
			} );
		}
	
		return this;
	};
	
	
	
	
	// Attach a bunch of functions for handling common AJAX events
	jQuery.each( [
		"ajaxStart",
		"ajaxStop",
		"ajaxComplete",
		"ajaxError",
		"ajaxSuccess",
		"ajaxSend"
	], function( i, type ) {
		jQuery.fn[ type ] = function( fn ) {
			return this.on( type, fn );
		};
	} );
	
	
	
	
	jQuery.expr.pseudos.animated = function( elem ) {
		return jQuery.grep( jQuery.timers, function( fn ) {
			return elem === fn.elem;
		} ).length;
	};
	
	
	
	
	jQuery.offset = {
		setOffset: function( elem, options, i ) {
			var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
				position = jQuery.css( elem, "position" ),
				curElem = jQuery( elem ),
				props = {};
	
			// Set position first, in-case top/left are set even on static elem
			if ( position === "static" ) {
				elem.style.position = "relative";
			}
	
			curOffset = curElem.offset();
			curCSSTop = jQuery.css( elem, "top" );
			curCSSLeft = jQuery.css( elem, "left" );
			calculatePosition = ( position === "absolute" || position === "fixed" ) &&
				( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
	
			// Need to be able to calculate position if either
			// top or left is auto and position is either absolute or fixed
			if ( calculatePosition ) {
				curPosition = curElem.position();
				curTop = curPosition.top;
				curLeft = curPosition.left;
	
			} else {
				curTop = parseFloat( curCSSTop ) || 0;
				curLeft = parseFloat( curCSSLeft ) || 0;
			}
	
			if ( jQuery.isFunction( options ) ) {
	
				// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
				options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
			}
	
			if ( options.top != null ) {
				props.top = ( options.top - curOffset.top ) + curTop;
			}
			if ( options.left != null ) {
				props.left = ( options.left - curOffset.left ) + curLeft;
			}
	
			if ( "using" in options ) {
				options.using.call( elem, props );
	
			} else {
				curElem.css( props );
			}
		}
	};
	
	jQuery.fn.extend( {
		offset: function( options ) {
	
			// Preserve chaining for setter
			if ( arguments.length ) {
				return options === undefined ?
					this :
					this.each( function( i ) {
						jQuery.offset.setOffset( this, options, i );
					} );
			}
	
			var doc, docElem, rect, win,
				elem = this[ 0 ];
	
			if ( !elem ) {
				return;
			}
	
			// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
			// Support: IE <=11 only
			// Running getBoundingClientRect on a
			// disconnected node in IE throws an error
			if ( !elem.getClientRects().length ) {
				return { top: 0, left: 0 };
			}
	
			rect = elem.getBoundingClientRect();
	
			doc = elem.ownerDocument;
			docElem = doc.documentElement;
			win = doc.defaultView;
	
			return {
				top: rect.top + win.pageYOffset - docElem.clientTop,
				left: rect.left + win.pageXOffset - docElem.clientLeft
			};
		},
	
		position: function() {
			if ( !this[ 0 ] ) {
				return;
			}
	
			var offsetParent, offset,
				elem = this[ 0 ],
				parentOffset = { top: 0, left: 0 };
	
			// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
			// because it is its only offset parent
			if ( jQuery.css( elem, "position" ) === "fixed" ) {
	
				// Assume getBoundingClientRect is there when computed position is fixed
				offset = elem.getBoundingClientRect();
	
			} else {
	
				// Get *real* offsetParent
				offsetParent = this.offsetParent();
	
				// Get correct offsets
				offset = this.offset();
				if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
					parentOffset = offsetParent.offset();
				}
	
				// Add offsetParent borders
				parentOffset = {
					top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
					left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
				};
			}
	
			// Subtract parent offsets and element margins
			return {
				top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
				left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
			};
		},
	
		// This method will return documentElement in the following cases:
		// 1) For the element inside the iframe without offsetParent, this method will return
		//    documentElement of the parent window
		// 2) For the hidden or detached element
		// 3) For body or html element, i.e. in case of the html node - it will return itself
		//
		// but those exceptions were never presented as a real life use-cases
		// and might be considered as more preferable results.
		//
		// This logic, however, is not guaranteed and can change at any point in the future
		offsetParent: function() {
			return this.map( function() {
				var offsetParent = this.offsetParent;
	
				while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
					offsetParent = offsetParent.offsetParent;
				}
	
				return offsetParent || documentElement;
			} );
		}
	} );
	
	// Create scrollLeft and scrollTop methods
	jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
		var top = "pageYOffset" === prop;
	
		jQuery.fn[ method ] = function( val ) {
			return access( this, function( elem, method, val ) {
	
				// Coalesce documents and windows
				var win;
				if ( jQuery.isWindow( elem ) ) {
					win = elem;
				} else if ( elem.nodeType === 9 ) {
					win = elem.defaultView;
				}
	
				if ( val === undefined ) {
					return win ? win[ prop ] : elem[ method ];
				}
	
				if ( win ) {
					win.scrollTo(
						!top ? val : win.pageXOffset,
						top ? val : win.pageYOffset
					);
	
				} else {
					elem[ method ] = val;
				}
			}, method, val, arguments.length );
		};
	} );
	
	// Support: Safari <=7 - 9.1, Chrome <=37 - 49
	// Add the top/left cssHooks using jQuery.fn.position
	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
	// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
	// getComputedStyle returns percent when specified for top/left/bottom/right;
	// rather than make the css module depend on the offset module, just check for it here
	jQuery.each( [ "top", "left" ], function( i, prop ) {
		jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
			function( elem, computed ) {
				if ( computed ) {
					computed = curCSS( elem, prop );
	
					// If curCSS returns percentage, fallback to offset
					return rnumnonpx.test( computed ) ?
						jQuery( elem ).position()[ prop ] + "px" :
						computed;
				}
			}
		);
	} );
	
	
	// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
	jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
		jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
			function( defaultExtra, funcName ) {
	
			// Margin is only for outerHeight, outerWidth
			jQuery.fn[ funcName ] = function( margin, value ) {
				var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
					extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
	
				return access( this, function( elem, type, value ) {
					var doc;
	
					if ( jQuery.isWindow( elem ) ) {
	
						// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
						return funcName.indexOf( "outer" ) === 0 ?
							elem[ "inner" + name ] :
							elem.document.documentElement[ "client" + name ];
					}
	
					// Get document width or height
					if ( elem.nodeType === 9 ) {
						doc = elem.documentElement;
	
						// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
						// whichever is greatest
						return Math.max(
							elem.body[ "scroll" + name ], doc[ "scroll" + name ],
							elem.body[ "offset" + name ], doc[ "offset" + name ],
							doc[ "client" + name ]
						);
					}
	
					return value === undefined ?
	
						// Get width or height on the element, requesting but not forcing parseFloat
						jQuery.css( elem, type, extra ) :
	
						// Set width or height on the element
						jQuery.style( elem, type, value, extra );
				}, type, chainable ? margin : undefined, chainable );
			};
		} );
	} );
	
	
	jQuery.fn.extend( {
	
		bind: function( types, data, fn ) {
			return this.on( types, null, data, fn );
		},
		unbind: function( types, fn ) {
			return this.off( types, null, fn );
		},
	
		delegate: function( selector, types, data, fn ) {
			return this.on( types, selector, data, fn );
		},
		undelegate: function( selector, types, fn ) {
	
			// ( namespace ) or ( selector, types [, fn] )
			return arguments.length === 1 ?
				this.off( selector, "**" ) :
				this.off( types, selector || "**", fn );
		}
	} );
	
	jQuery.holdReady = function( hold ) {
		if ( hold ) {
			jQuery.readyWait++;
		} else {
			jQuery.ready( true );
		}
	};
	jQuery.isArray = Array.isArray;
	jQuery.parseJSON = JSON.parse;
	jQuery.nodeName = nodeName;
	
	
	
	
	// Register as a named AMD module, since jQuery can be concatenated with other
	// files that may use define, but not via a proper concatenation script that
	// understands anonymous AMD modules. A named AMD is safest and most robust
	// way to register. Lowercase jquery is used because AMD module names are
	// derived from file names, and jQuery is normally delivered in a lowercase
	// file name. Do this after creating the global so that if an AMD module wants
	// to call noConflict to hide this version of jQuery, it will work.
	
	// Note that for maximum portability, libraries that are not jQuery should
	// declare themselves as anonymous modules, and avoid setting a global if an
	// AMD loader is present. jQuery is a special case. For more information, see
	// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
	
	if ( true ) {
		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
			return jQuery;
		}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	}
	
	
	
	
	var
	
		// Map over jQuery in case of overwrite
		_jQuery = window.jQuery,
	
		// Map over the $ in case of overwrite
		_$ = window.$;
	
	jQuery.noConflict = function( deep ) {
		if ( window.$ === jQuery ) {
			window.$ = _$;
		}
	
		if ( deep && window.jQuery === jQuery ) {
			window.jQuery = _jQuery;
		}
	
		return jQuery;
	};
	
	// Expose jQuery and $ identifiers, even in AMD
	// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
	// and CommonJS for browser emulators (#13566)
	if ( !noGlobal ) {
		window.jQuery = window.$ = jQuery;
	}
	
	
	
	
	return jQuery;
	} );
	
})
/** END DEFINE BLOCK for jquery@3.2.1/dist/jquery.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/nativeview.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/nativeview.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*
	 This file contains substantial portions of https://github.com/akre54/Backbone.NativeView/blob/521188d9554b53d95d70ed34f878d8ac9fc10df2/backbone.nativeview.js, which has the following license:
	
	(c) 2015 Adam Krebs, Jimmy Yuen Ho Wong
	Backbone.NativeView may be freely distributed under the MIT license.
	
	Copyright (c) 2014 Adam Krebs
	
	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:
	
	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.
	
	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
	
	*/
	var Backbone = __jupyter_require__('backbone@1.2.0/backbone.js');
	// Caches a local reference to `Element.prototype` for faster access.
	var ElementProto = Element.prototype; //: typeof Element = (typeof Element !== 'undefined' && Element.prototype) || {};
	// Find the right `Element#matches` for IE>=9 and modern browsers.
	var matchesSelector = ElementProto.matches ||
	    ElementProto['webkitMatchesSelector'] ||
	    ElementProto['mozMatchesSelector'] ||
	    ElementProto['msMatchesSelector'] ||
	    ElementProto['oMatchesSelector'] ||
	    function matches(selector) {
	        var matches = (this.document || this.ownerDocument).querySelectorAll(selector), i = matches.length;
	        while (--i >= 0 && matches.item(i) !== this) { }
	        return i > -1;
	    };
	var NativeView = (function (_super) {
	    __extends(NativeView, _super);
	    function NativeView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    NativeView.prototype._removeElement = function () {
	        this.undelegateEvents();
	        if (this.el.parentNode) {
	            this.el.parentNode.removeChild(this.el);
	        }
	    };
	    // Apply the `element` to the view.
	    NativeView.prototype._setElement = function (element) {
	        this.el = element;
	    };
	    // Set a hash of attributes to the view's `el`. We use the "prop" version
	    // if available, falling back to `setAttribute` for the catch-all.
	    NativeView.prototype._setAttributes = function (attrs) {
	        for (var attr in attrs) {
	            attr in this.el ? this.el[attr] = attrs[attr] : this.el.setAttribute(attr, attrs[attr]);
	        }
	    };
	    /**
	     * Make an event delegation handler for the given `eventName` and `selector`
	     * and attach it to `this.el`.
	     * If selector is empty, the listener will be bound to `this.el`. If not, a
	     * new handler that will recursively traverse up the event target's DOM
	     * hierarchy looking for a node that matches the selector. If one is found,
	     * the event's `delegateTarget` property is set to it and the return the
	     * result of calling bound `listener` with the parameters given to the
	     * handler.
	     *
	     * This does not properly handle selectors for things like focus and blur (see
	     * https://github.com/jquery/jquery/blob/7d21f02b9ec9f655583e898350badf89165ed4d5/src/event.js#L442
	     * for some similar exceptional cases).
	     */
	    NativeView.prototype.delegate = function (eventName, selector, listener) {
	        if (typeof selector !== 'string') {
	            listener = selector;
	            selector = null;
	        }
	        // We have to initialize this here, instead of in the constructor, because the
	        // super constructor eventually calls this method before we get a chance to initialize
	        // this._domEvents to an empty list.
	        if (this._domEvents === void 0) {
	            this._domEvents = [];
	        }
	        var root = this.el;
	        var handler = selector ? function (e) {
	            var node = e.target || e.srcElement;
	            for (; node && node != root; node = node.parentNode) {
	                if (matchesSelector.call(node, selector)) {
	                    e.delegateTarget = node;
	                    if (listener.handleEvent) {
	                        return listener.handleEvent(e);
	                    }
	                    else {
	                        return listener(e);
	                    }
	                }
	            }
	        } : listener;
	        this.el.addEventListener(eventName, handler, false);
	        this._domEvents.push({ eventName: eventName, handler: handler, listener: listener, selector: selector });
	        return handler;
	    };
	    // Remove a single delegated event. Either `eventName` or `selector` must
	    // be included, `selector` and `listener` are optional.
	    NativeView.prototype.undelegate = function (eventName, selector, listener) {
	        if (typeof selector === 'function') {
	            listener = selector;
	            selector = null;
	        }
	        if (this.el && this._domEvents) {
	            var handlers = this._domEvents.slice();
	            var i = handlers.length;
	            while (i--) {
	                var item = handlers[i];
	                var match = item.eventName === eventName &&
	                    (listener ? item.listener === listener : true) &&
	                    (selector ? item.selector === selector : true);
	                if (!match)
	                    continue;
	                this.el.removeEventListener(item.eventName, item.handler, false);
	                this._domEvents.splice(i, 1);
	            }
	        }
	        return this;
	    };
	    // Remove all events created with `delegate` from `el`
	    NativeView.prototype.undelegateEvents = function () {
	        if (this.el && this._domEvents) {
	            for (var i = 0, len = this._domEvents.length; i < len; i++) {
	                var item = this._domEvents[i];
	                this.el.removeEventListener(item.eventName, item.handler, false);
	            }
	            ;
	            this._domEvents.length = 0;
	        }
	        return this;
	    };
	    return NativeView;
	}(Backbone.View));
	exports.NativeView = NativeView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/nativeview.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/index.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/boxengine.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/boxlayout.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/boxpanel.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/commandpalette.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/contextmenu.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/docklayout.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/dockpanel.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/focustracker.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/gridlayout.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/layout.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/menu.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/menubar.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/panel.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/panellayout.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/scrollbar.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/splitlayout.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/splitpanel.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/stackedlayout.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/stackedpanel.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/tabbar.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/tabpanel.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/title.js'));
	__export(__jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js'));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/boxengine.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/boxengine.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A sizer object for use with the box engine layout functions.
	 *
	 * #### Notes
	 * A box sizer holds the geometry information for an object along an
	 * arbitrary layout orientation.
	 *
	 * For best performance, this class should be treated as a raw data
	 * struct. It should not typically be subclassed.
	 */
	var BoxSizer = (function () {
	    function BoxSizer() {
	        /**
	         * The preferred size for the sizer.
	         *
	         * #### Notes
	         * The sizer will be given this initial size subject to its size
	         * bounds. The sizer will not deviate from this size unless such
	         * deviation is required to fit into the available layout space.
	         *
	         * There is no limit to this value, but it will be clamped to the
	         * bounds defined by [[minSize]] and [[maxSize]].
	         *
	         * The default value is `0`.
	         */
	        this.sizeHint = 0;
	        /**
	         * The minimum size of the sizer.
	         *
	         * #### Notes
	         * The sizer will never be sized less than this value, even if
	         * it means the sizer will overflow the available layout space.
	         *
	         * It is assumed that this value lies in the range `[0, Infinity)`
	         * and that it is `<=` to [[maxSize]]. Failure to adhere to this
	         * constraint will yield undefined results.
	         *
	         * The default value is `0`.
	         */
	        this.minSize = 0;
	        /**
	         * The maximum size of the sizer.
	         *
	         * #### Notes
	         * The sizer will never be sized greater than this value, even if
	         * it means the sizer will underflow the available layout space.
	         *
	         * It is assumed that this value lies in the range `[0, Infinity]`
	         * and that it is `>=` to [[minSize]]. Failure to adhere to this
	         * constraint will yield undefined results.
	         *
	         * The default value is `Infinity`.
	         */
	        this.maxSize = Infinity;
	        /**
	         * The stretch factor for the sizer.
	         *
	         * #### Notes
	         * This controls how much the sizer stretches relative to its sibling
	         * sizers when layout space is distributed. A stretch factor of zero
	         * is special and will cause the sizer to only be resized after all
	         * other sizers with a stretch factor greater than zero have been
	         * resized to their limits.
	         *
	         * It is assumed that this value is an integer that lies in the range
	         * `[0, Infinity)`. Failure to adhere to this constraint will yield
	         * undefined results.
	         *
	         * The default value is `1`.
	         */
	        this.stretch = 1;
	        /**
	         * The computed size of the sizer.
	         *
	         * #### Notes
	         * This value is the output of a call to [[boxCalc]]. It represents
	         * the computed size for the object along the layout orientation,
	         * and will always lie in the range `[minSize, maxSize]`.
	         *
	         * This value is output only.
	         *
	         * Changing this value will have no effect.
	         */
	        this.size = 0;
	        /**
	         * An internal storage property for the layout algorithm.
	         *
	         * #### Notes
	         * This value is used as temporary storage by the layout algorithm.
	         *
	         * Changing this value will have no effect.
	         */
	        this.done = false;
	    }
	    return BoxSizer;
	}());
	exports.BoxSizer = BoxSizer;
	/**
	 * The namespace for the box engine layout functions.
	 */
	var BoxEngine;
	(function (BoxEngine) {
	    /**
	     * Calculate the optimal layout sizes for a sequence of box sizers.
	     *
	     * This distributes the available layout space among the box sizers
	     * according to the following algorithm:
	     *
	     * 1. Initialize the sizers's size to its size hint and compute the
	     *    sums for each of size hint, min size, and max size.
	     *
	     * 2. If the total size hint equals the available space, return.
	     *
	     * 3. If the available space is less than the total min size, set all
	     *    sizers to their min size and return.
	     *
	     * 4. If the available space is greater than the total max size, set
	     *    all sizers to their max size and return.
	     *
	     * 5. If the layout space is less than the total size hint, distribute
	     *    the negative delta as follows:
	     *
	     *    a. Shrink each sizer with a stretch factor greater than zero by
	     *       an amount proportional to the negative space and the sum of
	     *       stretch factors. If the sizer reaches its min size, remove
	     *       it and its stretch factor from the computation.
	     *
	     *    b. If after adjusting all stretch sizers there remains negative
	     *       space, distribute the space equally among the sizers with a
	     *       stretch factor of zero. If a sizer reaches its min size,
	     *       remove it from the computation.
	     *
	     * 6. If the layout space is greater than the total size hint,
	     *    distribute the positive delta as follows:
	     *
	     *    a. Expand each sizer with a stretch factor greater than zero by
	     *       an amount proportional to the postive space and the sum of
	     *       stretch factors. If the sizer reaches its max size, remove
	     *       it and its stretch factor from the computation.
	     *
	     *    b. If after adjusting all stretch sizers there remains positive
	     *       space, distribute the space equally among the sizers with a
	     *       stretch factor of zero. If a sizer reaches its max size,
	     *       remove it from the computation.
	     *
	     * 7. return
	     *
	     * @param sizers - The sizers for a particular layout line.
	     *
	     * @param space - The available layout space for the sizers.
	     *
	     * @returns The delta between the provided available space and the
	     *   actual consumed space. This value will be zero if the sizers
	     *   can be adjusted to fit, negative if the available space is too
	     *   small, and positive if the available space is too large.
	     *
	     * #### Notes
	     * The [[size]] of each sizer is updated with the computed size.
	     *
	     * This function can be called at any time to recompute the layout for
	     * an existing sequence of sizers. The previously computed results will
	     * have no effect on the new output. It is therefore not necessary to
	     * create new sizer objects on each resize event.
	     */
	    function calc(sizers, space) {
	        // Bail early if there is nothing to do.
	        var count = sizers.length;
	        if (count === 0) {
	            return space;
	        }
	        // Setup the size and stretch counters.
	        var totalMin = 0;
	        var totalMax = 0;
	        var totalSize = 0;
	        var totalStretch = 0;
	        var stretchCount = 0;
	        // Setup the sizers and compute the totals.
	        for (var i = 0; i < count; ++i) {
	            var sizer = sizers[i];
	            var min = sizer.minSize;
	            var max = sizer.maxSize;
	            var hint = sizer.sizeHint;
	            sizer.done = false;
	            sizer.size = Math.max(min, Math.min(hint, max));
	            totalSize += sizer.size;
	            totalMin += min;
	            totalMax += max;
	            if (sizer.stretch > 0) {
	                totalStretch += sizer.stretch;
	                stretchCount++;
	            }
	        }
	        // If the space is equal to the total size, return early.
	        if (space === totalSize) {
	            return 0;
	        }
	        // If the space is less than the total min, minimize each sizer.
	        if (space <= totalMin) {
	            for (var i = 0; i < count; ++i) {
	                var sizer = sizers[i];
	                sizer.size = sizer.minSize;
	            }
	            return space - totalMin;
	        }
	        // If the space is greater than the total max, maximize each sizer.
	        if (space >= totalMax) {
	            for (var i = 0; i < count; ++i) {
	                var sizer = sizers[i];
	                sizer.size = sizer.maxSize;
	            }
	            return space - totalMax;
	        }
	        // The loops below perform sub-pixel precision sizing. A near zero
	        // value is used for compares instead of zero to ensure that the
	        // loop terminates when the subdivided space is reasonably small.
	        var nearZero = 0.01;
	        // A counter which is decremented each time a sizer is resized to
	        // its limit. This ensures the loops terminate even if there is
	        // space remaining to distribute.
	        var notDoneCount = count;
	        // Distribute negative delta space.
	        if (space < totalSize) {
	            // Shrink each stretchable sizer by an amount proportional to its
	            // stretch factor. If a sizer reaches its min size it's marked as
	            // done. The loop progresses in phases where each sizer is given
	            // a chance to consume its fair share for the pass, regardless of
	            // whether a sizer before it reached its limit. This continues
	            // until the stretchable sizers or the free space is exhausted.
	            var freeSpace = totalSize - space;
	            while (stretchCount > 0 && freeSpace > nearZero) {
	                var distSpace = freeSpace;
	                var distStretch = totalStretch;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done || sizer.stretch === 0) {
	                        continue;
	                    }
	                    var amt = sizer.stretch * distSpace / distStretch;
	                    if (sizer.size - amt <= sizer.minSize) {
	                        freeSpace -= sizer.size - sizer.minSize;
	                        totalStretch -= sizer.stretch;
	                        sizer.size = sizer.minSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                        stretchCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size -= amt;
	                    }
	                }
	            }
	            // Distribute any remaining space evenly among the non-stretchable
	            // sizers. This progresses in phases in the same manner as above.
	            while (notDoneCount > 0 && freeSpace > nearZero) {
	                var amt = freeSpace / notDoneCount;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done) {
	                        continue;
	                    }
	                    if (sizer.size - amt <= sizer.minSize) {
	                        freeSpace -= sizer.size - sizer.minSize;
	                        sizer.size = sizer.minSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size -= amt;
	                    }
	                }
	            }
	        }
	        else {
	            // Expand each stretchable sizer by an amount proportional to its
	            // stretch factor. If a sizer reaches its max size it's marked as
	            // done. The loop progresses in phases where each sizer is given
	            // a chance to consume its fair share for the pass, regardless of
	            // whether a sizer before it reached its limit. This continues
	            // until the stretchable sizers or the free space is exhausted.
	            var freeSpace = space - totalSize;
	            while (stretchCount > 0 && freeSpace > nearZero) {
	                var distSpace = freeSpace;
	                var distStretch = totalStretch;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done || sizer.stretch === 0) {
	                        continue;
	                    }
	                    var amt = sizer.stretch * distSpace / distStretch;
	                    if (sizer.size + amt >= sizer.maxSize) {
	                        freeSpace -= sizer.maxSize - sizer.size;
	                        totalStretch -= sizer.stretch;
	                        sizer.size = sizer.maxSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                        stretchCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size += amt;
	                    }
	                }
	            }
	            // Distribute any remaining space evenly among the non-stretchable
	            // sizers. This progresses in phases in the same manner as above.
	            while (notDoneCount > 0 && freeSpace > nearZero) {
	                var amt = freeSpace / notDoneCount;
	                for (var i = 0; i < count; ++i) {
	                    var sizer = sizers[i];
	                    if (sizer.done) {
	                        continue;
	                    }
	                    if (sizer.size + amt >= sizer.maxSize) {
	                        freeSpace -= sizer.maxSize - sizer.size;
	                        sizer.size = sizer.maxSize;
	                        sizer.done = true;
	                        notDoneCount--;
	                    }
	                    else {
	                        freeSpace -= amt;
	                        sizer.size += amt;
	                    }
	                }
	            }
	        }
	        // Indicate that the consumed space equals the available space.
	        return 0;
	    }
	    BoxEngine.calc = calc;
	    /**
	     * Adjust a sizer by a delta and update its neighbors accordingly.
	     *
	     * @param sizers - The sizers which should be adjusted.
	     *
	     * @param index - The index of the sizer to grow.
	     *
	     * @param delta - The amount to adjust the sizer, positive or negative.
	     *
	     * #### Notes
	     * This will adjust the indicated sizer by the specified amount, along
	     * with the sizes of the appropriate neighbors, subject to the limits
	     * specified by each of the sizers.
	     *
	     * This is useful when implementing box layouts where the boundaries
	     * between the sizers are interactively adjustable by the user.
	     */
	    function adjust(sizers, index, delta) {
	        // Bail early when there is nothing to do.
	        if (sizers.length === 0 || delta === 0) {
	            return;
	        }
	        // Dispatch to the proper implementation.
	        if (delta > 0) {
	            growSizer(sizers, index, delta);
	        }
	        else {
	            shrinkSizer(sizers, index, -delta);
	        }
	    }
	    BoxEngine.adjust = adjust;
	    /**
	     * Grow a sizer by a positive delta and adjust neighbors.
	     */
	    function growSizer(sizers, index, delta) {
	        // Compute how much the items to the left can expand.
	        var growLimit = 0;
	        for (var i = 0; i <= index; ++i) {
	            var sizer = sizers[i];
	            growLimit += sizer.maxSize - sizer.size;
	        }
	        // Compute how much the items to the right can shrink.
	        var shrinkLimit = 0;
	        for (var i = index + 1, n = sizers.length; i < n; ++i) {
	            var sizer = sizers[i];
	            shrinkLimit += sizer.size - sizer.minSize;
	        }
	        // Clamp the delta adjustment to the limits.
	        delta = Math.min(delta, growLimit, shrinkLimit);
	        // Grow the sizers to the left by the delta.
	        var grow = delta;
	        for (var i = index; i >= 0 && grow > 0; --i) {
	            var sizer = sizers[i];
	            var limit = sizer.maxSize - sizer.size;
	            if (limit >= grow) {
	                sizer.sizeHint = sizer.size + grow;
	                grow = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size + limit;
	                grow -= limit;
	            }
	        }
	        // Shrink the sizers to the right by the delta.
	        var shrink = delta;
	        for (var i = index + 1, n = sizers.length; i < n && shrink > 0; ++i) {
	            var sizer = sizers[i];
	            var limit = sizer.size - sizer.minSize;
	            if (limit >= shrink) {
	                sizer.sizeHint = sizer.size - shrink;
	                shrink = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size - limit;
	                shrink -= limit;
	            }
	        }
	    }
	    /**
	     * Shrink a sizer by a positive delta and adjust neighbors.
	     */
	    function shrinkSizer(sizers, index, delta) {
	        // Compute how much the items to the right can expand.
	        var growLimit = 0;
	        for (var i = index + 1, n = sizers.length; i < n; ++i) {
	            var sizer = sizers[i];
	            growLimit += sizer.maxSize - sizer.size;
	        }
	        // Compute how much the items to the left can shrink.
	        var shrinkLimit = 0;
	        for (var i = 0; i <= index; ++i) {
	            var sizer = sizers[i];
	            shrinkLimit += sizer.size - sizer.minSize;
	        }
	        // Clamp the delta adjustment to the limits.
	        delta = Math.min(delta, growLimit, shrinkLimit);
	        // Grow the sizers to the right by the delta.
	        var grow = delta;
	        for (var i = index + 1, n = sizers.length; i < n && grow > 0; ++i) {
	            var sizer = sizers[i];
	            var limit = sizer.maxSize - sizer.size;
	            if (limit >= grow) {
	                sizer.sizeHint = sizer.size + grow;
	                grow = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size + limit;
	                grow -= limit;
	            }
	        }
	        // Shrink the sizers to the left by the delta.
	        var shrink = delta;
	        for (var i = index; i >= 0 && shrink > 0; --i) {
	            var sizer = sizers[i];
	            var limit = sizer.size - sizer.minSize;
	            if (limit >= shrink) {
	                sizer.sizeHint = sizer.size - shrink;
	                shrink = 0;
	            }
	            else {
	                sizer.sizeHint = sizer.size - limit;
	                shrink -= limit;
	            }
	        }
	    }
	})(BoxEngine = exports.BoxEngine || (exports.BoxEngine = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/boxengine.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/boxlayout.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/boxlayout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.1.1/lib/index.js');
	var boxengine_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/boxengine.js');
	var layout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/layout.js');
	var panellayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/panellayout.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A layout which arranges its widgets in a single row or column.
	 */
	var BoxLayout = (function (_super) {
	    __extends(BoxLayout, _super);
	    /**
	     * Construct a new box layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function BoxLayout(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._fixed = 0;
	        _this._spacing = 4;
	        _this._dirty = false;
	        _this._sizers = [];
	        _this._items = [];
	        _this._box = null;
	        _this._alignment = 'start';
	        _this._direction = 'top-to-bottom';
	        if (options.direction !== undefined) {
	            _this._direction = options.direction;
	        }
	        if (options.alignment !== undefined) {
	            _this._alignment = options.alignment;
	        }
	        if (options.spacing !== undefined) {
	            _this._spacing = Private.clampSpacing(options.spacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    BoxLayout.prototype.dispose = function () {
	        // Dispose of the layout items.
	        algorithm_1.each(this._items, function (item) { item.dispose(); });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        this._sizers.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(BoxLayout.prototype, "direction", {
	        /**
	         * Get the layout direction for the box layout.
	         */
	        get: function () {
	            return this._direction;
	        },
	        /**
	         * Set the layout direction for the box layout.
	         */
	        set: function (value) {
	            if (this._direction === value) {
	                return;
	            }
	            this._direction = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['direction'] = value;
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxLayout.prototype, "alignment", {
	        /**
	         * Get the content alignment for the box layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        get: function () {
	            return this._alignment;
	        },
	        /**
	         * Set the content alignment for the box layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        set: function (value) {
	            if (this._alignment === value) {
	                return;
	            }
	            this._alignment = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['alignment'] = value;
	            this.parent.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxLayout.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the box layout.
	         */
	        get: function () {
	            return this._spacing;
	        },
	        /**
	         * Set the inter-element spacing for the box layout.
	         */
	        set: function (value) {
	            value = Private.clampSpacing(value);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    BoxLayout.prototype.init = function () {
	        this.parent.dataset['direction'] = this.direction;
	        this.parent.dataset['alignment'] = this.alignment;
	        _super.prototype.init.call(this);
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.attachWidget = function (index, widget) {
	        // Create and add a new layout item for the widget.
	        algorithm_1.ArrayExt.insert(this._items, index, new layout_1.LayoutItem(widget));
	        // Create and add a new sizer for the widget.
	        algorithm_1.ArrayExt.insert(this._sizers, index, new boxengine_1.BoxSizer());
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Move the layout item for the widget.
	        algorithm_1.ArrayExt.move(this._items, fromIndex, toIndex);
	        // Move the sizer for the widget.
	        algorithm_1.ArrayExt.move(this._sizers, fromIndex, toIndex);
	        // Post an update request for the parent widget.
	        this.parent.update();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    BoxLayout.prototype.detachWidget = function (index, widget) {
	        // Remove the layout item for the widget.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Remove the sizer for the widget.
	        algorithm_1.ArrayExt.removeAt(this._sizers, index);
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Dispose of the layout item.
	        item.dispose();
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    BoxLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    BoxLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    BoxLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    BoxLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    BoxLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    BoxLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    BoxLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    BoxLayout.prototype._fit = function () {
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Update the fixed space for the visible items.
	        this._fixed = this._spacing * Math.max(0, nVisible - 1);
	        // Setup the computed minimum size.
	        var horz = Private.isHorizontal(this._direction);
	        var minW = horz ? this._fixed : 0;
	        var minH = horz ? 0 : this._fixed;
	        // Update the sizers and computed minimum size.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item and corresponding box sizer.
	            var item = this._items[i];
	            var sizer = this._sizers[i];
	            // If the item is hidden, it should consume zero size.
	            if (item.isHidden) {
	                sizer.minSize = 0;
	                sizer.maxSize = 0;
	                continue;
	            }
	            // Update the size limits for the item.
	            item.fit();
	            // Update the size basis and stretch factor.
	            sizer.sizeHint = BoxLayout.getSizeBasis(item.widget);
	            sizer.stretch = BoxLayout.getStretch(item.widget);
	            // Update the sizer limits and computed min size.
	            if (horz) {
	                sizer.minSize = item.minWidth;
	                sizer.maxSize = item.maxWidth;
	                minW += item.minWidth;
	                minH = Math.max(minH, item.minHeight);
	            }
	            else {
	                sizer.minSize = item.minHeight;
	                sizer.maxSize = item.maxHeight;
	                minH += item.minHeight;
	                minW = Math.max(minW, item.minWidth);
	            }
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    BoxLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Bail early if there are no visible items to layout.
	        if (nVisible === 0) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the layout area adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Distribute the layout space and adjust the start position.
	        var delta;
	        switch (this._direction) {
	            case 'left-to-right':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, width - this._fixed));
	                break;
	            case 'top-to-bottom':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, height - this._fixed));
	                break;
	            case 'right-to-left':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, width - this._fixed));
	                left += width;
	                break;
	            case 'bottom-to-top':
	                delta = boxengine_1.BoxEngine.calc(this._sizers, Math.max(0, height - this._fixed));
	                top += height;
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Setup the variables for justification and alignment offset.
	        var extra = 0;
	        var offset = 0;
	        // Account for alignment if there is extra layout space.
	        if (delta > 0) {
	            switch (this._alignment) {
	                case 'start':
	                    break;
	                case 'center':
	                    extra = 0;
	                    offset = delta / 2;
	                    break;
	                case 'end':
	                    extra = 0;
	                    offset = delta;
	                    break;
	                case 'justify':
	                    extra = delta / nVisible;
	                    offset = 0;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Layout the items using the computed box sizes.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Fetch the computed size for the widget.
	            var size = this._sizers[i].size;
	            // Update the widget geometry and advance the relevant edge.
	            switch (this._direction) {
	                case 'left-to-right':
	                    item.update(left + offset, top, size + extra, height);
	                    left += size + extra + this._spacing;
	                    break;
	                case 'top-to-bottom':
	                    item.update(left, top + offset, width, size + extra);
	                    top += size + extra + this._spacing;
	                    break;
	                case 'right-to-left':
	                    item.update(left - offset - size - extra, top, size + extra, height);
	                    left -= size + extra + this._spacing;
	                    break;
	                case 'bottom-to-top':
	                    item.update(left, top - offset - size - extra, width, size + extra);
	                    top -= size + extra + this._spacing;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	    };
	    return BoxLayout;
	}(panellayout_1.PanelLayout));
	exports.BoxLayout = BoxLayout;
	/**
	 * The namespace for the `BoxLayout` class statics.
	 */
	(function (BoxLayout) {
	    /**
	     * Get the box layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box layout stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return Private.stretchProperty.get(widget);
	    }
	    BoxLayout.getStretch = getStretch;
	    /**
	     * Set the box layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        Private.stretchProperty.set(widget, value);
	    }
	    BoxLayout.setStretch = setStretch;
	    /**
	     * Get the box layout size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box layout size basis for the widget.
	     */
	    function getSizeBasis(widget) {
	        return Private.sizeBasisProperty.get(widget);
	    }
	    BoxLayout.getSizeBasis = getSizeBasis;
	    /**
	     * Set the box layout size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the size basis.
	     */
	    function setSizeBasis(widget, value) {
	        Private.sizeBasisProperty.set(widget, value);
	    }
	    BoxLayout.setSizeBasis = setSizeBasis;
	})(BoxLayout = exports.BoxLayout || (exports.BoxLayout = {}));
	exports.BoxLayout = BoxLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The property descriptor for a widget stretch factor.
	     */
	    Private.stretchProperty = new properties_1.AttachedProperty({
	        name: 'stretch',
	        create: function () { return 0; },
	        coerce: function (owner, value) { return Math.max(0, Math.floor(value)); },
	        changed: onChildSizingChanged
	    });
	    /**
	     * The property descriptor for a widget size basis.
	     */
	    Private.sizeBasisProperty = new properties_1.AttachedProperty({
	        name: 'sizeBasis',
	        create: function () { return 0; },
	        coerce: function (owner, value) { return Math.max(0, Math.floor(value)); },
	        changed: onChildSizingChanged
	    });
	    /**
	     * Test whether a direction has horizontal orientation.
	     */
	    function isHorizontal(dir) {
	        return dir === 'left-to-right' || dir === 'right-to-left';
	    }
	    Private.isHorizontal = isHorizontal;
	    /**
	     * Clamp a spacing value to an integer >= 0.
	     */
	    function clampSpacing(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampSpacing = clampSpacing;
	    /**
	     * The change handler for the attached sizing properties.
	     */
	    function onChildSizingChanged(child) {
	        if (child.parent && child.parent.layout instanceof BoxLayout) {
	            child.parent.fit();
	        }
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/boxlayout.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/index.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/array.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/chain.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/empty.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/filter.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/find.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/map.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/range.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/reduce.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/repeat.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/retro.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/sort.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/stride.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/string.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/take.js'));
	__export(__jupyter_require__('@phosphor/algorithm@1.1.1/lib/zip.js'));
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/array.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/array.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for array-specific algorithms.
	 */
	var ArrayExt;
	(function (ArrayExt) {
	    /**
	     * Find the index of the first occurrence of a value in an array.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param value - The value to locate in the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first occurrence of the value, or `-1`
	     *   if the value is not found.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = ['one', 'two', 'three', 'four', 'one'];
	     * ArrayExt.firstIndexOf(data, 'red');        // -1
	     * ArrayExt.firstIndexOf(data, 'one');        // 0
	     * ArrayExt.firstIndexOf(data, 'one', 1);     // 4
	     * ArrayExt.firstIndexOf(data, 'two', 2);     // -1
	     * ArrayExt.firstIndexOf(data, 'two', 2, 1);  // 1
	     * ```
	     */
	    function firstIndexOf(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (stop < start) {
	            span = (stop + 1) + (n - start);
	        }
	        else {
	            span = stop - start + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            var j = (start + i) % n;
	            if (array[j] === value) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.firstIndexOf = firstIndexOf;
	    /**
	     * Find the index of the last occurrence of a value in an array.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param value - The value to locate in the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the last occurrence of the value, or `-1`
	     *   if the value is not found.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the front of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = ['one', 'two', 'three', 'four', 'one'];
	     * ArrayExt.lastIndexOf(data, 'red');        // -1
	     * ArrayExt.lastIndexOf(data, 'one');        // 4
	     * ArrayExt.lastIndexOf(data, 'one', 1);     // 0
	     * ArrayExt.lastIndexOf(data, 'two', 0);     // -1
	     * ArrayExt.lastIndexOf(data, 'two', 0, 1);  // 1
	     * ```
	     */
	    function lastIndexOf(array, value, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (start < stop) {
	            span = (start + 1) + (n - stop);
	        }
	        else {
	            span = start - stop + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            var j = (start - i + n) % n;
	            if (array[j] === value) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.lastIndexOf = lastIndexOf;
	    /**
	     * Find the index of the first value which matches a predicate.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first matching value, or `-1` if no
	     *   matching value is found.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findFirstIndex(data, isEven);       // 1
	     * ArrayExt.findFirstIndex(data, isEven, 4);    // 5
	     * ArrayExt.findFirstIndex(data, isEven, 6);    // -1
	     * ArrayExt.findFirstIndex(data, isEven, 6, 5); // 1
	     * ```
	     */
	    function findFirstIndex(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (stop < start) {
	            span = (stop + 1) + (n - start);
	        }
	        else {
	            span = stop - start + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            var j = (start + i) % n;
	            if (fn(array[j], j)) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.findFirstIndex = findFirstIndex;
	    /**
	     * Find the index of the last value which matches a predicate.
	     *
	     * @param object - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the last matching value, or `-1` if no
	     *   matching value is found.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the front of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findLastIndex(data, isEven);        // 5
	     * ArrayExt.findLastIndex(data, isEven, 4);     // 3
	     * ArrayExt.findLastIndex(data, isEven, 0);     // -1
	     * ArrayExt.findLastIndex(data, isEven, 0, 1);  // 5
	     * ```
	     */
	    function findLastIndex(array, fn, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var n = array.length;
	        if (n === 0) {
	            return -1;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var d;
	        if (start < stop) {
	            d = (start + 1) + (n - stop);
	        }
	        else {
	            d = start - stop + 1;
	        }
	        for (var i = 0; i < d; ++i) {
	            var j = (start - i + n) % n;
	            if (fn(array[j], j)) {
	                return j;
	            }
	        }
	        return -1;
	    }
	    ArrayExt.findLastIndex = findLastIndex;
	    /**
	     * Find the first value which matches a predicate.
	     *
	     * @param array - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The first matching value, or `undefined` if no matching
	     *   value is found.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findFirstValue(data, isEven);       // 2
	     * ArrayExt.findFirstValue(data, isEven, 2);    // 4
	     * ArrayExt.findFirstValue(data, isEven, 6);    // undefined
	     * ArrayExt.findFirstValue(data, isEven, 6, 5); // 2
	     * ```
	     */
	    function findFirstValue(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var index = findFirstIndex(array, fn, start, stop);
	        return index !== -1 ? array[index] : undefined;
	    }
	    ArrayExt.findFirstValue = findFirstValue;
	    /**
	     * Find the last value which matches a predicate.
	     *
	     * @param object - The array-like object to search.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The last matching value, or `undefined` if no matching
	     *   value is found.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the front of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [1, 2, 3, 4, 3, 2, 1];
	     * ArrayExt.findLastValue(data, isEven);        // 2
	     * ArrayExt.findLastValue(data, isEven, 4);     // 4
	     * ArrayExt.findLastValue(data, isEven, 0);     // undefined
	     * ArrayExt.findLastValue(data, isEven, 0, 1);  // 2
	     * ```
	     */
	    function findLastValue(array, fn, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var index = findLastIndex(array, fn, start, stop);
	        return index !== -1 ? array[index] : undefined;
	    }
	    ArrayExt.findLastValue = findLastValue;
	    /**
	     * Find the index of the first element which compares `>=` to a value.
	     *
	     * @param array - The sorted array-like object to search.
	     *
	     * @param value - The value to locate in the array.
	     *
	     * @param fn - The 3-way comparison function to apply to the values.
	     *   It should return `< 0` if an element is less than a value, `0` if
	     *   an element is equal to a value, or `> 0` if an element is greater
	     *   than a value.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first element which compares `>=` to the
	     *   value, or `length` if there is no such element. If the computed
	     *   index for `stop` is less than `start`, then the computed index
	     *   for `start` is returned.
	     *
	     * #### Notes
	     * The array must already be sorted in ascending order according to
	     * the comparison function.
	     *
	     * #### Complexity
	     * Logarithmic.
	     *
	     * #### Undefined Behavior
	     * Searching a range which is not sorted in ascending order.
	     *
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function numberCmp(a: number, b: number): number {
	     *   return a - b;
	     * }
	     *
	     * let data = [0, 3, 4, 7, 7, 9];
	     * ArrayExt.lowerBound(data, 0, numberCmp);   // 0
	     * ArrayExt.lowerBound(data, 6, numberCmp);   // 3
	     * ArrayExt.lowerBound(data, 7, numberCmp);   // 3
	     * ArrayExt.lowerBound(data, -1, numberCmp);  // 0
	     * ArrayExt.lowerBound(data, 10, numberCmp);  // 6
	     * ```
	     */
	    function lowerBound(array, value, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var begin = start;
	        var span = stop - start + 1;
	        while (span > 0) {
	            var half = span >> 1;
	            var middle = begin + half;
	            if (fn(array[middle], value) < 0) {
	                begin = middle + 1;
	                span -= half + 1;
	            }
	            else {
	                span = half;
	            }
	        }
	        return begin;
	    }
	    ArrayExt.lowerBound = lowerBound;
	    /**
	     * Find the index of the first element which compares `>` than a value.
	     *
	     * @param array - The sorted array-like object to search.
	     *
	     * @param value - The value to locate in the array.
	     *
	     * @param fn - The 3-way comparison function to apply to the values.
	     *   It should return `< 0` if an element is less than a value, `0` if
	     *   an element is equal to a value, or `> 0` if an element is greater
	     *   than a value.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the first element which compares `>` than the
	     *   value, or `length` if there is no such element. If the computed
	     *   index for `stop` is less than `start`, then the computed index
	     *   for `start` is returned.
	     *
	     * #### Notes
	     * The array must already be sorted in ascending order according to
	     * the comparison function.
	     *
	     * #### Complexity
	     * Logarithmic.
	     *
	     * #### Undefined Behavior
	     * Searching a range which is not sorted in ascending order.
	     *
	     * A `start` or `stop` which is non-integral.
	     *
	     * Modifying the length of the array while searching.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function numberCmp(a: number, b: number): number {
	     *   return a - b;
	     * }
	     *
	     * let data = [0, 3, 4, 7, 7, 9];
	     * ArrayExt.upperBound(data, 0, numberCmp);   // 1
	     * ArrayExt.upperBound(data, 6, numberCmp);   // 3
	     * ArrayExt.upperBound(data, 7, numberCmp);   // 5
	     * ArrayExt.upperBound(data, -1, numberCmp);  // 0
	     * ArrayExt.upperBound(data, 10, numberCmp);  // 6
	     * ```
	     */
	    function upperBound(array, value, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var begin = start;
	        var span = stop - start + 1;
	        while (span > 0) {
	            var half = span >> 1;
	            var middle = begin + half;
	            if (fn(array[middle], value) > 0) {
	                span = half;
	            }
	            else {
	                begin = middle + 1;
	                span -= half + 1;
	            }
	        }
	        return begin;
	    }
	    ArrayExt.upperBound = upperBound;
	    /**
	     * Move an element in an array from one index to another.
	     *
	     * @param array - The mutable array-like object of interest.
	     *
	     * @param fromIndex - The index of the element to move. Negative
	     *   values are taken as an offset from the end of the array.
	     *
	     * @param toIndex - The target index of the element. Negative
	     *   values are taken as an offset from the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `fromIndex` or `toIndex` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2, 3, 4];
	     * ArrayExt.move(data, 1, 2);  // [0, 2, 1, 3, 4]
	     * ArrayExt.move(data, 4, 2);  // [0, 2, 4, 1, 3]
	     * ```
	     */
	    function move(array, fromIndex, toIndex) {
	        var n = array.length;
	        if (n <= 1) {
	            return;
	        }
	        if (fromIndex < 0) {
	            fromIndex = Math.max(0, fromIndex + n);
	        }
	        else {
	            fromIndex = Math.min(fromIndex, n - 1);
	        }
	        if (toIndex < 0) {
	            toIndex = Math.max(0, toIndex + n);
	        }
	        else {
	            toIndex = Math.min(toIndex, n - 1);
	        }
	        if (fromIndex === toIndex) {
	            return;
	        }
	        var value = array[fromIndex];
	        var d = fromIndex < toIndex ? 1 : -1;
	        for (var i = fromIndex; i !== toIndex; i += d) {
	            array[i] = array[i + d];
	        }
	        array[toIndex] = value;
	    }
	    ArrayExt.move = move;
	    /**
	     * Reverse an array in-place.
	     *
	     * @param array - The mutable array-like object of interest.
	     *
	     * @param start - The index of the first element in the range to be
	     *   reversed, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   reversed, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or  `stop` index which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2, 3, 4];
	     * ArrayExt.reverse(data, 1, 3);  // [0, 3, 2, 1, 4]
	     * ArrayExt.reverse(data, 3);     // [0, 3, 2, 4, 1]
	     * ArrayExt.reverse(data);        // [1, 4, 2, 3, 0]
	     * ```
	     */
	    function reverse(array, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n <= 1) {
	            return;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        while (start < stop) {
	            var a = array[start];
	            var b = array[stop];
	            array[start++] = b;
	            array[stop--] = a;
	        }
	    }
	    ArrayExt.reverse = reverse;
	    /**
	     * Rotate the elements of an array in-place.
	     *
	     * @param array - The mutable array-like object of interest.
	     *
	     * @param delta - The amount of rotation to apply to the elements. A
	     *   positive value will rotate the elements to the left. A negative
	     *   value will rotate the elements to the right.
	     *
	     * @param start - The index of the first element in the range to be
	     *   rotated, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   rotated, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `delta`, `start`, or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2, 3, 4];
	     * ArrayExt.rotate(data, 2);        // [2, 3, 4, 0, 1]
	     * ArrayExt.rotate(data, -2);       // [0, 1, 2, 3, 4]
	     * ArrayExt.rotate(data, 10);       // [0, 1, 2, 3, 4]
	     * ArrayExt.rotate(data, 9);        // [4, 0, 1, 2, 3]
	     * ArrayExt.rotate(data, 2, 1, 3);  // [4, 2, 0, 1, 3]
	     * ```
	     */
	    function rotate(array, delta, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n <= 1) {
	            return;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        if (start >= stop) {
	            return;
	        }
	        var length = stop - start + 1;
	        if (delta > 0) {
	            delta = delta % length;
	        }
	        else if (delta < 0) {
	            delta = ((delta % length) + length) % length;
	        }
	        if (delta === 0) {
	            return;
	        }
	        var pivot = start + delta;
	        reverse(array, start, pivot - 1);
	        reverse(array, pivot, stop);
	        reverse(array, start, stop);
	    }
	    ArrayExt.rotate = rotate;
	    /**
	     * Fill an array with a static value.
	     *
	     * @param array - The mutable array-like object to fill.
	     *
	     * @param value - The static value to use to fill the array.
	     *
	     * @param start - The index of the first element in the range to be
	     *   filled, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   filled, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * #### Notes
	     * If `stop < start` the fill will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * A `start` or `stop` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = ['one', 'two', 'three', 'four'];
	     * ArrayExt.fill(data, 'r');        // ['r', 'r', 'r', 'r']
	     * ArrayExt.fill(data, 'g', 1);     // ['r', 'g', 'g', 'g']
	     * ArrayExt.fill(data, 'b', 2, 3);  // ['r', 'g', 'b', 'b']
	     * ArrayExt.fill(data, 'z', 3, 1);  // ['z', 'z', 'b', 'z']
	     * ```
	     */
	    function fill(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var span;
	        if (stop < start) {
	            span = (stop + 1) + (n - start);
	        }
	        else {
	            span = stop - start + 1;
	        }
	        for (var i = 0; i < span; ++i) {
	            array[(start + i) % n] = value;
	        }
	    }
	    ArrayExt.fill = fill;
	    /**
	     * Insert a value into an array at a specific index.
	     *
	     * @param array - The array of interest.
	     *
	     * @param index - The index at which to insert the value. Negative
	     *   values are taken as an offset from the end of the array.
	     *
	     * @param value - The value to set at the specified index.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 1, 2];
	     * ArrayExt.insert(data, 0, -1);  // [-1, 0, 1, 2]
	     * ArrayExt.insert(data, 2, 12);  // [-1, 0, 12, 1, 2]
	     * ArrayExt.insert(data, -1, 7);  // [-1, 0, 12, 1, 7, 2]
	     * ArrayExt.insert(data, 6, 19);  // [-1, 0, 12, 1, 7, 2, 19]
	     * ```
	     */
	    function insert(array, index, value) {
	        var n = array.length;
	        if (index < 0) {
	            index = Math.max(0, index + n);
	        }
	        else {
	            index = Math.min(index, n);
	        }
	        for (var i = n; i > index; --i) {
	            array[i] = array[i - 1];
	        }
	        array[index] = value;
	    }
	    ArrayExt.insert = insert;
	    /**
	     * Remove and return a value at a specific index in an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param index - The index of the value to remove. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The value at the specified index, or `undefined` if the
	     *   index is out of range.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeAt(data, 2);   // 23
	     * ArrayExt.removeAt(data, -2);  // 12
	     * ArrayExt.removeAt(data, 10);  // undefined;
	     * ```
	     */
	    function removeAt(array, index) {
	        var n = array.length;
	        if (index < 0) {
	            index += n;
	        }
	        if (index < 0 || index >= n) {
	            return undefined;
	        }
	        var value = array[index];
	        for (var i = index + 1; i < n; ++i) {
	            array[i - 1] = array[i];
	        }
	        array.length = n - 1;
	        return value;
	    }
	    ArrayExt.removeAt = removeAt;
	    /**
	     * Remove the first occurrence of a value from an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param value - The value to remove from the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the removed value, or `-1` if the value
	     *   is not contained in the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeFirstOf(data, 12);        // 1
	     * ArrayExt.removeFirstOf(data, 17);        // -1
	     * ArrayExt.removeFirstOf(data, 39, 3);     // -1
	     * ArrayExt.removeFirstOf(data, 39, 3, 2);  // 2
	     * ```
	     */
	    function removeFirstOf(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var index = firstIndexOf(array, value, start, stop);
	        if (index !== -1) {
	            removeAt(array, index);
	        }
	        return index;
	    }
	    ArrayExt.removeFirstOf = removeFirstOf;
	    /**
	     * Remove the last occurrence of a value from an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param value - The value to remove from the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The index of the removed value, or `-1` if the value
	     *   is not contained in the array.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeLastOf(data, 12);        // 5
	     * ArrayExt.removeLastOf(data, 17);        // -1
	     * ArrayExt.removeLastOf(data, 39, 2);     // -1
	     * ArrayExt.removeLastOf(data, 39, 2, 3);  // 3
	     * ```
	     */
	    function removeLastOf(array, value, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var index = lastIndexOf(array, value, start, stop);
	        if (index !== -1) {
	            removeAt(array, index);
	        }
	        return index;
	    }
	    ArrayExt.removeLastOf = removeLastOf;
	    /**
	     * Remove all occurrences of a value from an array.
	     *
	     * @param array - The array of interest.
	     *
	     * @param value - The value to remove from the array. Values are
	     *   compared using strict `===` equality.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The number of elements removed from the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will conceptually wrap at the end of
	     * the array, however the array will be traversed front-to-back.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * let data = [14, 12, 23, 39, 14, 12, 19, 14];
	     * ArrayExt.removeAllOf(data, 12);        // 2
	     * ArrayExt.removeAllOf(data, 17);        // 0
	     * ArrayExt.removeAllOf(data, 14, 1, 4);  // 1
	     * ```
	     */
	    function removeAllOf(array, value, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var count = 0;
	        for (var i = 0; i < n; ++i) {
	            if (start <= stop && (i >= start && i <= stop) && array[i] === value) {
	                count++;
	            }
	            else if (stop < start && (i <= stop || i >= start) && array[i] === value) {
	                count++;
	            }
	            else if (count > 0) {
	                array[i - count] = array[i];
	            }
	        }
	        if (count > 0) {
	            array.length = n - count;
	        }
	        return count;
	    }
	    ArrayExt.removeAllOf = removeAllOf;
	    /**
	     * Remove the first occurrence of a value which matches a predicate.
	     *
	     * @param array - The array of interest.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The removed `{ index, value }`, which will be `-1` and
	     *   `undefined` if the value is not contained in the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeFirstWhere(data, isEven);     // { index: 0, value: 0 }
	     * ArrayExt.removeFirstWhere(data, isEven, 2);  // { index: 3, value: 14 }
	     * ArrayExt.removeFirstWhere(data, isEven, 4);  // { index: -1, value: undefined }
	     * ```
	     */
	    function removeFirstWhere(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var value;
	        var index = findFirstIndex(array, fn, start, stop);
	        if (index !== -1) {
	            value = removeAt(array, index);
	        }
	        return { index: index, value: value };
	    }
	    ArrayExt.removeFirstWhere = removeFirstWhere;
	    /**
	     * Remove the last occurrence of a value which matches a predicate.
	     *
	     * @param array - The array of interest.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The removed `{ index, value }`, which will be `-1` and
	     *   `undefined` if the value is not contained in the array.
	     *
	     * #### Notes
	     * If `start < stop` the search will wrap at the end of the array.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * let data = [0, 12, 23, 39, 14, 12, 75];
	     * ArrayExt.removeLastWhere(data, isEven);        // { index: 5, value: 12 }
	     * ArrayExt.removeLastWhere(data, isEven, 2);     // { index: 1, value: 12 }
	     * ArrayExt.removeLastWhere(data, isEven, 2, 1);  // { index: -1, value: undefined }
	     * ```
	     */
	    function removeLastWhere(array, fn, start, stop) {
	        if (start === void 0) { start = -1; }
	        if (stop === void 0) { stop = 0; }
	        var value;
	        var index = findLastIndex(array, fn, start, stop);
	        if (index !== -1) {
	            value = removeAt(array, index);
	        }
	        return { index: index, value: value };
	    }
	    ArrayExt.removeLastWhere = removeLastWhere;
	    /**
	     * Remove all occurrences of values which match a predicate.
	     *
	     * @param array - The array of interest.
	     *
	     * @param fn - The predicate function to apply to the values.
	     *
	     * @param start - The index of the first element in the range to be
	     *   searched, inclusive. The default value is `0`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @param stop - The index of the last element in the range to be
	     *   searched, inclusive. The default value is `-1`. Negative values
	     *   are taken as an offset from the end of the array.
	     *
	     * @returns The number of elements removed from the array.
	     *
	     * #### Notes
	     * If `stop < start` the search will conceptually wrap at the end of
	     * the array, however the array will be traversed front-to-back.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Example
	     * ```typescript
	     * import { ArrayExt } from '@phosphor/algorithm';
	     *
	     * function isEven(value: number): boolean {
	     *   return value % 2 === 0;
	     * }
	     *
	     * function isNegative(value: number): boolean {
	     *   return value < 0;
	     * }
	     *
	     * let data = [0, 12, -13, -9, 23, 39, 14, -15, 12, 75];
	     * ArrayExt.removeAllWhere(data, isEven);            // 4
	     * ArrayExt.removeAllWhere(data, isNegative, 0, 3);  // 2
	     * ```
	     */
	    function removeAllWhere(array, fn, start, stop) {
	        if (start === void 0) { start = 0; }
	        if (stop === void 0) { stop = -1; }
	        var n = array.length;
	        if (n === 0) {
	            return 0;
	        }
	        if (start < 0) {
	            start = Math.max(0, start + n);
	        }
	        else {
	            start = Math.min(start, n - 1);
	        }
	        if (stop < 0) {
	            stop = Math.max(0, stop + n);
	        }
	        else {
	            stop = Math.min(stop, n - 1);
	        }
	        var count = 0;
	        for (var i = 0; i < n; ++i) {
	            if (start <= stop && (i >= start && i <= stop) && fn(array[i], i)) {
	                count++;
	            }
	            else if (stop < start && (i <= stop || i >= start) && fn(array[i], i)) {
	                count++;
	            }
	            else if (count > 0) {
	                array[i - count] = array[i];
	            }
	        }
	        if (count > 0) {
	            array.length = n - count;
	        }
	        return count;
	    }
	    ArrayExt.removeAllWhere = removeAllWhere;
	})(ArrayExt = exports.ArrayExt || (exports.ArrayExt = {}));
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/array.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/chain.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/chain.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Chain together several iterables.
	 *
	 * @param objects - The iterable or array-like objects of interest.
	 *
	 * @returns An iterator which yields the values of the iterables
	 *   in the order in which they are supplied.
	 *
	 * #### Example
	 * ```typescript
	 * import { chain, toArray } from '@phosphor/algorithm';
	 *
	 * let data1 = [1, 2, 3];
	 * let data2 = [4, 5, 6];
	 *
	 * let stream = chain(data1, data2);
	 *
	 * toArray(stream);  // [1, 2, 3, 4, 5, 6]
	 * ```
	 */
	function chain() {
	    var objects = [];
	    for (var _i = 0; _i < arguments.length; _i++) {
	        objects[_i] = arguments[_i];
	    }
	    return new ChainIterator(iter_1.iter(objects.map(iter_1.iter)));
	}
	exports.chain = chain;
	/**
	 * An iterator which chains together several iterators.
	 */
	var ChainIterator = (function () {
	    /**
	     * Construct a new chain iterator.
	     *
	     * @param source - The iterator of iterators of interest.
	     */
	    function ChainIterator(source) {
	        this._cloned = false;
	        this._source = source;
	        this._active = undefined;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    ChainIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    ChainIterator.prototype.clone = function () {
	        var result = new ChainIterator(this._source.clone());
	        result._active = this._active && this._active.clone();
	        result._cloned = true;
	        this._cloned = true;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    ChainIterator.prototype.next = function () {
	        if (this._active === undefined) {
	            var active = this._source.next();
	            if (active === undefined) {
	                return undefined;
	            }
	            this._active = this._cloned ? active.clone() : active;
	        }
	        var value = this._active.next();
	        if (value !== undefined) {
	            return value;
	        }
	        this._active = undefined;
	        return this.next();
	    };
	    return ChainIterator;
	}());
	exports.ChainIterator = ChainIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/chain.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/iter.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/iter.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator for an iterable object.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @returns A new iterator for the given object.
	 *
	 * #### Notes
	 * This function allows iteration algorithms to operate on user-defined
	 * iterable types and builtin array-like objects in a uniform fashion.
	 */
	function iter(object) {
	    var it;
	    if (typeof object.iter === 'function') {
	        it = object.iter();
	    }
	    else {
	        it = new ArrayIterator(object);
	    }
	    return it;
	}
	exports.iter = iter;
	/**
	 * Invoke a function for each value in an iterable.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The callback function to invoke for each value.
	 *
	 * #### Notes
	 * Iteration can be terminated early by returning `false` from the
	 * callback function.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { each } from '@phosphor/algorithm';
	 *
	 * let data = [5, 7, 0, -2, 9];
	 *
	 * each(data, value => { console.log(value); });
	 * ```
	 */
	function each(object, fn) {
	    var index = 0;
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, index++) === false) {
	            return;
	        }
	    }
	}
	exports.each = each;
	/**
	 * Test whether all values in an iterable satisfy a predicate.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The predicate function to invoke for each value.
	 *
	 * @returns `true` if all values pass the test, `false` otherwise.
	 *
	 * #### Notes
	 * Iteration terminates on the first `false` predicate result.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { every } from '@phosphor/algorithm';
	 *
	 * let data = [5, 7, 1];
	 *
	 * every(data, value => value % 2 === 0);  // false
	 * every(data, value => value % 2 === 1);  // true
	 * ```
	 */
	function every(object, fn) {
	    var index = 0;
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (!fn(value, index++)) {
	            return false;
	        }
	    }
	    return true;
	}
	exports.every = every;
	/**
	 * Test whether any value in an iterable satisfies a predicate.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The predicate function to invoke for each value.
	 *
	 * @returns `true` if any value passes the test, `false` otherwise.
	 *
	 * #### Notes
	 * Iteration terminates on the first `true` predicate result.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { some } from '@phosphor/algorithm';
	 *
	 * let data = [5, 7, 1];
	 *
	 * some(data, value => value === 7);  // true
	 * some(data, value => value === 3);  // false
	 * ```
	 */
	function some(object, fn) {
	    var index = 0;
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, index++)) {
	            return true;
	        }
	    }
	    return false;
	}
	exports.some = some;
	/**
	 * Create an array from an iterable of values.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @returns A new array of values from the given object.
	 *
	 * #### Example
	 * ```typescript
	 * import { iter, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = iter(data);
	 *
	 * toArray(stream);  // [1, 2, 3, 4, 5, 6];
	 * ```
	 */
	function toArray(object) {
	    var index = 0;
	    var result = [];
	    var it = iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        result[index++] = value;
	    }
	    return result;
	}
	exports.toArray = toArray;
	/**
	 * An iterator for an array-like object.
	 *
	 * #### Notes
	 * This iterator can be used for any builtin JS array-like object.
	 */
	var ArrayIterator = (function () {
	    /**
	     * Construct a new array iterator.
	     *
	     * @param source - The array-like object of interest.
	     */
	    function ArrayIterator(source) {
	        this._index = 0;
	        this._source = source;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    ArrayIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    ArrayIterator.prototype.clone = function () {
	        var result = new ArrayIterator(this._source);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    ArrayIterator.prototype.next = function () {
	        if (this._index >= this._source.length) {
	            return undefined;
	        }
	        return this._source[this._index++];
	    };
	    return ArrayIterator;
	}());
	exports.ArrayIterator = ArrayIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/iter.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/empty.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/empty.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an empty iterator.
	 *
	 * @returns A new iterator which yields nothing.
	 *
	 * #### Example
	 * ```typescript
	 * import { empty, toArray } from '@phosphor/algorithm';
	 *
	 * let stream = empty<number>();
	 *
	 * toArray(stream);  // []
	 * ```
	 */
	function empty() {
	    return new EmptyIterator();
	}
	exports.empty = empty;
	/**
	 * An iterator which is always empty.
	 */
	var EmptyIterator = (function () {
	    /**
	     * Construct a new empty iterator.
	     */
	    function EmptyIterator() {
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    EmptyIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    EmptyIterator.prototype.clone = function () {
	        return new EmptyIterator();
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    EmptyIterator.prototype.next = function () {
	        return undefined;
	    };
	    return EmptyIterator;
	}());
	exports.EmptyIterator = EmptyIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/empty.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/filter.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/filter.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Filter an iterable for values which pass a test.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The predicate function to invoke for each value.
	 *
	 * @returns An iterator which yields the values which pass the test.
	 *
	 * #### Example
	 * ```typescript
	 * import { filter, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = filter(data, value => value % 2 === 0);
	 *
	 * toArray(stream);  // [2, 4, 6]
	 * ```
	 */
	function filter(object, fn) {
	    return new FilterIterator(iter_1.iter(object), fn);
	}
	exports.filter = filter;
	/**
	 * An iterator which yields values which pass a test.
	 */
	var FilterIterator = (function () {
	    /**
	     * Construct a new filter iterator.
	     *
	     * @param source - The iterator of values of interest.
	     *
	     * @param fn - The predicate function to invoke for each value.
	     */
	    function FilterIterator(source, fn) {
	        this._index = 0;
	        this._source = source;
	        this._fn = fn;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    FilterIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    FilterIterator.prototype.clone = function () {
	        var result = new FilterIterator(this._source.clone(), this._fn);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    FilterIterator.prototype.next = function () {
	        var fn = this._fn;
	        var it = this._source;
	        var value;
	        while ((value = it.next()) !== undefined) {
	            if (fn(value, this._index++)) {
	                return value;
	            }
	        }
	        return undefined;
	    };
	    return FilterIterator;
	}());
	exports.FilterIterator = FilterIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/filter.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/find.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/find.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Find the first value in an iterable which matches a predicate.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The predicate function to apply to the values.
	 *
	 * @returns The first matching value, or `undefined` if no matching
	 *   value is found.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { find } from '@phosphor/algorithm';
	 *
	 * interface IAnimal { species: string, name: string };
	 *
	 * function isCat(value: IAnimal): boolean {
	 *   return value.species === 'cat';
	 * }
	 *
	 * let data: IAnimal[] = [
	 *   { species: 'dog', name: 'spot' },
	 *   { species: 'cat', name: 'fluffy' },
	 *   { species: 'alligator', name: 'pocho' }
	 * ];
	 *
	 * find(data, isCat).name;  // 'fluffy'
	 * ```
	 */
	function find(object, fn) {
	    var index = 0;
	    var it = iter_1.iter(object);
	    var value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, index++)) {
	            return value;
	        }
	    }
	    return undefined;
	}
	exports.find = find;
	/**
	 * Find the minimum value in an iterable.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The 3-way comparison function to apply to the values.
	 *   It should return `< 0` if the first value is less than the second.
	 *   `0` if the values are equivalent, or `> 0` if the first value is
	 *   greater than the second.
	 *
	 * @returns The minimum value in the iterable. If multiple values are
	 *   equivalent to the minimum, the left-most value is returned. If
	 *   the iterable is empty, this returns `undefined`.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { min } from '@phosphor/algorithm';
	 *
	 * function numberCmp(a: number, b: number): number {
	 *   return a - b;
	 * }
	 *
	 * min([7, 4, 0, 3, 9, 4], numberCmp);  // 0
	 * ```
	 */
	function min(object, fn) {
	    var it = iter_1.iter(object);
	    var value = it.next();
	    if (value === undefined) {
	        return undefined;
	    }
	    var result = value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, result) < 0) {
	            result = value;
	        }
	    }
	    return result;
	}
	exports.min = min;
	/**
	 * Find the maximum value in an iterable.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The 3-way comparison function to apply to the values.
	 *   It should return `< 0` if the first value is less than the second.
	 *   `0` if the values are equivalent, or `> 0` if the first value is
	 *   greater than the second.
	 *
	 * @returns The maximum value in the iterable. If multiple values are
	 *   equivalent to the maximum, the left-most value is returned. If
	 *   the iterable is empty, this returns `undefined`.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { max } from '@phosphor/algorithm';
	 *
	 * function numberCmp(a: number, b: number): number {
	 *   return a - b;
	 * }
	 *
	 * max([7, 4, 0, 3, 9, 4], numberCmp);  // 9
	 * ```
	 */
	function max(object, fn) {
	    var it = iter_1.iter(object);
	    var value = it.next();
	    if (value === undefined) {
	        return undefined;
	    }
	    var result = value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, result) > 0) {
	            result = value;
	        }
	    }
	    return result;
	}
	exports.max = max;
	/**
	 * Find the minimum and maximum values in an iterable.
	 *
	 * @param object - The iterable or array-like object to search.
	 *
	 * @param fn - The 3-way comparison function to apply to the values.
	 *   It should return `< 0` if the first value is less than the second.
	 *   `0` if the values are equivalent, or `> 0` if the first value is
	 *   greater than the second.
	 *
	 * @returns A 2-tuple of the `[min, max]` values in the iterable. If
	 *   multiple values are equivalent, the left-most values are returned.
	 *   If the iterable is empty, this returns `undefined`.
	 *
	 * #### Complexity
	 * Linear.
	 *
	 * #### Example
	 * ```typescript
	 * import { minmax } from '@phosphor/algorithm';
	 *
	 * function numberCmp(a: number, b: number): number {
	 *   return a - b;
	 * }
	 *
	 * minmax([7, 4, 0, 3, 9, 4], numberCmp);  // [0, 9]
	 * ```
	 */
	function minmax(object, fn) {
	    var it = iter_1.iter(object);
	    var value = it.next();
	    if (value === undefined) {
	        return undefined;
	    }
	    var vmin = value;
	    var vmax = value;
	    while ((value = it.next()) !== undefined) {
	        if (fn(value, vmin) < 0) {
	            vmin = value;
	        }
	        else if (fn(value, vmax) > 0) {
	            vmax = value;
	        }
	    }
	    return [vmin, vmax];
	}
	exports.minmax = minmax;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/find.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/map.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/map.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Transform the values of an iterable with a mapping function.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param fn - The mapping function to invoke for each value.
	 *
	 * @returns An iterator which yields the transformed values.
	 *
	 * #### Example
	 * ```typescript
	 * import { map, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3];
	 *
	 * let stream = map(data, value => value * 2);
	 *
	 * toArray(stream);  // [2, 4, 6]
	 * ```
	 */
	function map(object, fn) {
	    return new MapIterator(iter_1.iter(object), fn);
	}
	exports.map = map;
	/**
	 * An iterator which transforms values using a mapping function.
	 */
	var MapIterator = (function () {
	    /**
	     * Construct a new map iterator.
	     *
	     * @param source - The iterator of values of interest.
	     *
	     * @param fn - The mapping function to invoke for each value.
	     */
	    function MapIterator(source, fn) {
	        this._index = 0;
	        this._source = source;
	        this._fn = fn;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    MapIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    MapIterator.prototype.clone = function () {
	        var result = new MapIterator(this._source.clone(), this._fn);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    MapIterator.prototype.next = function () {
	        var value = this._source.next();
	        if (value === undefined) {
	            return undefined;
	        }
	        return this._fn.call(undefined, value, this._index++);
	    };
	    return MapIterator;
	}());
	exports.MapIterator = MapIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/map.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/range.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/range.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator of evenly spaced values.
	 *
	 * @param start - The starting value for the range, inclusive.
	 *
	 * @param stop - The stopping value for the range, exclusive.
	 *
	 * @param step - The distance between each value.
	 *
	 * @returns An iterator which produces evenly spaced values.
	 *
	 * #### Notes
	 * In the single argument form of `range(stop)`, `start` defaults to
	 * `0` and `step` defaults to `1`.
	 *
	 * In the two argument form of `range(start, stop)`, `step` defaults
	 * to `1`.
	 */
	function range(start, stop, step) {
	    if (stop === undefined) {
	        return new RangeIterator(0, start, 1);
	    }
	    if (step === undefined) {
	        return new RangeIterator(start, stop, 1);
	    }
	    return new RangeIterator(start, stop, step);
	}
	exports.range = range;
	/**
	 * An iterator which produces a range of evenly spaced values.
	 */
	var RangeIterator = (function () {
	    /**
	     * Construct a new range iterator.
	     *
	     * @param start - The starting value for the range, inclusive.
	     *
	     * @param stop - The stopping value for the range, exclusive.
	     *
	     * @param step - The distance between each value.
	     */
	    function RangeIterator(start, stop, step) {
	        this._index = 0;
	        this._start = start;
	        this._stop = stop;
	        this._step = step;
	        this._length = Private.rangeLength(start, stop, step);
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    RangeIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    RangeIterator.prototype.clone = function () {
	        var result = new RangeIterator(this._start, this._stop, this._step);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    RangeIterator.prototype.next = function () {
	        if (this._index >= this._length) {
	            return undefined;
	        }
	        return this._start + this._step * this._index++;
	    };
	    return RangeIterator;
	}());
	exports.RangeIterator = RangeIterator;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Compute the effective length of a range.
	     *
	     * @param start - The starting value for the range, inclusive.
	     *
	     * @param stop - The stopping value for the range, exclusive.
	     *
	     * @param step - The distance between each value.
	     *
	     * @returns The number of steps need to traverse the range.
	     */
	    function rangeLength(start, stop, step) {
	        if (step === 0) {
	            return Infinity;
	        }
	        if (start > stop && step > 0) {
	            return 0;
	        }
	        if (start < stop && step < 0) {
	            return 0;
	        }
	        return Math.ceil((stop - start) / step);
	    }
	    Private.rangeLength = rangeLength;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/range.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/reduce.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/reduce.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	function reduce(object, fn, initial) {
	    // Setup the iterator and fetch the first value.
	    var index = 0;
	    var it = iter_1.iter(object);
	    var first = it.next();
	    // An empty iterator and no initial value is an error.
	    if (first === undefined && initial === undefined) {
	        throw new TypeError('Reduce of empty iterable with no initial value.');
	    }
	    // If the iterator is empty, return the initial value.
	    if (first === undefined) {
	        return initial;
	    }
	    // If the iterator has a single item and no initial value, the
	    // reducer is not invoked and the first item is the return value.
	    var second = it.next();
	    if (second === undefined && initial === undefined) {
	        return first;
	    }
	    // If iterator has a single item and an initial value is provided,
	    // the reducer is invoked and that result is the return value.
	    if (second === undefined) {
	        return fn(initial, first, index++);
	    }
	    // Setup the initial accumlated value.
	    var accumulator;
	    if (initial === undefined) {
	        accumulator = fn(first, second, index++);
	    }
	    else {
	        accumulator = fn(fn(initial, first, index++), second, index++);
	    }
	    // Iterate the rest of the values, updating the accumulator.
	    var next;
	    while ((next = it.next()) !== undefined) {
	        accumulator = fn(accumulator, next, index++);
	    }
	    // Return the final accumulated value.
	    return accumulator;
	}
	exports.reduce = reduce;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/reduce.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/repeat.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/repeat.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator which repeats a value a number of times.
	 *
	 * @param value - The value to repeat.
	 *
	 * @param count - The number of times to repeat the value.
	 *
	 * @returns A new iterator which repeats the specified value.
	 *
	 * #### Example
	 * ```typescript
	 * import { repeat, toArray } from '@phosphor/algorithm';
	 *
	 * let stream = repeat(7, 3);
	 *
	 * toArray(stream);  // [7, 7, 7]
	 * ```
	 */
	function repeat(value, count) {
	    return new RepeatIterator(value, count);
	}
	exports.repeat = repeat;
	/**
	 * Create an iterator which yields a value a single time.
	 *
	 * @param value - The value to wrap in an iterator.
	 *
	 * @returns A new iterator which yields the value a single time.
	 *
	 * #### Example
	 * ```typescript
	 * import { once, toArray } from '@phosphor/algorithm';
	 *
	 * let stream = once(7);
	 *
	 * toArray(stream);  // [7]
	 * ```
	 */
	function once(value) {
	    return new RepeatIterator(value, 1);
	}
	exports.once = once;
	/**
	 * An iterator which repeats a value a specified number of times.
	 */
	var RepeatIterator = (function () {
	    /**
	     * Construct a new repeat iterator.
	     *
	     * @param value - The value to repeat.
	     *
	     * @param count - The number of times to repeat the value.
	     */
	    function RepeatIterator(value, count) {
	        this._value = value;
	        this._count = count;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    RepeatIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    RepeatIterator.prototype.clone = function () {
	        return new RepeatIterator(this._value, this._count);
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    RepeatIterator.prototype.next = function () {
	        if (this._count <= 0) {
	            return undefined;
	        }
	        this._count--;
	        return this._value;
	    };
	    return RepeatIterator;
	}());
	exports.RepeatIterator = RepeatIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/repeat.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/retro.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/retro.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Create an iterator for a retroable object.
	 *
	 * @param object - The retroable or array-like object of interest.
	 *
	 * @returns An iterator which traverses the object's values in reverse.
	 *
	 * #### Example
	 * ```typescript
	 * import { retro, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = retro(data);
	 *
	 * toArray(stream);  // [6, 5, 4, 3, 2, 1]
	 * ```
	 */
	function retro(object) {
	    var it;
	    if (typeof object.retro === 'function') {
	        it = object.retro();
	    }
	    else {
	        it = new RetroArrayIterator(object);
	    }
	    return it;
	}
	exports.retro = retro;
	/**
	 * An iterator which traverses an array-like object in reverse.
	 *
	 * #### Notes
	 * This iterator can be used for any builtin JS array-like object.
	 */
	var RetroArrayIterator = (function () {
	    /**
	     * Construct a new retro iterator.
	     *
	     * @param source - The array-like object of interest.
	     */
	    function RetroArrayIterator(source) {
	        this._source = source;
	        this._index = source.length - 1;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    RetroArrayIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    RetroArrayIterator.prototype.clone = function () {
	        var result = new RetroArrayIterator(this._source);
	        result._index = this._index;
	        return result;
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    RetroArrayIterator.prototype.next = function () {
	        if (this._index < 0 || this._index >= this._source.length) {
	            return undefined;
	        }
	        return this._source[this._index--];
	    };
	    return RetroArrayIterator;
	}());
	exports.RetroArrayIterator = RetroArrayIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/retro.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/sort.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/sort.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Topologically sort an iterable of edges.
	 *
	 * @param edges - The iterable or array-like object of edges to sort.
	 *   An edge is represented as a 2-tuple of `[fromNode, toNode]`.
	 *
	 * @returns The topologically sorted array of nodes.
	 *
	 * #### Notes
	 * If a cycle is present in the graph, the cycle will be ignored and
	 * the return value will be only approximately sorted.
	 *
	 * #### Example
	 * ```typescript
	 * import { topologicSort } from '@phosphor/algorithm';
	 *
	 * let data = [
	 *   ['d', 'e'],
	 *   ['c', 'd'],
	 *   ['a', 'b'],
	 *   ['b', 'c']
	 * ];
	 *
	 * topologicSort(data);  // ['a', 'b', 'c', 'd', 'e']
	 */
	function topologicSort(edges) {
	    // Setup the shared sorting state.
	    var sorted = [];
	    var visited = new Set();
	    var graph = new Map();
	    // Add the edges to the graph.
	    iter_1.each(edges, addEdge);
	    // Visit each node in the graph.
	    graph.forEach(function (v, k) { visit(k); });
	    // Return the sorted results.
	    return sorted;
	    // Add an edge to the graph.
	    function addEdge(edge) {
	        var fromNode = edge[0], toNode = edge[1];
	        var children = graph.get(toNode);
	        if (children) {
	            children.push(fromNode);
	        }
	        else {
	            graph.set(toNode, [fromNode]);
	        }
	    }
	    // Recursively visit the node.
	    function visit(node) {
	        if (visited.has(node)) {
	            return;
	        }
	        visited.add(node);
	        var children = graph.get(node);
	        if (children) {
	            children.forEach(visit);
	        }
	        sorted.push(node);
	    }
	}
	exports.topologicSort = topologicSort;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/sort.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/stride.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/stride.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Iterate over an iterable using a stepped increment.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param step - The distance to step on each iteration. A value
	 *   of less than `1` will behave the same as a value of `1`.
	 *
	 * @returns An iterator which traverses the iterable step-wise.
	 *
	 * #### Example
	 * ```typescript
	 * import { stride, toArray } from '@phosphor/algorithm';
	 *
	 * let data = [1, 2, 3, 4, 5, 6];
	 *
	 * let stream = stride(data, 2);
	 *
	 * toArray(stream);  // [1, 3, 5];
	 * ```
	 */
	function stride(object, step) {
	    return new StrideIterator(iter_1.iter(object), step);
	}
	exports.stride = stride;
	/**
	 * An iterator which traverses a source iterator step-wise.
	 */
	var StrideIterator = (function () {
	    /**
	     * Construct a new stride iterator.
	     *
	     * @param source - The iterator of values of interest.
	     *
	     * @param step - The distance to step on each iteration. A value
	     *   of less than `1` will behave the same as a value of `1`.
	     */
	    function StrideIterator(source, step) {
	        this._source = source;
	        this._step = step;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    StrideIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    StrideIterator.prototype.clone = function () {
	        return new StrideIterator(this._source.clone(), this._step);
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    StrideIterator.prototype.next = function () {
	        var value = this._source.next();
	        for (var n = this._step - 1; n > 0; --n) {
	            this._source.next();
	        }
	        return value;
	    };
	    return StrideIterator;
	}());
	exports.StrideIterator = StrideIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/stride.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/string.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/string.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for string-specific algorithms.
	 */
	var StringExt;
	(function (StringExt) {
	    /**
	     * Find the indices of characters in a source text.
	     *
	     * @param source - The source text which should be searched.
	     *
	     * @param query - The characters to locate in the source text.
	     *
	     * @param start - The index to start the search.
	     *
	     * @returns The matched indices, or `null` if there is no match.
	     *
	     * #### Complexity
	     * Linear on `sourceText`.
	     *
	     * #### Notes
	     * In order for there to be a match, all of the characters in `query`
	     * **must** appear in `source` in the order given by `query`.
	     *
	     * Characters are matched using strict `===` equality.
	     */
	    function findIndices(source, query, start) {
	        if (start === void 0) { start = 0; }
	        var indices = new Array(query.length);
	        for (var i = 0, j = start, n = query.length; i < n; ++i, ++j) {
	            j = source.indexOf(query[i], j);
	            if (j === -1) {
	                return null;
	            }
	            indices[i] = j;
	        }
	        return indices;
	    }
	    StringExt.findIndices = findIndices;
	    /**
	     * A string matcher which uses a sum-of-squares algorithm.
	     *
	     * @param source - The source text which should be searched.
	     *
	     * @param query - The characters to locate in the source text.
	     *
	     * @param start - The index to start the search.
	     *
	     * @returns The match result, or `null` if there is no match.
	     *   A lower `score` represents a stronger match.
	     *
	     * #### Complexity
	     * Linear on `sourceText`.
	     *
	     * #### Notes
	     * This scoring algorithm uses a sum-of-squares approach to determine
	     * the score. In order for there to be a match, all of the characters
	     * in `query` **must** appear in `source` in order. The index of each
	     * matching character is squared and added to the score. This means
	     * that early and consecutive character matches are preferred, while
	     * late matches are heavily penalized.
	     */
	    function matchSumOfSquares(source, query, start) {
	        if (start === void 0) { start = 0; }
	        var indices = findIndices(source, query, start);
	        if (!indices) {
	            return null;
	        }
	        var score = 0;
	        for (var i = 0, n = indices.length; i < n; ++i) {
	            var j = indices[i] - start;
	            score += j * j;
	        }
	        return { score: score, indices: indices };
	    }
	    StringExt.matchSumOfSquares = matchSumOfSquares;
	    /**
	     * A string matcher which uses a sum-of-deltas algorithm.
	     *
	     * @param source - The source text which should be searched.
	     *
	     * @param query - The characters to locate in the source text.
	     *
	     * @param start - The index to start the search.
	     *
	     * @returns The match result, or `null` if there is no match.
	     *   A lower `score` represents a stronger match.
	     *
	     * #### Complexity
	     * Linear on `sourceText`.
	     *
	     * #### Notes
	     * This scoring algorithm uses a sum-of-deltas approach to determine
	     * the score. In order for there to be a match, all of the characters
	     * in `query` **must** appear in `source` in order. The delta between
	     * the indices are summed to create the score. This means that groups
	     * of matched characters are preferred, while fragmented matches are
	     * penalized.
	     */
	    function matchSumOfDeltas(source, query, start) {
	        if (start === void 0) { start = 0; }
	        var indices = findIndices(source, query, start);
	        if (!indices) {
	            return null;
	        }
	        var score = 0;
	        var last = start - 1;
	        for (var i = 0, n = indices.length; i < n; ++i) {
	            var j = indices[i];
	            score += j - last - 1;
	            last = j;
	        }
	        return { score: score, indices: indices };
	    }
	    StringExt.matchSumOfDeltas = matchSumOfDeltas;
	    /**
	     * Highlight the matched characters of a source text.
	     *
	     * @param source - The text which should be highlighted.
	     *
	     * @param indices - The indices of the matched characters. They must
	     *   appear in increasing order and must be in bounds of the source.
	     *
	     * @param fn - The function to apply to the matched chunks.
	     *
	     * @returns An array of unmatched and highlighted chunks.
	     */
	    function highlight(source, indices, fn) {
	        // Set up the result array.
	        var result = [];
	        // Set up the counter variables.
	        var k = 0;
	        var last = 0;
	        var n = indices.length;
	        // Iterator over each index.
	        while (k < n) {
	            // Set up the chunk indices.
	            var i = indices[k];
	            var j = indices[k];
	            // Advance the right chunk index until it's non-contiguous.
	            while (++k < n && indices[k] === j + 1) {
	                j++;
	            }
	            // Extract the unmatched text.
	            if (last < i) {
	                result.push(source.slice(last, i));
	            }
	            // Extract and highlight the matched text.
	            if (i < j + 1) {
	                result.push(fn(source.slice(i, j + 1)));
	            }
	            // Update the last visited index.
	            last = j + 1;
	        }
	        // Extract any remaining unmatched text.
	        if (last < source.length) {
	            result.push(source.slice(last));
	        }
	        // Return the highlighted result.
	        return result;
	    }
	    StringExt.highlight = highlight;
	})(StringExt = exports.StringExt || (exports.StringExt = {}));
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/string.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/take.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/take.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Take a fixed number of items from an iterable.
	 *
	 * @param object - The iterable or array-like object of interest.
	 *
	 * @param count - The number of items to take from the iterable.
	 *
	 * @returns An iterator which yields the specified number of items
	 *   from the source iterable.
	 *
	 * #### Notes
	 * The returned iterator will exhaust early if the source iterable
	 * contains an insufficient number of items.
	 */
	function take(object, count) {
	    return new TakeIterator(iter_1.iter(object), count);
	}
	exports.take = take;
	/**
	 * An iterator which takes a fixed number of items from a source.
	 */
	var TakeIterator = (function () {
	    /**
	     * Construct a new take iterator.
	     *
	     * @param source - The iterator of interest.
	     *
	     * @param count - The number of items to take from the source.
	     */
	    function TakeIterator(source, count) {
	        this._source = source;
	        this._count = count;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    TakeIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    TakeIterator.prototype.clone = function () {
	        return new TakeIterator(this._source.clone(), this._count);
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    TakeIterator.prototype.next = function () {
	        if (this._count <= 0) {
	            return undefined;
	        }
	        var value = this._source.next();
	        if (value === undefined) {
	            return undefined;
	        }
	        this._count--;
	        return value;
	    };
	    return TakeIterator;
	}());
	exports.TakeIterator = TakeIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/take.js **/


/** START DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/zip.js **/
jupyter.define('@phosphor/algorithm@1.1.1/lib/zip.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var iter_1 = __jupyter_require__('@phosphor/algorithm@1.1.1/lib/iter.js');
	/**
	 * Iterate several iterables in lockstep.
	 *
	 * @param objects - The iterable or array-like objects of interest.
	 *
	 * @returns An iterator which yields successive tuples of values where
	 *   each value is taken in turn from the provided iterables. It will
	 *   be as long as the shortest provided iterable.
	 *
	 * #### Example
	 * ```typescript
	 * import { zip, toArray } from '@phosphor/algorithm';
	 *
	 * let data1 = [1, 2, 3];
	 * let data2 = [4, 5, 6];
	 *
	 * let stream = zip(data1, data2);
	 *
	 * toArray(stream);  // [[1, 4], [2, 5], [3, 6]]
	 * ```
	 */
	function zip() {
	    var objects = [];
	    for (var _i = 0; _i < arguments.length; _i++) {
	        objects[_i] = arguments[_i];
	    }
	    return new ZipIterator(objects.map(iter_1.iter));
	}
	exports.zip = zip;
	/**
	 * An iterator which iterates several sources in lockstep.
	 */
	var ZipIterator = (function () {
	    /**
	     * Construct a new zip iterator.
	     *
	     * @param source - The iterators of interest.
	     */
	    function ZipIterator(source) {
	        this._source = source;
	    }
	    /**
	     * Get an iterator over the object's values.
	     *
	     * @returns An iterator which yields the object's values.
	     */
	    ZipIterator.prototype.iter = function () {
	        return this;
	    };
	    /**
	     * Create an independent clone of the iterator.
	     *
	     * @returns A new independent clone of the iterator.
	     */
	    ZipIterator.prototype.clone = function () {
	        return new ZipIterator(this._source.map(function (it) { return it.clone(); }));
	    };
	    /**
	     * Get the next value from the iterator.
	     *
	     * @returns The next value from the iterator, or `undefined`.
	     */
	    ZipIterator.prototype.next = function () {
	        var result = new Array(this._source.length);
	        for (var i = 0, n = this._source.length; i < n; ++i) {
	            var value = this._source[i].next();
	            if (value === undefined) {
	                return undefined;
	            }
	            result[i] = value;
	        }
	        return result;
	    };
	    return ZipIterator;
	}());
	exports.ZipIterator = ZipIterator;
	
})
/** END DEFINE BLOCK for @phosphor/algorithm@1.1.1/lib/zip.js **/


/** START DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/index.js **/
jupyter.define('@phosphor/domutils@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__jupyter_require__('@phosphor/domutils@1.1.1/lib/element.js'));
	__export(__jupyter_require__('@phosphor/domutils@1.1.1/lib/platform.js'));
	__export(__jupyter_require__('@phosphor/domutils@1.1.1/lib/selector.js'));
	
})
/** END DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/element.js **/
jupyter.define('@phosphor/domutils@1.1.1/lib/element.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for element related utilities.
	 */
	var ElementExt;
	(function (ElementExt) {
	    /**
	     * Compute the box sizing for an element.
	     *
	     * @param element - The element of interest.
	     *
	     * @returns The box sizing data for the specified element.
	     */
	    function boxSizing(element) {
	        var style = window.getComputedStyle(element);
	        var bt = parseFloat(style.borderTopWidth) || 0;
	        var bl = parseFloat(style.borderLeftWidth) || 0;
	        var br = parseFloat(style.borderRightWidth) || 0;
	        var bb = parseFloat(style.borderBottomWidth) || 0;
	        var pt = parseFloat(style.paddingTop) || 0;
	        var pl = parseFloat(style.paddingLeft) || 0;
	        var pr = parseFloat(style.paddingRight) || 0;
	        var pb = parseFloat(style.paddingBottom) || 0;
	        var hs = bl + pl + pr + br;
	        var vs = bt + pt + pb + bb;
	        return {
	            borderTop: bt,
	            borderLeft: bl,
	            borderRight: br,
	            borderBottom: bb,
	            paddingTop: pt,
	            paddingLeft: pl,
	            paddingRight: pr,
	            paddingBottom: pb,
	            horizontalSum: hs,
	            verticalSum: vs
	        };
	    }
	    ElementExt.boxSizing = boxSizing;
	    /**
	     * Compute the size limits for an element.
	     *
	     * @param element - The element of interest.
	     *
	     * @returns The size limit data for the specified element.
	     */
	    function sizeLimits(element) {
	        var style = window.getComputedStyle(element);
	        var minWidth = parseFloat(style.minWidth) || 0;
	        var minHeight = parseFloat(style.minHeight) || 0;
	        var maxWidth = parseFloat(style.maxWidth) || Infinity;
	        var maxHeight = parseFloat(style.maxHeight) || Infinity;
	        maxWidth = Math.max(minWidth, maxWidth);
	        maxHeight = Math.max(minHeight, maxHeight);
	        return { minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight };
	    }
	    ElementExt.sizeLimits = sizeLimits;
	    /**
	     * Test whether a client position lies within an element.
	     *
	     * @param element - The DOM element of interest.
	     *
	     * @param clientX - The client X coordinate of interest.
	     *
	     * @param clientY - The client Y coordinate of interest.
	     *
	     * @returns Whether the point is within the given element.
	     */
	    function hitTest(element, clientX, clientY) {
	        var rect = element.getBoundingClientRect();
	        return (clientX >= rect.left &&
	            clientX < rect.right &&
	            clientY >= rect.top &&
	            clientY < rect.bottom);
	    }
	    ElementExt.hitTest = hitTest;
	    /**
	     * Vertically scroll an element into view if needed.
	     *
	     * @param area - The scroll area element.
	     *
	     * @param element - The element of interest.
	     *
	     * #### Notes
	     * This follows the "nearest" behavior of the native `scrollIntoView`
	     * method, which is not supported by all browsers.
	     * https://drafts.csswg.org/cssom-view/#element-scrolling-members
	     *
	     * If the element fully covers the visible area or is fully contained
	     * within the visible area, no scrolling will take place. Otherwise,
	     * the nearest edges of the area and element are aligned.
	     */
	    function scrollIntoViewIfNeeded(area, element) {
	        var ar = area.getBoundingClientRect();
	        var er = element.getBoundingClientRect();
	        if (er.top <= ar.top && er.bottom >= ar.bottom) {
	            return;
	        }
	        if (er.top < ar.top && er.height <= ar.height) {
	            area.scrollTop -= ar.top - er.top;
	            return;
	        }
	        if (er.bottom > ar.bottom && er.height >= ar.height) {
	            area.scrollTop -= ar.top - er.top;
	            return;
	        }
	        if (er.top < ar.top && er.height > ar.height) {
	            area.scrollTop -= ar.bottom - er.bottom;
	            return;
	        }
	        if (er.bottom > ar.bottom && er.height < ar.height) {
	            area.scrollTop -= ar.bottom - er.bottom;
	            return;
	        }
	    }
	    ElementExt.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
	})(ElementExt = exports.ElementExt || (exports.ElementExt = {}));
	
})
/** END DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/element.js **/


/** START DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/platform.js **/
jupyter.define('@phosphor/domutils@1.1.1/lib/platform.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for platform related utilities.
	 */
	var Platform;
	(function (Platform) {
	    /**
	     * A flag indicating whether the platform is Mac.
	     */
	    Platform.IS_MAC = !!navigator.platform.match(/Mac/i);
	    /**
	     * A flag indicating whether the platform is Windows.
	     */
	    Platform.IS_WIN = !!navigator.platform.match(/Win/i);
	    /**
	     * A flag indicating whether the browser is IE.
	     */
	    Platform.IS_IE = /Trident/.test(navigator.userAgent);
	    /**
	     * A flag indicating whether the browser is Edge.
	     */
	    Platform.IS_EDGE = /Edge/.test(navigator.userAgent);
	})(Platform = exports.Platform || (exports.Platform = {}));
	
})
/** END DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/platform.js **/


/** START DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/selector.js **/
jupyter.define('@phosphor/domutils@1.1.1/lib/selector.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for selector related utilities.
	 */
	var Selector;
	(function (Selector) {
	    /**
	     * Calculate the specificity of a single CSS selector.
	     *
	     * @param selector - The CSS selector of interest.
	     *
	     * @returns The specificity of the selector.
	     *
	     * #### Undefined Behavior
	     * The selector is invalid.
	     *
	     * #### Notes
	     * This is based on https://www.w3.org/TR/css3-selectors/#specificity
	     *
	     * A larger number represents a more specific selector.
	     *
	     * The smallest possible specificity is `0`.
	     *
	     * The result is represented as a hex number `0x<aa><bb><cc>` where
	     * each component is the count of the respective selector clause.
	     *
	     * If the selector contains commas, only the first clause is used.
	     *
	     * The computed result is cached, so subsequent calculations for the
	     * same selector are extremely fast.
	     */
	    function calculateSpecificity(selector) {
	        if (selector in Private.specificityCache) {
	            return Private.specificityCache[selector];
	        }
	        var result = Private.calculateSingle(selector);
	        return Private.specificityCache[selector] = result;
	    }
	    Selector.calculateSpecificity = calculateSpecificity;
	    /**
	     * Test whether a selector is a valid CSS selector.
	     *
	     * @param selector - The CSS selector of interest.
	     *
	     * @returns `true` if the selector is valid, `false` otherwise.
	     *
	     * #### Notes
	     * The computed result is cached, so subsequent tests for the same
	     * selector are extremely fast.
	     */
	    function isValid(selector) {
	        if (selector in Private.validityCache) {
	            return Private.validityCache[selector];
	        }
	        var result = true;
	        try {
	            Private.testElem.querySelector(selector);
	        }
	        catch (err) {
	            result = false;
	        }
	        return Private.validityCache[selector] = result;
	    }
	    Selector.isValid = isValid;
	    /**
	     * Test whether an element matches a CSS selector.
	     *
	     * @param element - The element of interest.
	     *
	     * @param selector - The valid CSS selector of interest.
	     *
	     * @returns `true` if the element is a match, `false` otherwise.
	     *
	     * #### Notes
	     * This function uses the builtin browser capabilities when possible,
	     * falling back onto a document query otherwise.
	     */
	    function matches(element, selector) {
	        return Private.protoMatchFunc.call(element, selector);
	    }
	    Selector.matches = matches;
	})(Selector = exports.Selector || (exports.Selector = {}));
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A cache of computed selector specificity values.
	     */
	    Private.specificityCache = Object.create(null);
	    /**
	     * A cache of computed selector validity.
	     */
	    Private.validityCache = Object.create(null);
	    /**
	     * An empty element for testing selector validity.
	     */
	    Private.testElem = document.createElement('div');
	    /**
	     * A cross-browser CSS selector matching prototype function.
	     */
	    Private.protoMatchFunc = (function () {
	        var proto = Element.prototype;
	        return (proto.matches ||
	            proto.matchesSelector ||
	            proto.mozMatchesSelector ||
	            proto.msMatchesSelector ||
	            proto.oMatchesSelector ||
	            proto.webkitMatchesSelector ||
	            (function (selector) {
	                var elem = this;
	                var matches = elem.ownerDocument.querySelectorAll(selector);
	                return Array.prototype.indexOf.call(matches, elem) !== -1;
	            }));
	    })();
	    /**
	     * Calculate the specificity of a single selector.
	     *
	     * The behavior is undefined if the selector is invalid.
	     */
	    function calculateSingle(selector) {
	        // Ignore anything after the first comma.
	        selector = selector.split(',', 1)[0];
	        // Setup the aggregate counters.
	        var a = 0;
	        var b = 0;
	        var c = 0;
	        // Apply a regex to the front of the selector. If it succeeds, that
	        // portion of the selector is removed. Returns a success/fail flag.
	        function match(re) {
	            var match = selector.match(re);
	            if (match === null) {
	                return false;
	            }
	            selector = selector.slice(match[0].length);
	            return true;
	        }
	        // Replace the negation pseudo-class (which is ignored),
	        // but keep its inner content (which is not ignored).
	        selector = selector.replace(NEGATION_RE, ' $1 ');
	        // Continue matching until the selector is consumed.
	        while (selector.length > 0) {
	            // Match an ID selector.
	            if (match(ID_RE)) {
	                a++;
	                continue;
	            }
	            // Match a class selector.
	            if (match(CLASS_RE)) {
	                b++;
	                continue;
	            }
	            // Match an attribute selector.
	            if (match(ATTR_RE)) {
	                b++;
	                continue;
	            }
	            // Match a pseudo-element selector. This is done before matching
	            // a pseudo-class since this regex overlaps with that regex.
	            if (match(PSEUDO_ELEM_RE)) {
	                c++;
	                continue;
	            }
	            // Match a pseudo-class selector.
	            if (match(PSEDUO_CLASS_RE)) {
	                b++;
	                continue;
	            }
	            // Match a plain type selector.
	            if (match(TYPE_RE)) {
	                c++;
	                continue;
	            }
	            // Finally, match any ignored characters.
	            if (match(IGNORE_RE)) {
	                continue;
	            }
	            // At this point, the selector is assumed to be invalid.
	            return 0;
	        }
	        // Clamp each component to a reasonable base.
	        a = Math.min(a, 0xFF);
	        b = Math.min(b, 0xFF);
	        c = Math.min(c, 0xFF);
	        // Combine the components into a single result.
	        return (a << 16) | (b << 8) | c;
	    }
	    Private.calculateSingle = calculateSingle;
	    /**
	     * A regex which matches an ID selector at string start.
	     */
	    var ID_RE = /^#[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches a class selector at string start.
	     */
	    var CLASS_RE = /^\.[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches an attribute selector at string start.
	     */
	    var ATTR_RE = /^\[[^\]]+\]/;
	    /**
	     * A regex which matches a type selector at string start.
	     */
	    var TYPE_RE = /^[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches a pseudo-element selector at string start.
	     */
	    var PSEUDO_ELEM_RE = /^(::[^\s\+>~#\.\[:]+|:first-line|:first-letter|:before|:after)/;
	    /**
	     * A regex which matches a pseudo-class selector at string start.
	     */
	    var PSEDUO_CLASS_RE = /^:[^\s\+>~#\.\[:]+/;
	    /**
	     * A regex which matches ignored characters at string start.
	     */
	    var IGNORE_RE = /^[\s\+>~\*]+/;
	    /**
	     * A regex which matches the negation pseudo-class globally.
	     */
	    var NEGATION_RE = /:not\(([^\)]+)\)/g;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/domutils@1.1.1/lib/selector.js **/


/** START DEFINE BLOCK for @phosphor/messaging@1.2.1/lib/index.js **/
jupyter.define('@phosphor/messaging@1.2.1/lib/index.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(setImmediate, clearImmediate) {"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var collections_1 = __jupyter_require__('@phosphor/collections@^1.1.1/lib/index.js');
	/**
	 * A message which can be delivered to a message handler.
	 *
	 * #### Notes
	 * This class may be subclassed to create complex message types.
	 */
	var Message = (function () {
	    /**
	     * Construct a new message.
	     *
	     * @param type - The type of the message.
	     */
	    function Message(type) {
	        this.type = type;
	    }
	    Object.defineProperty(Message.prototype, "isConflatable", {
	        /**
	         * Test whether the message is conflatable.
	         *
	         * #### Notes
	         * Message conflation is an advanced topic. Most message types will
	         * not make use of this feature.
	         *
	         * If a conflatable message is posted to a handler while another
	         * conflatable message of the same `type` has already been posted
	         * to the handler, the `conflate()` method of the existing message
	         * will be invoked. If that method returns `true`, the new message
	         * will not be enqueued. This allows messages to be compressed, so
	         * that only a single instance of the message type is processed per
	         * cycle, no matter how many times messages of that type are posted.
	         *
	         * Custom message types may reimplement this property.
	         *
	         * The default implementation is always `false`.
	         */
	        get: function () {
	            return false;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Conflate this message with another message of the same `type`.
	     *
	     * @param other - A conflatable message of the same `type`.
	     *
	     * @returns `true` if the message was successfully conflated, or
	     *   `false` otherwise.
	     *
	     * #### Notes
	     * Message conflation is an advanced topic. Most message types will
	     * not make use of this feature.
	     *
	     * This method is called automatically by the message loop when the
	     * given message is posted to the handler paired with this message.
	     * This message will already be enqueued and conflatable, and the
	     * given message will have the same `type` and also be conflatable.
	     *
	     * This method should merge the state of the other message into this
	     * message as needed so that when this message is finally delivered
	     * to the handler, it receives the most up-to-date information.
	     *
	     * If this method returns `true`, it signals that the other message
	     * was successfully conflated and that message will not be enqueued.
	     *
	     * If this method returns `false`, the other message will be enqueued
	     * for normal delivery.
	     *
	     * Custom message types may reimplement this method.
	     *
	     * The default implementation always returns `false`.
	     */
	    Message.prototype.conflate = function (other) {
	        return false;
	    };
	    return Message;
	}());
	exports.Message = Message;
	/**
	 * A convenience message class which conflates automatically.
	 *
	 * #### Notes
	 * Message conflation is an advanced topic. Most user code will not
	 * make use of this class.
	 *
	 * This message class is useful for creating message instances which
	 * should be conflated, but which have no state other than `type`.
	 *
	 * If conflation of stateful messages is required, a custom `Message`
	 * subclass should be created.
	 */
	var ConflatableMessage = (function (_super) {
	    __extends(ConflatableMessage, _super);
	    function ConflatableMessage() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    Object.defineProperty(ConflatableMessage.prototype, "isConflatable", {
	        /**
	         * Test whether the message is conflatable.
	         *
	         * #### Notes
	         * This property is always `true`.
	         */
	        get: function () {
	            return true;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Conflate this message with another message of the same `type`.
	     *
	     * #### Notes
	     * This method always returns `true`.
	     */
	    ConflatableMessage.prototype.conflate = function (other) {
	        return true;
	    };
	    return ConflatableMessage;
	}(Message));
	exports.ConflatableMessage = ConflatableMessage;
	/**
	 * The namespace for the global singleton message loop.
	 */
	var MessageLoop;
	(function (MessageLoop) {
	    /**
	     * Send a message to a message handler to process immediately.
	     *
	     * @param handler - The handler which should process the message.
	     *
	     * @param msg - The message to deliver to the handler.
	     *
	     * #### Notes
	     * The message will first be sent through any installed message hooks
	     * for the handler. If the message passes all hooks, it will then be
	     * delivered to the `processMessage` method of the handler.
	     *
	     * The message will not be conflated with pending posted messages.
	     *
	     * Exceptions in hooks and handlers will be caught and logged.
	     */
	    function sendMessage(handler, msg) {
	        // Lookup the message hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Handle the common case of no installed hooks.
	        if (!hooks || hooks.length === 0) {
	            invokeHandler(handler, msg);
	            return;
	        }
	        // Invoke the message hooks starting with the newest first.
	        var passed = algorithm_1.every(algorithm_1.retro(hooks), function (hook) {
	            return hook ? invokeHook(hook, handler, msg) : true;
	        });
	        // Invoke the handler if the message passes all hooks.
	        if (passed) {
	            invokeHandler(handler, msg);
	        }
	    }
	    MessageLoop.sendMessage = sendMessage;
	    /**
	     * Post a message to a message handler to process in the future.
	     *
	     * @param handler - The handler which should process the message.
	     *
	     * @param msg - The message to post to the handler.
	     *
	     * #### Notes
	     * The message will be conflated with the pending posted messages for
	     * the handler, if possible. If the message is not conflated, it will
	     * be queued for normal delivery on the next cycle of the event loop.
	     *
	     * Exceptions in hooks and handlers will be caught and logged.
	     */
	    function postMessage(handler, msg) {
	        // Handle the common case of a non-conflatable message.
	        if (!msg.isConflatable) {
	            enqueueMessage(handler, msg);
	            return;
	        }
	        // Conflate the message with an existing message if possible.
	        var conflated = algorithm_1.some(messageQueue, function (posted) {
	            if (posted.handler !== handler) {
	                return false;
	            }
	            if (!posted.msg) {
	                return false;
	            }
	            if (posted.msg.type !== msg.type) {
	                return false;
	            }
	            if (!posted.msg.isConflatable) {
	                return false;
	            }
	            return posted.msg.conflate(msg);
	        });
	        // Enqueue the message if it was not conflated.
	        if (!conflated) {
	            enqueueMessage(handler, msg);
	        }
	    }
	    MessageLoop.postMessage = postMessage;
	    /**
	     * Install a message hook for a message handler.
	     *
	     * @param handler - The message handler of interest.
	     *
	     * @param hook - The message hook to install.
	     *
	     * #### Notes
	     * A message hook is invoked before a message is delivered to the
	     * handler. If the hook returns `false`, no other hooks will be
	     * invoked and the message will not be delivered to the handler.
	     *
	     * The most recently installed message hook is executed first.
	     *
	     * If the hook is already installed, this is a no-op.
	     */
	    function installMessageHook(handler, hook) {
	        // Lookup the hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Bail early if the hook is already installed.
	        if (hooks && hooks.indexOf(hook) !== -1) {
	            return;
	        }
	        // Add the hook to the end, so it will be the first to execute.
	        if (!hooks) {
	            messageHooks.set(handler, [hook]);
	        }
	        else {
	            hooks.push(hook);
	        }
	    }
	    MessageLoop.installMessageHook = installMessageHook;
	    /**
	     * Remove an installed message hook for a message handler.
	     *
	     * @param handler - The message handler of interest.
	     *
	     * @param hook - The message hook to remove.
	     *
	     * #### Notes
	     * It is safe to call this function while the hook is executing.
	     *
	     * If the hook is not installed, this is a no-op.
	     */
	    function removeMessageHook(handler, hook) {
	        // Lookup the hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Bail early if the hooks do not exist.
	        if (!hooks) {
	            return;
	        }
	        // Lookup the index of the hook and bail if not found.
	        var i = hooks.indexOf(hook);
	        if (i === -1) {
	            return;
	        }
	        // Clear the hook and schedule a cleanup of the array.
	        hooks[i] = null;
	        scheduleCleanup(hooks);
	    }
	    MessageLoop.removeMessageHook = removeMessageHook;
	    /**
	     * Clear all message data associated with a message handler.
	     *
	     * @param handler - The message handler of interest.
	     *
	     * #### Notes
	     * This will clear all posted messages and hooks for the handler.
	     */
	    function clearData(handler) {
	        // Lookup the hooks for the handler.
	        var hooks = messageHooks.get(handler);
	        // Clear all messsage hooks for the handler.
	        if (hooks && hooks.length > 0) {
	            algorithm_1.ArrayExt.fill(hooks, null);
	            scheduleCleanup(hooks);
	        }
	        // Clear all posted messages for the handler.
	        algorithm_1.each(messageQueue, function (posted) {
	            if (posted.handler === handler) {
	                posted.handler = null;
	                posted.msg = null;
	            }
	        });
	    }
	    MessageLoop.clearData = clearData;
	    /**
	     * Process the pending posted messages in the queue immediately.
	     *
	     * #### Notes
	     * This function is useful when posted messages must be processed
	     * immediately, instead of on the next animation frame.
	     *
	     * This function should normally not be needed, but it may be
	     * required to work around certain browser idiosyncrasies.
	     *
	     * Recursing into this function is a no-op.
	     */
	    function flush() {
	        // Bail if recursion is detected or if there is no pending task.
	        if (flushGuard || loopTaskID === 0) {
	            return;
	        }
	        // Unschedule the pending loop task.
	        unschedule(loopTaskID);
	        // Run the message loop within the recursion guard.
	        flushGuard = true;
	        runMessageLoop();
	        flushGuard = false;
	    }
	    MessageLoop.flush = flush;
	    /**
	     * Get the message loop exception handler.
	     *
	     * @returns The current exception handler.
	     *
	     * #### Notes
	     * The default exception handler is `console.error`.
	     */
	    function getExceptionHandler() {
	        return exceptionHandler;
	    }
	    MessageLoop.getExceptionHandler = getExceptionHandler;
	    /**
	     * Set the message loop exception handler.
	     *
	     * @param handler - The function to use as the exception handler.
	     *
	     * @returns The old exception handler.
	     *
	     * #### Notes
	     * The exception handler is invoked when a message handler or a
	     * message hook throws an exception.
	     */
	    function setExceptionHandler(handler) {
	        var old = exceptionHandler;
	        exceptionHandler = handler;
	        return old;
	    }
	    MessageLoop.setExceptionHandler = setExceptionHandler;
	    /**
	     * The queue of posted message pairs.
	     */
	    var messageQueue = new collections_1.LinkedList();
	    /**
	     * A mapping of handler to array of installed message hooks.
	     */
	    var messageHooks = new WeakMap();
	    /**
	     * A set of message hook arrays which are pending cleanup.
	     */
	    var dirtySet = new Set();
	    /**
	     * The message loop exception handler.
	     */
	    var exceptionHandler = function (err) {
	        console.error(err);
	    };
	    /**
	     * The id of the pending loop task animation frame.
	     */
	    var loopTaskID = 0;
	    /**
	     * A guard flag to prevent flush recursion.
	     */
	    var flushGuard = false;
	    /**
	     * A function to schedule an event loop callback.
	     */
	    var schedule = (function () {
	        var ok = typeof requestAnimationFrame === 'function';
	        return ok ? requestAnimationFrame : setImmediate;
	    })();
	    /**
	     * A function to unschedule an event loop callback.
	     */
	    var unschedule = (function () {
	        var ok = typeof cancelAnimationFrame === 'function';
	        return ok ? cancelAnimationFrame : clearImmediate;
	    })();
	    /**
	     * Invoke a message hook with the specified handler and message.
	     *
	     * Returns the result of the hook, or `true` if the hook throws.
	     *
	     * Exceptions in the hook will be caught and logged.
	     */
	    function invokeHook(hook, handler, msg) {
	        var result = true;
	        try {
	            if (typeof hook === 'function') {
	                result = hook(handler, msg);
	            }
	            else {
	                result = hook.messageHook(handler, msg);
	            }
	        }
	        catch (err) {
	            exceptionHandler(err);
	        }
	        return result;
	    }
	    /**
	     * Invoke a message handler with the specified message.
	     *
	     * Exceptions in the handler will be caught and logged.
	     */
	    function invokeHandler(handler, msg) {
	        try {
	            handler.processMessage(msg);
	        }
	        catch (err) {
	            exceptionHandler(err);
	        }
	    }
	    /**
	     * Add a message to the end of the message queue.
	     *
	     * This will automatically schedule a run of the message loop.
	     */
	    function enqueueMessage(handler, msg) {
	        // Add the posted message to the queue.
	        messageQueue.addLast({ handler: handler, msg: msg });
	        // Bail if a loop task is already pending.
	        if (loopTaskID !== 0) {
	            return;
	        }
	        // Schedule a run of the message loop.
	        loopTaskID = schedule(runMessageLoop);
	    }
	    /**
	     * Run an iteration of the message loop.
	     *
	     * This will process all pending messages in the queue. If a message
	     * is added to the queue while the message loop is running, it will
	     * be processed on the next cycle of the loop.
	     */
	    function runMessageLoop() {
	        // Clear the task ID so the next loop can be scheduled.
	        loopTaskID = 0;
	        // If the message queue is empty, there is nothing else to do.
	        if (messageQueue.isEmpty) {
	            return;
	        }
	        // Add a sentinel value to the end of the queue. The queue will
	        // only be processed up to the sentinel. Messages posted during
	        // this cycle will execute on the next cycle.
	        var sentinel = { handler: null, msg: null };
	        messageQueue.addLast(sentinel);
	        // Enter the message loop.
	        while (true) {
	            // Remove the first posted message in the queue.
	            var posted = messageQueue.removeFirst();
	            // If the value is the sentinel, exit the loop.
	            if (posted === sentinel) {
	                return;
	            }
	            // Dispatch the message if it has not been cleared.
	            if (posted.handler && posted.msg) {
	                sendMessage(posted.handler, posted.msg);
	            }
	        }
	    }
	    /**
	     * Schedule a cleanup of a message hooks array.
	     *
	     * This will add the array to the dirty set and schedule a deferred
	     * cleanup of the array contents. On cleanup, any `null` hook will
	     * be removed from the array.
	     */
	    function scheduleCleanup(hooks) {
	        if (dirtySet.size === 0) {
	            schedule(cleanupDirtySet);
	        }
	        dirtySet.add(hooks);
	    }
	    /**
	     * Cleanup the message hook arrays in the dirty set.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupDirtySet() {
	        dirtySet.forEach(cleanupHooks);
	        dirtySet.clear();
	    }
	    /**
	     * Cleanup the dirty hooks in a message hooks array.
	     *
	     * This will remove any `null` hook from the array.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupHooks(hooks) {
	        algorithm_1.ArrayExt.removeAllWhere(hooks, isNull);
	    }
	    /**
	     * Test whether a value is `null`.
	     */
	    function isNull(value) {
	        return value === null;
	    }
	})(MessageLoop = exports.MessageLoop || (exports.MessageLoop = {}));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('timers-browserify@2.0.2/main.js').setImmediate, __jupyter_require__('timers-browserify@2.0.2/main.js').clearImmediate))
})
/** END DEFINE BLOCK for @phosphor/messaging@1.2.1/lib/index.js **/


/** START DEFINE BLOCK for timers-browserify@2.0.2/main.js **/
jupyter.define('timers-browserify@2.0.2/main.js', function (module, exports, __jupyter_require__) {
	var apply = Function.prototype.apply;
	
	// DOM APIs, for completeness
	
	exports.setTimeout = function() {
	  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
	};
	exports.setInterval = function() {
	  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
	};
	exports.clearTimeout =
	exports.clearInterval = function(timeout) {
	  if (timeout) {
	    timeout.close();
	  }
	};
	
	function Timeout(id, clearFn) {
	  this._id = id;
	  this._clearFn = clearFn;
	}
	Timeout.prototype.unref = Timeout.prototype.ref = function() {};
	Timeout.prototype.close = function() {
	  this._clearFn.call(window, this._id);
	};
	
	// Does not start the time, just sets up the members needed.
	exports.enroll = function(item, msecs) {
	  clearTimeout(item._idleTimeoutId);
	  item._idleTimeout = msecs;
	};
	
	exports.unenroll = function(item) {
	  clearTimeout(item._idleTimeoutId);
	  item._idleTimeout = -1;
	};
	
	exports._unrefActive = exports.active = function(item) {
	  clearTimeout(item._idleTimeoutId);
	
	  var msecs = item._idleTimeout;
	  if (msecs >= 0) {
	    item._idleTimeoutId = setTimeout(function onTimeout() {
	      if (item._onTimeout)
	        item._onTimeout();
	    }, msecs);
	  }
	};
	
	// setimmediate attaches itself to the global object
	__jupyter_require__('setimmediate@^1.0.4/setImmediate.js');
	exports.setImmediate = setImmediate;
	exports.clearImmediate = clearImmediate;
	
})
/** END DEFINE BLOCK for timers-browserify@2.0.2/main.js **/


/** START DEFINE BLOCK for setimmediate@1.0.5/setImmediate.js **/
jupyter.define('setimmediate@1.0.5/setImmediate.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
	    "use strict";
	
	    if (global.setImmediate) {
	        return;
	    }
	
	    var nextHandle = 1; // Spec says greater than zero
	    var tasksByHandle = {};
	    var currentlyRunningATask = false;
	    var doc = global.document;
	    var registerImmediate;
	
	    function setImmediate(callback) {
	      // Callback can either be a function or a string
	      if (typeof callback !== "function") {
	        callback = new Function("" + callback);
	      }
	      // Copy function arguments
	      var args = new Array(arguments.length - 1);
	      for (var i = 0; i < args.length; i++) {
	          args[i] = arguments[i + 1];
	      }
	      // Store and register the task
	      var task = { callback: callback, args: args };
	      tasksByHandle[nextHandle] = task;
	      registerImmediate(nextHandle);
	      return nextHandle++;
	    }
	
	    function clearImmediate(handle) {
	        delete tasksByHandle[handle];
	    }
	
	    function run(task) {
	        var callback = task.callback;
	        var args = task.args;
	        switch (args.length) {
	        case 0:
	            callback();
	            break;
	        case 1:
	            callback(args[0]);
	            break;
	        case 2:
	            callback(args[0], args[1]);
	            break;
	        case 3:
	            callback(args[0], args[1], args[2]);
	            break;
	        default:
	            callback.apply(undefined, args);
	            break;
	        }
	    }
	
	    function runIfPresent(handle) {
	        // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
	        // So if we're currently running a task, we'll need to delay this invocation.
	        if (currentlyRunningATask) {
	            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
	            // "too much recursion" error.
	            setTimeout(runIfPresent, 0, handle);
	        } else {
	            var task = tasksByHandle[handle];
	            if (task) {
	                currentlyRunningATask = true;
	                try {
	                    run(task);
	                } finally {
	                    clearImmediate(handle);
	                    currentlyRunningATask = false;
	                }
	            }
	        }
	    }
	
	    function installNextTickImplementation() {
	        registerImmediate = function(handle) {
	            process.nextTick(function () { runIfPresent(handle); });
	        };
	    }
	
	    function canUsePostMessage() {
	        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
	        // where `global.postMessage` means something completely different and can't be used for this purpose.
	        if (global.postMessage && !global.importScripts) {
	            var postMessageIsAsynchronous = true;
	            var oldOnMessage = global.onmessage;
	            global.onmessage = function() {
	                postMessageIsAsynchronous = false;
	            };
	            global.postMessage("", "*");
	            global.onmessage = oldOnMessage;
	            return postMessageIsAsynchronous;
	        }
	    }
	
	    function installPostMessageImplementation() {
	        // Installs an event handler on `global` for the `message` event: see
	        // * https://developer.mozilla.org/en/DOM/window.postMessage
	        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
	
	        var messagePrefix = "setImmediate$" + Math.random() + "$";
	        var onGlobalMessage = function(event) {
	            if (event.source === global &&
	                typeof event.data === "string" &&
	                event.data.indexOf(messagePrefix) === 0) {
	                runIfPresent(+event.data.slice(messagePrefix.length));
	            }
	        };
	
	        if (global.addEventListener) {
	            global.addEventListener("message", onGlobalMessage, false);
	        } else {
	            global.attachEvent("onmessage", onGlobalMessage);
	        }
	
	        registerImmediate = function(handle) {
	            global.postMessage(messagePrefix + handle, "*");
	        };
	    }
	
	    function installMessageChannelImplementation() {
	        var channel = new MessageChannel();
	        channel.port1.onmessage = function(event) {
	            var handle = event.data;
	            runIfPresent(handle);
	        };
	
	        registerImmediate = function(handle) {
	            channel.port2.postMessage(handle);
	        };
	    }
	
	    function installReadyStateChangeImplementation() {
	        var html = doc.documentElement;
	        registerImmediate = function(handle) {
	            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
	            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
	            var script = doc.createElement("script");
	            script.onreadystatechange = function () {
	                runIfPresent(handle);
	                script.onreadystatechange = null;
	                html.removeChild(script);
	                script = null;
	            };
	            html.appendChild(script);
	        };
	    }
	
	    function installSetTimeoutImplementation() {
	        registerImmediate = function(handle) {
	            setTimeout(runIfPresent, 0, handle);
	        };
	    }
	
	    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
	    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
	    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
	
	    // Don't get fooled by e.g. browserify environments.
	    if ({}.toString.call(global.process) === "[object process]") {
	        // For Node.js before 0.9
	        installNextTickImplementation();
	
	    } else if (canUsePostMessage()) {
	        // For non-IE10 modern browsers
	        installPostMessageImplementation();
	
	    } else if (global.MessageChannel) {
	        // For web workers, where supported
	        installMessageChannelImplementation();
	
	    } else if (doc && "onreadystatechange" in doc.createElement("script")) {
	        // For IE 6–8
	        installReadyStateChangeImplementation();
	
	    } else {
	        // For older browsers
	        installSetTimeoutImplementation();
	    }
	
	    attachTo.setImmediate = setImmediate;
	    attachTo.clearImmediate = clearImmediate;
	}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __jupyter_require__('process@0.11.10/browser.js')))
})
/** END DEFINE BLOCK for setimmediate@1.0.5/setImmediate.js **/


/** START DEFINE BLOCK for process@0.11.10/browser.js **/
jupyter.define('process@0.11.10/browser.js', function (module, exports, __jupyter_require__) {
	// shim for using process in browser
	var process = module.exports = {};
	
	// cached from whatever global is present so that test runners that stub it
	// don't break things.  But we need to wrap it in a try catch in case it is
	// wrapped in strict mode code which doesn't define any globals.  It's inside a
	// function because try/catches deoptimize in certain engines.
	
	var cachedSetTimeout;
	var cachedClearTimeout;
	
	function defaultSetTimout() {
	    throw new Error('setTimeout has not been defined');
	}
	function defaultClearTimeout () {
	    throw new Error('clearTimeout has not been defined');
	}
	(function () {
	    try {
	        if (typeof setTimeout === 'function') {
	            cachedSetTimeout = setTimeout;
	        } else {
	            cachedSetTimeout = defaultSetTimout;
	        }
	    } catch (e) {
	        cachedSetTimeout = defaultSetTimout;
	    }
	    try {
	        if (typeof clearTimeout === 'function') {
	            cachedClearTimeout = clearTimeout;
	        } else {
	            cachedClearTimeout = defaultClearTimeout;
	        }
	    } catch (e) {
	        cachedClearTimeout = defaultClearTimeout;
	    }
	} ())
	function runTimeout(fun) {
	    if (cachedSetTimeout === setTimeout) {
	        //normal enviroments in sane situations
	        return setTimeout(fun, 0);
	    }
	    // if setTimeout wasn't available but was latter defined
	    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
	        cachedSetTimeout = setTimeout;
	        return setTimeout(fun, 0);
	    }
	    try {
	        // when when somebody has screwed with setTimeout but no I.E. maddness
	        return cachedSetTimeout(fun, 0);
	    } catch(e){
	        try {
	            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
	            return cachedSetTimeout.call(null, fun, 0);
	        } catch(e){
	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
	            return cachedSetTimeout.call(this, fun, 0);
	        }
	    }
	
	
	}
	function runClearTimeout(marker) {
	    if (cachedClearTimeout === clearTimeout) {
	        //normal enviroments in sane situations
	        return clearTimeout(marker);
	    }
	    // if clearTimeout wasn't available but was latter defined
	    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
	        cachedClearTimeout = clearTimeout;
	        return clearTimeout(marker);
	    }
	    try {
	        // when when somebody has screwed with setTimeout but no I.E. maddness
	        return cachedClearTimeout(marker);
	    } catch (e){
	        try {
	            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
	            return cachedClearTimeout.call(null, marker);
	        } catch (e){
	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
	            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
	            return cachedClearTimeout.call(this, marker);
	        }
	    }
	
	
	
	}
	var queue = [];
	var draining = false;
	var currentQueue;
	var queueIndex = -1;
	
	function cleanUpNextTick() {
	    if (!draining || !currentQueue) {
	        return;
	    }
	    draining = false;
	    if (currentQueue.length) {
	        queue = currentQueue.concat(queue);
	    } else {
	        queueIndex = -1;
	    }
	    if (queue.length) {
	        drainQueue();
	    }
	}
	
	function drainQueue() {
	    if (draining) {
	        return;
	    }
	    var timeout = runTimeout(cleanUpNextTick);
	    draining = true;
	
	    var len = queue.length;
	    while(len) {
	        currentQueue = queue;
	        queue = [];
	        while (++queueIndex < len) {
	            if (currentQueue) {
	                currentQueue[queueIndex].run();
	            }
	        }
	        queueIndex = -1;
	        len = queue.length;
	    }
	    currentQueue = null;
	    draining = false;
	    runClearTimeout(timeout);
	}
	
	process.nextTick = function (fun) {
	    var args = new Array(arguments.length - 1);
	    if (arguments.length > 1) {
	        for (var i = 1; i < arguments.length; i++) {
	            args[i - 1] = arguments[i];
	        }
	    }
	    queue.push(new Item(fun, args));
	    if (queue.length === 1 && !draining) {
	        runTimeout(drainQueue);
	    }
	};
	
	// v8 likes predictible objects
	function Item(fun, array) {
	    this.fun = fun;
	    this.array = array;
	}
	Item.prototype.run = function () {
	    this.fun.apply(null, this.array);
	};
	process.title = 'browser';
	process.browser = true;
	process.env = {};
	process.argv = [];
	process.version = ''; // empty string to avoid regexp issues
	process.versions = {};
	
	function noop() {}
	
	process.on = noop;
	process.addListener = noop;
	process.once = noop;
	process.off = noop;
	process.removeListener = noop;
	process.removeAllListeners = noop;
	process.emit = noop;
	process.prependListener = noop;
	process.prependOnceListener = noop;
	
	process.listeners = function (name) { return [] }
	
	process.binding = function (name) {
	    throw new Error('process.binding is not supported');
	};
	
	process.cwd = function () { return '/' };
	process.chdir = function (dir) {
	    throw new Error('process.chdir is not supported');
	};
	process.umask = function() { return 0; };
	
})
/** END DEFINE BLOCK for process@0.11.10/browser.js **/


/** START DEFINE BLOCK for @phosphor/collections@1.1.1/lib/index.js **/
jupyter.define('@phosphor/collections@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__jupyter_require__('@phosphor/collections@1.1.1/lib/linkedlist.js'));
	
})
/** END DEFINE BLOCK for @phosphor/collections@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/collections@1.1.1/lib/linkedlist.js **/
jupyter.define('@phosphor/collections@1.1.1/lib/linkedlist.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	/**
	 * A generic doubly-linked list.
	 */
	var LinkedList = (function () {
	    /**
	     * Construct a new linked list.
	     */
	    function LinkedList() {
	        this._first = null;
	        this._last = null;
	        this._length = 0;
	    }
	    Object.defineProperty(LinkedList.prototype, "isEmpty", {
	        /**
	         * Whether the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._length === 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "length", {
	        /**
	         * The length of the list.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._length;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "first", {
	        /**
	         * The first value in the list.
	         *
	         * This is `undefined` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._first ? this._first.value : undefined;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "last", {
	        /**
	         * The last value in the list.
	         *
	         * This is `undefined` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._last ? this._last.value : undefined;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "firstNode", {
	        /**
	         * The first node in the list.
	         *
	         * This is `null` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._first;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LinkedList.prototype, "lastNode", {
	        /**
	         * The last node in the list.
	         *
	         * This is `null` if the list is empty.
	         *
	         * #### Complexity
	         * Constant.
	         */
	        get: function () {
	            return this._last;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the values in the list.
	     *
	     * @returns A new iterator starting with the first value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.iter = function () {
	        return new LinkedList.ForwardValueIterator(this._first);
	    };
	    /**
	     * Create a reverse iterator over the values in the list.
	     *
	     * @returns A new iterator starting with the last value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.retro = function () {
	        return new LinkedList.RetroValueIterator(this._last);
	    };
	    /**
	     * Create an iterator over the nodes in the list.
	     *
	     * @returns A new iterator starting with the first node.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.nodes = function () {
	        return new LinkedList.ForwardNodeIterator(this._first);
	    };
	    /**
	     * Create a reverse iterator over the nodes in the list.
	     *
	     * @returns A new iterator starting with the last node.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.retroNodes = function () {
	        return new LinkedList.RetroNodeIterator(this._last);
	    };
	    /**
	     * Add a value to the beginning of the list.
	     *
	     * @param value - The value to add to the beginning of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.addFirst = function (value) {
	        var node = new Private.LinkedListNode(this, value);
	        if (!this._first) {
	            this._first = node;
	            this._last = node;
	        }
	        else {
	            node.next = this._first;
	            this._first.prev = node;
	            this._first = node;
	        }
	        this._length++;
	        return node;
	    };
	    /**
	     * Add a value to the end of the list.
	     *
	     * @param value - The value to add to the end of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.addLast = function (value) {
	        var node = new Private.LinkedListNode(this, value);
	        if (!this._last) {
	            this._first = node;
	            this._last = node;
	        }
	        else {
	            node.prev = this._last;
	            this._last.next = node;
	            this._last = node;
	        }
	        this._length++;
	        return node;
	    };
	    /**
	     * Insert a value before a specific node in the list.
	     *
	     * @param value - The value to insert before the reference node.
	     *
	     * @param ref - The reference node of interest. If this is `null`,
	     *   the value will be added to the beginning of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Notes
	     * The reference node must be owned by the list.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.insertBefore = function (value, ref) {
	        if (!ref || ref === this._first) {
	            return this.addFirst(value);
	        }
	        if (!(ref instanceof Private.LinkedListNode) || ref.list !== this) {
	            throw new Error('Reference node is not owned by the list.');
	        }
	        var node = new Private.LinkedListNode(this, value);
	        var _ref = ref;
	        var prev = _ref.prev;
	        node.next = _ref;
	        node.prev = prev;
	        _ref.prev = node;
	        prev.next = node;
	        this._length++;
	        return node;
	    };
	    /**
	     * Insert a value after a specific node in the list.
	     *
	     * @param value - The value to insert after the reference node.
	     *
	     * @param ref - The reference node of interest. If this is `null`,
	     *   the value will be added to the end of the list.
	     *
	     * @returns The list node which holds the value.
	     *
	     * #### Notes
	     * The reference node must be owned by the list.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.insertAfter = function (value, ref) {
	        if (!ref || ref === this._last) {
	            return this.addLast(value);
	        }
	        if (!(ref instanceof Private.LinkedListNode) || ref.list !== this) {
	            throw new Error('Reference node is not owned by the list.');
	        }
	        var node = new Private.LinkedListNode(this, value);
	        var _ref = ref;
	        var next = _ref.next;
	        node.next = next;
	        node.prev = _ref;
	        _ref.next = node;
	        next.prev = node;
	        this._length++;
	        return node;
	    };
	    /**
	     * Remove and return the value at the beginning of the list.
	     *
	     * @returns The removed value, or `undefined` if the list is empty.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.removeFirst = function () {
	        var node = this._first;
	        if (!node) {
	            return undefined;
	        }
	        if (node === this._last) {
	            this._first = null;
	            this._last = null;
	        }
	        else {
	            this._first = node.next;
	            this._first.prev = null;
	        }
	        node.list = null;
	        node.next = null;
	        node.prev = null;
	        this._length--;
	        return node.value;
	    };
	    /**
	     * Remove and return the value at the end of the list.
	     *
	     * @returns The removed value, or `undefined` if the list is empty.
	     *
	     * #### Complexity
	     * Constant.
	     */
	    LinkedList.prototype.removeLast = function () {
	        var node = this._last;
	        if (!node) {
	            return undefined;
	        }
	        if (node === this._first) {
	            this._first = null;
	            this._last = null;
	        }
	        else {
	            this._last = node.prev;
	            this._last.next = null;
	        }
	        node.list = null;
	        node.next = null;
	        node.prev = null;
	        this._length--;
	        return node.value;
	    };
	    /**
	     * Remove a specific node from the list.
	     *
	     * @param node - The node to remove from the list.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Notes
	     * The node must be owned by the list.
	     */
	    LinkedList.prototype.removeNode = function (node) {
	        if (!(node instanceof Private.LinkedListNode) || node.list !== this) {
	            throw new Error('Node is not owned by the list.');
	        }
	        var _node = node;
	        if (_node === this._first && _node === this._last) {
	            this._first = null;
	            this._last = null;
	        }
	        else if (_node === this._first) {
	            this._first = _node.next;
	            this._first.prev = null;
	        }
	        else if (_node === this._last) {
	            this._last = _node.prev;
	            this._last.next = null;
	        }
	        else {
	            _node.next.prev = _node.prev;
	            _node.prev.next = _node.next;
	        }
	        _node.list = null;
	        _node.next = null;
	        _node.prev = null;
	        this._length--;
	    };
	    /**
	     * Remove all values from the list.
	     *
	     * #### Complexity
	     * Linear.
	     */
	    LinkedList.prototype.clear = function () {
	        var node = this._first;
	        while (node) {
	            var next = node.next;
	            node.list = null;
	            node.prev = null;
	            node.next = null;
	            node = next;
	        }
	        this._first = null;
	        this._last = null;
	        this._length = 0;
	    };
	    return LinkedList;
	}());
	exports.LinkedList = LinkedList;
	/**
	 * The namespace for the `LinkedList` class statics.
	 */
	(function (LinkedList) {
	    /**
	     * Create a linked list from an iterable of values.
	     *
	     * @param values - The iterable or array-like object of interest.
	     *
	     * @returns A new linked list initialized with the given values.
	     */
	    function from(values) {
	        var list = new LinkedList();
	        algorithm_1.each(values, function (value) { list.addLast(value); });
	        return list;
	    }
	    LinkedList.from = from;
	    /**
	     * A forward iterator for values in a linked list.
	     */
	    var ForwardValueIterator = (function () {
	        /**
	         * Construct a forward value iterator.
	         *
	         * @param node - The first node in the list.
	         */
	        function ForwardValueIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        ForwardValueIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        ForwardValueIterator.prototype.clone = function () {
	            return new ForwardValueIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        ForwardValueIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.next;
	            return node.value;
	        };
	        return ForwardValueIterator;
	    }());
	    LinkedList.ForwardValueIterator = ForwardValueIterator;
	    /**
	     * A reverse iterator for values in a linked list.
	     */
	    var RetroValueIterator = (function () {
	        /**
	         * Construct a retro value iterator.
	         *
	         * @param node - The last node in the list.
	         */
	        function RetroValueIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        RetroValueIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        RetroValueIterator.prototype.clone = function () {
	            return new RetroValueIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        RetroValueIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.prev;
	            return node.value;
	        };
	        return RetroValueIterator;
	    }());
	    LinkedList.RetroValueIterator = RetroValueIterator;
	    /**
	     * A forward iterator for nodes in a linked list.
	     */
	    var ForwardNodeIterator = (function () {
	        /**
	         * Construct a forward node iterator.
	         *
	         * @param node - The first node in the list.
	         */
	        function ForwardNodeIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        ForwardNodeIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        ForwardNodeIterator.prototype.clone = function () {
	            return new ForwardNodeIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        ForwardNodeIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.next;
	            return node;
	        };
	        return ForwardNodeIterator;
	    }());
	    LinkedList.ForwardNodeIterator = ForwardNodeIterator;
	    /**
	     * A reverse iterator for nodes in a linked list.
	     */
	    var RetroNodeIterator = (function () {
	        /**
	         * Construct a retro node iterator.
	         *
	         * @param node - The last node in the list.
	         */
	        function RetroNodeIterator(node) {
	            this._node = node;
	        }
	        /**
	         * Get an iterator over the object's values.
	         *
	         * @returns An iterator which yields the object's values.
	         */
	        RetroNodeIterator.prototype.iter = function () {
	            return this;
	        };
	        /**
	         * Create an independent clone of the iterator.
	         *
	         * @returns A new independent clone of the iterator.
	         */
	        RetroNodeIterator.prototype.clone = function () {
	            return new RetroNodeIterator(this._node);
	        };
	        /**
	         * Get the next value from the iterator.
	         *
	         * @returns The next value from the iterator, or `undefined`.
	         */
	        RetroNodeIterator.prototype.next = function () {
	            if (!this._node) {
	                return undefined;
	            }
	            var node = this._node;
	            this._node = node.prev;
	            return node;
	        };
	        return RetroNodeIterator;
	    }());
	    LinkedList.RetroNodeIterator = RetroNodeIterator;
	})(LinkedList = exports.LinkedList || (exports.LinkedList = {}));
	exports.LinkedList = LinkedList;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The internal linked list node implementation.
	     */
	    var LinkedListNode = (function () {
	        /**
	         * Construct a new linked list node.
	         *
	         * @param list - The list which owns the node.
	         *
	         * @param value - The value for the link.
	         */
	        function LinkedListNode(list, value) {
	            /**
	             * The linked list which created and owns the node.
	             */
	            this.list = null;
	            /**
	             * The next node in the list.
	             */
	            this.next = null;
	            /**
	             * The previous node in the list.
	             */
	            this.prev = null;
	            this.list = list;
	            this.value = value;
	        }
	        return LinkedListNode;
	    }());
	    Private.LinkedListNode = LinkedListNode;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/collections@1.1.1/lib/linkedlist.js **/


/** START DEFINE BLOCK for @phosphor/properties@1.1.1/lib/index.js **/
jupyter.define('@phosphor/properties@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A class which attaches a value to an external object.
	 *
	 * #### Notes
	 * Attached properties are used to extend the state of an object with
	 * semantic data from an unrelated class. They also encapsulate value
	 * creation, coercion, and notification.
	 *
	 * Because attached property values are stored in a hash table, which
	 * in turn is stored in a WeakMap keyed on the owner object, there is
	 * non-trivial storage overhead involved in their use. The pattern is
	 * therefore best used for the storage of rare data.
	 */
	var AttachedProperty = (function () {
	    /**
	     * Construct a new attached property.
	     *
	     * @param options - The options for initializing the property.
	     */
	    function AttachedProperty(options) {
	        this._pid = Private.nextPID();
	        this.name = options.name;
	        this._create = options.create;
	        this._coerce = options.coerce || null;
	        this._compare = options.compare || null;
	        this._changed = options.changed || null;
	    }
	    /**
	     * Get the current value of the property for a given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * @returns The current value of the property.
	     *
	     * #### Notes
	     * If the value has not yet been set, the default value will be
	     * computed and assigned as the current value of the property.
	     */
	    AttachedProperty.prototype.get = function (owner) {
	        var value;
	        var map = Private.ensureMap(owner);
	        if (this._pid in map) {
	            value = map[this._pid];
	        }
	        else {
	            value = map[this._pid] = this._createValue(owner);
	        }
	        return value;
	    };
	    /**
	     * Set the current value of the property for a given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * @param value - The value for the property.
	     *
	     * #### Notes
	     * If the value has not yet been set, the default value will be
	     * computed and used as the previous value for the comparison.
	     */
	    AttachedProperty.prototype.set = function (owner, value) {
	        var oldValue;
	        var map = Private.ensureMap(owner);
	        if (this._pid in map) {
	            oldValue = map[this._pid];
	        }
	        else {
	            oldValue = map[this._pid] = this._createValue(owner);
	        }
	        var newValue = this._coerceValue(owner, value);
	        this._maybeNotify(owner, oldValue, map[this._pid] = newValue);
	    };
	    /**
	     * Explicitly coerce the current property value for a given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * #### Notes
	     * If the value has not yet been set, the default value will be
	     * computed and used as the previous value for the comparison.
	     */
	    AttachedProperty.prototype.coerce = function (owner) {
	        var oldValue;
	        var map = Private.ensureMap(owner);
	        if (this._pid in map) {
	            oldValue = map[this._pid];
	        }
	        else {
	            oldValue = map[this._pid] = this._createValue(owner);
	        }
	        var newValue = this._coerceValue(owner, oldValue);
	        this._maybeNotify(owner, oldValue, map[this._pid] = newValue);
	    };
	    /**
	     * Get or create the default value for the given owner.
	     */
	    AttachedProperty.prototype._createValue = function (owner) {
	        var create = this._create;
	        return create(owner);
	    };
	    /**
	     * Coerce the value for the given owner.
	     */
	    AttachedProperty.prototype._coerceValue = function (owner, value) {
	        var coerce = this._coerce;
	        return coerce ? coerce(owner, value) : value;
	    };
	    /**
	     * Compare the old value and new value for equality.
	     */
	    AttachedProperty.prototype._compareValue = function (oldValue, newValue) {
	        var compare = this._compare;
	        return compare ? compare(oldValue, newValue) : oldValue === newValue;
	    };
	    /**
	     * Run the change notification if the given values are different.
	     */
	    AttachedProperty.prototype._maybeNotify = function (owner, oldValue, newValue) {
	        var changed = this._changed;
	        if (changed && !this._compareValue(oldValue, newValue)) {
	            changed(owner, oldValue, newValue);
	        }
	    };
	    return AttachedProperty;
	}());
	exports.AttachedProperty = AttachedProperty;
	/**
	 * The namespace for the `AttachedProperty` class statics.
	 */
	(function (AttachedProperty) {
	    /**
	     * Clear the stored property data for the given owner.
	     *
	     * @param owner - The property owner of interest.
	     *
	     * #### Notes
	     * This will clear all property values for the owner, but it will
	     * **not** run the change notification for any of the properties.
	     */
	    function clearData(owner) {
	        Private.ownerData.delete(owner);
	    }
	    AttachedProperty.clearData = clearData;
	})(AttachedProperty = exports.AttachedProperty || (exports.AttachedProperty = {}));
	exports.AttachedProperty = AttachedProperty;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A weak mapping of property owner to property map.
	     */
	    Private.ownerData = new WeakMap();
	    /**
	     * A function which computes successive unique property ids.
	     */
	    Private.nextPID = (function () {
	        var id = 0;
	        return function () {
	            var rand = Math.random();
	            var stem = ("" + rand).slice(2);
	            return "pid-" + stem + "-" + id++;
	        };
	    })();
	    /**
	     * Lookup the data map for the property owner.
	     *
	     * This will create the map if one does not already exist.
	     */
	    function ensureMap(owner) {
	        var map = Private.ownerData.get(owner);
	        if (map) {
	            return map;
	        }
	        map = Object.create(null);
	        Private.ownerData.set(owner, map);
	        return map;
	    }
	    Private.ensureMap = ensureMap;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/properties@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/layout.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/layout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.1.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * An abstract base class for creating Phosphor layouts.
	 *
	 * #### Notes
	 * A layout is used to add widgets to a parent and to arrange those
	 * widgets within the parent's DOM node.
	 *
	 * This class implements the base functionality which is required of
	 * nearly all layouts. It must be subclassed in order to be useful.
	 *
	 * Notably, this class does not define a uniform interface for adding
	 * widgets to the layout. A subclass should define that API in a way
	 * which is meaningful for its intended use.
	 */
	var Layout = (function () {
	    /**
	     * Construct a new layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function Layout(options) {
	        if (options === void 0) { options = {}; }
	        this._disposed = false;
	        this._parent = null;
	        this._fitPolicy = options.fitPolicy || 'set-min-size';
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This should be reimplemented to clear and dispose of the widgets.
	     *
	     * All reimplementations should call the superclass method.
	     *
	     * This method is called automatically when the parent is disposed.
	     */
	    Layout.prototype.dispose = function () {
	        this._parent = null;
	        this._disposed = true;
	        signaling_1.Signal.clearData(this);
	        properties_1.AttachedProperty.clearData(this);
	    };
	    Object.defineProperty(Layout.prototype, "isDisposed", {
	        /**
	         * Test whether the layout is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Layout.prototype, "parent", {
	        /**
	         * Get the parent widget of the layout.
	         */
	        get: function () {
	            return this._parent;
	        },
	        /**
	         * Set the parent widget of the layout.
	         *
	         * #### Notes
	         * This is set automatically when installing the layout on the parent
	         * widget. The parent widget should not be set directly by user code.
	         */
	        set: function (value) {
	            if (this._parent === value) {
	                return;
	            }
	            if (this._parent) {
	                throw new Error('Cannot change parent widget.');
	            }
	            if (value.layout !== this) {
	                throw new Error('Invalid parent widget.');
	            }
	            this._parent = value;
	            this.init();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Layout.prototype, "fitPolicy", {
	        /**
	         * Get the fit policy for the layout.
	         *
	         * #### Notes
	         * The fit policy controls the computed size constraints which are
	         * applied to the parent widget by the layout.
	         *
	         * Some layout implementations may ignore the fit policy.
	         */
	        get: function () {
	            return this._fitPolicy;
	        },
	        /**
	         * Set the fit policy for the layout.
	         *
	         * #### Notes
	         * The fit policy controls the computed size constraints which are
	         * applied to the parent widget by the layout.
	         *
	         * Some layout implementations may ignore the fit policy.
	         *
	         * Changing the fit policy will clear the current size constraint
	         * for the parent widget and then re-fit the parent.
	         */
	        set: function (value) {
	            // Bail if the policy does not change
	            if (this._fitPolicy === value) {
	                return;
	            }
	            // Update the internal policy.
	            this._fitPolicy = value;
	            // Clear the size constraints and schedule a fit of the parent.
	            if (this._parent) {
	                var style = this._parent.node.style;
	                style.minWidth = '';
	                style.minHeight = '';
	                style.maxWidth = '';
	                style.maxHeight = '';
	                this._parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Process a message sent to the parent widget.
	     *
	     * @param msg - The message sent to the parent widget.
	     *
	     * #### Notes
	     * This method is called by the parent widget to process a message.
	     *
	     * Subclasses may reimplement this method as needed.
	     */
	    Layout.prototype.processParentMessage = function (msg) {
	        switch (msg.type) {
	            case 'resize':
	                this.onResize(msg);
	                break;
	            case 'update-request':
	                this.onUpdateRequest(msg);
	                break;
	            case 'fit-request':
	                this.onFitRequest(msg);
	                break;
	            case 'before-show':
	                this.onBeforeShow(msg);
	                break;
	            case 'after-show':
	                this.onAfterShow(msg);
	                break;
	            case 'before-hide':
	                this.onBeforeHide(msg);
	                break;
	            case 'after-hide':
	                this.onAfterHide(msg);
	                break;
	            case 'before-attach':
	                this.onBeforeAttach(msg);
	                break;
	            case 'after-attach':
	                this.onAfterAttach(msg);
	                break;
	            case 'before-detach':
	                this.onBeforeDetach(msg);
	                break;
	            case 'after-detach':
	                this.onAfterDetach(msg);
	                break;
	            case 'child-removed':
	                this.onChildRemoved(msg);
	                break;
	            case 'child-shown':
	                this.onChildShown(msg);
	                break;
	            case 'child-hidden':
	                this.onChildHidden(msg);
	                break;
	        }
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     *
	     * #### Notes
	     * This method is invoked immediately after the layout is installed
	     * on the parent widget.
	     *
	     * The default implementation reparents all of the widgets to the
	     * layout parent widget.
	     *
	     * Subclasses should reimplement this method and attach the child
	     * widget nodes to the parent widget's node.
	     */
	    Layout.prototype.init = function () {
	        var _this = this;
	        algorithm_1.each(this, function (widget) {
	            widget.parent = _this.parent;
	        });
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     *
	     * #### Notes
	     * The layout should ensure that its widgets are resized according
	     * to the specified layout space, and that they are sent a `'resize'`
	     * message if appropriate.
	     *
	     * The default implementation of this method sends an `UnknownSize`
	     * resize message to all widgets.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onResize = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.ResizeMessage.UnknownSize);
	        });
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     *
	     * #### Notes
	     * The layout should ensure that its widgets are resized according
	     * to the available layout space, and that they are sent a `'resize'`
	     * message if appropriate.
	     *
	     * The default implementation of this method sends an `UnknownSize`
	     * resize message to all widgets.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onUpdateRequest = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.ResizeMessage.UnknownSize);
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeAttach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterAttach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeDetach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message
	     * to all widgets. It assumes all widget nodes are attached to the
	     * parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterDetach = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            messaging_1.MessageLoop.sendMessage(widget, msg);
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeShow = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterShow = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on a `'before-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onBeforeHide = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on an `'after-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this method forwards the message to
	     * all non-hidden widgets. It assumes all widget nodes are attached
	     * to the parent widget node.
	     *
	     * This may be reimplemented by subclasses as needed.
	     */
	    Layout.prototype.onAfterHide = function (msg) {
	        algorithm_1.each(this, function (widget) {
	            if (!widget.isHidden) {
	                messaging_1.MessageLoop.sendMessage(widget, msg);
	            }
	        });
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     *
	     * #### Notes
	     * This will remove the child widget from the layout.
	     *
	     * Subclasses should **not** typically reimplement this method.
	     */
	    Layout.prototype.onChildRemoved = function (msg) {
	        this.removeWidget(msg.child);
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onFitRequest = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onChildShown = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Layout.prototype.onChildHidden = function (msg) { };
	    return Layout;
	}());
	exports.Layout = Layout;
	/**
	 * The namespace for the `Layout` class statics.
	 */
	(function (Layout) {
	    /**
	     * Get the horizontal alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The horizontal alignment for the widget.
	     *
	     * #### Notes
	     * If the layout width allocated to a widget is larger than its max
	     * width, the horizontal alignment controls how the widget is placed
	     * within the extra horizontal space.
	     *
	     * If the allocated width is less than the widget's max width, the
	     * horizontal alignment has no effect.
	     *
	     * Some layout implementations may ignore horizontal alignment.
	     */
	    function getHorizontalAlignment(widget) {
	        return Private.horizontalAlignmentProperty.get(widget);
	    }
	    Layout.getHorizontalAlignment = getHorizontalAlignment;
	    /**
	     * Set the horizontal alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the horizontal alignment.
	     *
	     * #### Notes
	     * If the layout width allocated to a widget is larger than its max
	     * width, the horizontal alignment controls how the widget is placed
	     * within the extra horizontal space.
	     *
	     * If the allocated width is less than the widget's max width, the
	     * horizontal alignment has no effect.
	     *
	     * Some layout implementations may ignore horizontal alignment.
	     *
	     * Changing the horizontal alignment will post an `update-request`
	     * message to widget's parent, provided the parent has a layout
	     * installed.
	     */
	    function setHorizontalAlignment(widget, value) {
	        Private.horizontalAlignmentProperty.set(widget, value);
	    }
	    Layout.setHorizontalAlignment = setHorizontalAlignment;
	    /**
	     * Get the vertical alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The vertical alignment for the widget.
	     *
	     * #### Notes
	     * If the layout height allocated to a widget is larger than its max
	     * height, the vertical alignment controls how the widget is placed
	     * within the extra vertical space.
	     *
	     * If the allocated height is less than the widget's max height, the
	     * vertical alignment has no effect.
	     *
	     * Some layout implementations may ignore vertical alignment.
	     */
	    function getVerticalAlignment(widget) {
	        return Private.verticalAlignmentProperty.get(widget);
	    }
	    Layout.getVerticalAlignment = getVerticalAlignment;
	    /**
	     * Set the vertical alignment for a widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the vertical alignment.
	     *
	     * #### Notes
	     * If the layout height allocated to a widget is larger than its max
	     * height, the vertical alignment controls how the widget is placed
	     * within the extra vertical space.
	     *
	     * If the allocated height is less than the widget's max height, the
	     * vertical alignment has no effect.
	     *
	     * Some layout implementations may ignore vertical alignment.
	     *
	     * Changing the horizontal alignment will post an `update-request`
	     * message to widget's parent, provided the parent has a layout
	     * installed.
	     */
	    function setVerticalAlignment(widget, value) {
	        Private.verticalAlignmentProperty.set(widget, value);
	    }
	    Layout.setVerticalAlignment = setVerticalAlignment;
	})(Layout = exports.Layout || (exports.Layout = {}));
	exports.Layout = Layout;
	/**
	 * An object which assists in the absolute layout of widgets.
	 *
	 * #### Notes
	 * This class is useful when implementing a layout which arranges its
	 * widgets using absolute positioning.
	 *
	 * This class is used by nearly all of the built-in Phosphor layouts.
	 */
	var LayoutItem = (function () {
	    /**
	     * Construct a new layout item.
	     *
	     * @param widget - The widget to be managed by the item.
	     *
	     * #### Notes
	     * The widget will be set to absolute positioning.
	     */
	    function LayoutItem(widget) {
	        this._top = NaN;
	        this._left = NaN;
	        this._width = NaN;
	        this._height = NaN;
	        this._minWidth = 0;
	        this._minHeight = 0;
	        this._maxWidth = Infinity;
	        this._maxHeight = Infinity;
	        this._disposed = false;
	        this.widget = widget;
	        this.widget.node.style.position = 'absolute';
	    }
	    /**
	     * Dispose of the the layout item.
	     *
	     * #### Notes
	     * This will reset the positioning of the widget.
	     */
	    LayoutItem.prototype.dispose = function () {
	        // Do nothing if the item is already disposed.
	        if (this._disposed) {
	            return;
	        }
	        // Mark the item as disposed.
	        this._disposed = true;
	        // Reset the widget style.
	        var style = this.widget.node.style;
	        style.position = '';
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	    };
	    Object.defineProperty(LayoutItem.prototype, "minWidth", {
	        /**
	         * The computed minimum width of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._minWidth;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "minHeight", {
	        /**
	         * The computed minimum height of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._minHeight;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "maxWidth", {
	        /**
	         * The computed maximum width of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._maxWidth;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "maxHeight", {
	        /**
	         * The computed maximum height of the widget.
	         *
	         * #### Notes
	         * This value can be updated by calling the `fit` method.
	         */
	        get: function () {
	            return this._maxHeight;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isDisposed", {
	        /**
	         * Whether the layout item is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isHidden", {
	        /**
	         * Whether the managed widget is hidden.
	         */
	        get: function () {
	            return this.widget.isHidden;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isVisible", {
	        /**
	         * Whether the managed widget is visible.
	         */
	        get: function () {
	            return this.widget.isVisible;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(LayoutItem.prototype, "isAttached", {
	        /**
	         * Whether the managed widget is attached.
	         */
	        get: function () {
	            return this.widget.isAttached;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Update the computed size limits of the managed widget.
	     */
	    LayoutItem.prototype.fit = function () {
	        var limits = domutils_1.ElementExt.sizeLimits(this.widget.node);
	        this._minWidth = limits.minWidth;
	        this._minHeight = limits.minHeight;
	        this._maxWidth = limits.maxWidth;
	        this._maxHeight = limits.maxHeight;
	    };
	    /**
	     * Update the position and size of the managed widget.
	     *
	     * @param left - The left edge position of the layout box.
	     *
	     * @param top - The top edge position of the layout box.
	     *
	     * @param width - The width of the layout box.
	     *
	     * @param height - The height of the layout box.
	     */
	    LayoutItem.prototype.update = function (left, top, width, height) {
	        // Clamp the size to the computed size limits.
	        var clampW = Math.max(this._minWidth, Math.min(width, this._maxWidth));
	        var clampH = Math.max(this._minHeight, Math.min(height, this._maxHeight));
	        // Ajdust the left edge for the horizontal alignment, if needed.
	        if (clampW < width) {
	            switch (Layout.getHorizontalAlignment(this.widget)) {
	                case 'left':
	                    break;
	                case 'center':
	                    left += (width - clampW) / 2;
	                    break;
	                case 'right':
	                    left += width - clampW;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Ajdust the top edge for the vertical alignment, if needed.
	        if (clampH < height) {
	            switch (Layout.getVerticalAlignment(this.widget)) {
	                case 'top':
	                    break;
	                case 'center':
	                    top += (height - clampH) / 2;
	                    break;
	                case 'bottom':
	                    top += height - clampH;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Set up the resize variables.
	        var resized = false;
	        var style = this.widget.node.style;
	        // Update the top edge of the widget if needed.
	        if (this._top !== top) {
	            this._top = top;
	            style.top = top + "px";
	        }
	        // Update the left edge of the widget if needed.
	        if (this._left !== left) {
	            this._left = left;
	            style.left = left + "px";
	        }
	        // Update the width of the widget if needed.
	        if (this._width !== clampW) {
	            resized = true;
	            this._width = clampW;
	            style.width = clampW + "px";
	        }
	        // Update the height of the widget if needed.
	        if (this._height !== clampH) {
	            resized = true;
	            this._height = clampH;
	            style.height = clampH + "px";
	        }
	        // Send a resize message to the widget if needed.
	        if (resized) {
	            var msg = new widget_1.Widget.ResizeMessage(clampW, clampH);
	            messaging_1.MessageLoop.sendMessage(this.widget, msg);
	        }
	    };
	    return LayoutItem;
	}());
	exports.LayoutItem = LayoutItem;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The attached property for a widget horizontal alignment.
	     */
	    Private.horizontalAlignmentProperty = new properties_1.AttachedProperty({
	        name: 'horizontalAlignment',
	        create: function () { return 'center'; },
	        changed: onAlignmentChanged
	    });
	    /**
	     * The attached property for a widget vertical alignment.
	     */
	    Private.verticalAlignmentProperty = new properties_1.AttachedProperty({
	        name: 'verticalAlignment',
	        create: function () { return 'top'; },
	        changed: onAlignmentChanged
	    });
	    /**
	     * The change handler for the attached alignment properties.
	     */
	    function onAlignmentChanged(child) {
	        if (child.parent && child.parent.layout) {
	            child.parent.update();
	        }
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/layout.js **/


/** START DEFINE BLOCK for @phosphor/signaling@1.2.1/lib/index.js **/
jupyter.define('@phosphor/signaling@1.2.1/lib/index.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(setImmediate) {"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	/**
	 * A concrete implementation of `ISignal`.
	 *
	 * #### Example
	 * ```typescript
	 * import { ISignal, Signal } from '@phosphor/signaling';
	 *
	 * class SomeClass {
	 *
	 *   constructor(name: string) {
	 *     this.name = name;
	 *   }
	 *
	 *   readonly name: string;
	 *
	 *   get valueChanged: ISignal<this, number> {
	 *     return this._valueChanged;
	 *   }
	 *
	 *   get value(): number {
	 *     return this._value;
	 *   }
	 *
	 *   set value(value: number) {
	 *     if (value === this._value) {
	 *       return;
	 *     }
	 *     this._value = value;
	 *     this._valueChanged.emit(value);
	 *   }
	 *
	 *   private _value = 0;
	 *   private _valueChanged = new Signal<this, number>(this);
	 * }
	 *
	 * function logger(sender: SomeClass, value: number): void {
	 *   console.log(sender.name, value);
	 * }
	 *
	 * let m1 = new SomeClass('foo');
	 * let m2 = new SomeClass('bar');
	 *
	 * m1.valueChanged.connect(logger);
	 * m2.valueChanged.connect(logger);
	 *
	 * m1.value = 42;  // logs: foo 42
	 * m2.value = 17;  // logs: bar 17
	 * ```
	 */
	var Signal = (function () {
	    /**
	     * Construct a new signal.
	     *
	     * @param sender - The sender which owns the signal.
	     */
	    function Signal(sender) {
	        this.sender = sender;
	    }
	    /**
	     * Connect a slot to the signal.
	     *
	     * @param slot - The slot to invoke when the signal is emitted.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection succeeds, `false` otherwise.
	     */
	    Signal.prototype.connect = function (slot, thisArg) {
	        return Private.connect(this, slot, thisArg);
	    };
	    /**
	     * Disconnect a slot from the signal.
	     *
	     * @param slot - The slot to disconnect from the signal.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection is removed, `false` otherwise.
	     */
	    Signal.prototype.disconnect = function (slot, thisArg) {
	        return Private.disconnect(this, slot, thisArg);
	    };
	    /**
	     * Emit the signal and invoke the connected slots.
	     *
	     * @param args - The args to pass to the connected slots.
	     *
	     * #### Notes
	     * Slots are invoked synchronously in connection order.
	     *
	     * Exceptions thrown by connected slots will be caught and logged.
	     */
	    Signal.prototype.emit = function (args) {
	        Private.emit(this, args);
	    };
	    return Signal;
	}());
	exports.Signal = Signal;
	/**
	 * The namespace for the `Signal` class statics.
	 */
	(function (Signal) {
	    /**
	     * Remove all connections between a sender and receiver.
	     *
	     * @param sender - The sender object of interest.
	     *
	     * @param receiver - The receiver object of interest.
	     *
	     * #### Notes
	     * If a `thisArg` is provided when connecting a signal, that object
	     * is considered the receiver. Otherwise, the `slot` is considered
	     * the receiver.
	     */
	    function disconnectBetween(sender, receiver) {
	        Private.disconnectBetween(sender, receiver);
	    }
	    Signal.disconnectBetween = disconnectBetween;
	    /**
	     * Remove all connections where the given object is the sender.
	     *
	     * @param sender - The sender object of interest.
	     */
	    function disconnectSender(sender) {
	        Private.disconnectSender(sender);
	    }
	    Signal.disconnectSender = disconnectSender;
	    /**
	     * Remove all connections where the given object is the receiver.
	     *
	     * @param receiver - The receiver object of interest.
	     *
	     * #### Notes
	     * If a `thisArg` is provided when connecting a signal, that object
	     * is considered the receiver. Otherwise, the `slot` is considered
	     * the receiver.
	     */
	    function disconnectReceiver(receiver) {
	        Private.disconnectReceiver(receiver);
	    }
	    Signal.disconnectReceiver = disconnectReceiver;
	    /**
	     * Remove all connections where an object is the sender or receiver.
	     *
	     * @param object - The object of interest.
	     *
	     * #### Notes
	     * If a `thisArg` is provided when connecting a signal, that object
	     * is considered the receiver. Otherwise, the `slot` is considered
	     * the receiver.
	     */
	    function disconnectAll(object) {
	        Private.disconnectAll(object);
	    }
	    Signal.disconnectAll = disconnectAll;
	    /**
	     * Clear all signal data associated with the given object.
	     *
	     * @param object - The object for which the data should be cleared.
	     *
	     * #### Notes
	     * This removes all signal connections and any other signal data
	     * associated with the object.
	     */
	    function clearData(object) {
	        Private.disconnectAll(object);
	    }
	    Signal.clearData = clearData;
	    /**
	     * Get the signal exception handler.
	     *
	     * @returns The current exception handler.
	     *
	     * #### Notes
	     * The default exception handler is `console.error`.
	     */
	    function getExceptionHandler() {
	        return Private.exceptionHandler;
	    }
	    Signal.getExceptionHandler = getExceptionHandler;
	    /**
	     * Set the signal exception handler.
	     *
	     * @param handler - The function to use as the exception handler.
	     *
	     * @returns The old exception handler.
	     *
	     * #### Notes
	     * The exception handler is invoked when a slot throws an exception.
	     */
	    function setExceptionHandler(handler) {
	        var old = Private.exceptionHandler;
	        Private.exceptionHandler = handler;
	        return old;
	    }
	    Signal.setExceptionHandler = setExceptionHandler;
	})(Signal = exports.Signal || (exports.Signal = {}));
	exports.Signal = Signal;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The signal exception handler function.
	     */
	    Private.exceptionHandler = function (err) {
	        console.error(err);
	    };
	    /**
	     * Connect a slot to a signal.
	     *
	     * @param signal - The signal of interest.
	     *
	     * @param slot - The slot to invoke when the signal is emitted.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection succeeds, `false` otherwise.
	     */
	    function connect(signal, slot, thisArg) {
	        // Coerce a `null` `thisArg` to `undefined`.
	        thisArg = thisArg || undefined;
	        // Ensure the sender's array of receivers is created.
	        var receivers = receiversForSender.get(signal.sender);
	        if (!receivers) {
	            receivers = [];
	            receiversForSender.set(signal.sender, receivers);
	        }
	        // Bail if a matching connection already exists.
	        if (findConnection(receivers, signal, slot, thisArg)) {
	            return false;
	        }
	        // Choose the best object for the receiver.
	        var receiver = thisArg || slot;
	        // Ensure the receiver's array of senders is created.
	        var senders = sendersForReceiver.get(receiver);
	        if (!senders) {
	            senders = [];
	            sendersForReceiver.set(receiver, senders);
	        }
	        // Create a new connection and add it to the end of each array.
	        var connection = { signal: signal, slot: slot, thisArg: thisArg };
	        receivers.push(connection);
	        senders.push(connection);
	        // Indicate a successful connection.
	        return true;
	    }
	    Private.connect = connect;
	    /**
	     * Disconnect a slot from a signal.
	     *
	     * @param signal - The signal of interest.
	     *
	     * @param slot - The slot to disconnect from the signal.
	     *
	     * @param thisArg - The `this` context for the slot. If provided,
	     *   this must be a non-primitive object.
	     *
	     * @returns `true` if the connection is removed, `false` otherwise.
	     */
	    function disconnect(signal, slot, thisArg) {
	        // Coerce a `null` `thisArg` to `undefined`.
	        thisArg = thisArg || undefined;
	        // Lookup the list of receivers, and bail if none exist.
	        var receivers = receiversForSender.get(signal.sender);
	        if (!receivers || receivers.length === 0) {
	            return false;
	        }
	        // Bail if no matching connection exits.
	        var connection = findConnection(receivers, signal, slot, thisArg);
	        if (!connection) {
	            return false;
	        }
	        // Choose the best object for the receiver.
	        var receiver = thisArg || slot;
	        // Lookup the array of senders, which is now known to exist.
	        var senders = sendersForReceiver.get(receiver);
	        // Clear the connection and schedule cleanup of the arrays.
	        connection.signal = null;
	        scheduleCleanup(receivers);
	        scheduleCleanup(senders);
	        // Indicate a successful disconnection.
	        return true;
	    }
	    Private.disconnect = disconnect;
	    /**
	     * Remove all connections between a sender and receiver.
	     *
	     * @param sender - The sender object of interest.
	     *
	     * @param receiver - The receiver object of interest.
	     */
	    function disconnectBetween(sender, receiver) {
	        // If there are no receivers, there is nothing to do.
	        var receivers = receiversForSender.get(sender);
	        if (!receivers || receivers.length === 0) {
	            return;
	        }
	        // If there are no senders, there is nothing to do.
	        var senders = sendersForReceiver.get(receiver);
	        if (!senders || senders.length === 0) {
	            return;
	        }
	        // Clear each connection between the sender and receiver.
	        algorithm_1.each(senders, function (connection) {
	            // Skip connections which have already been cleared.
	            if (!connection.signal) {
	                return;
	            }
	            // Clear the connection if it matches the sender.
	            if (connection.signal.sender === sender) {
	                connection.signal = null;
	            }
	        });
	        // Schedule a cleanup of the senders and receivers.
	        scheduleCleanup(receivers);
	        scheduleCleanup(senders);
	    }
	    Private.disconnectBetween = disconnectBetween;
	    /**
	     * Remove all connections where the given object is the sender.
	     *
	     * @param sender - The sender object of interest.
	     */
	    function disconnectSender(sender) {
	        // If there are no receivers, there is nothing to do.
	        var receivers = receiversForSender.get(sender);
	        if (!receivers || receivers.length === 0) {
	            return;
	        }
	        // Clear each receiver connection.
	        algorithm_1.each(receivers, function (connection) {
	            // Skip connections which have already been cleared.
	            if (!connection.signal) {
	                return;
	            }
	            // Choose the best object for the receiver.
	            var receiver = connection.thisArg || connection.slot;
	            // Clear the connection.
	            connection.signal = null;
	            // Cleanup the array of senders, which is now known to exist.
	            scheduleCleanup(sendersForReceiver.get(receiver));
	        });
	        // Schedule a cleanup of the receivers.
	        scheduleCleanup(receivers);
	    }
	    Private.disconnectSender = disconnectSender;
	    /**
	     * Remove all connections where the given object is the receiver.
	     *
	     * @param receiver - The receiver object of interest.
	     */
	    function disconnectReceiver(receiver) {
	        // If there are no senders, there is nothing to do.
	        var senders = sendersForReceiver.get(receiver);
	        if (!senders || senders.length === 0) {
	            return;
	        }
	        // Clear each sender connection.
	        algorithm_1.each(senders, function (connection) {
	            // Skip connections which have already been cleared.
	            if (!connection.signal) {
	                return;
	            }
	            // Lookup the sender for the connection.
	            var sender = connection.signal.sender;
	            // Clear the connection.
	            connection.signal = null;
	            // Cleanup the array of receivers, which is now known to exist.
	            scheduleCleanup(receiversForSender.get(sender));
	        });
	        // Schedule a cleanup of the list of senders.
	        scheduleCleanup(senders);
	    }
	    Private.disconnectReceiver = disconnectReceiver;
	    /**
	     * Remove all connections where an object is the sender or receiver.
	     *
	     * @param object - The object of interest.
	     */
	    function disconnectAll(object) {
	        // Clear and cleanup any receiver connections.
	        var receivers = receiversForSender.get(object);
	        if (receivers && receivers.length > 0) {
	            algorithm_1.each(receivers, function (connection) { connection.signal = null; });
	            scheduleCleanup(receivers);
	        }
	        // Clear and cleanup any sender connections.
	        var senders = sendersForReceiver.get(object);
	        if (senders && senders.length > 0) {
	            algorithm_1.each(senders, function (connection) { connection.signal = null; });
	            scheduleCleanup(senders);
	        }
	    }
	    Private.disconnectAll = disconnectAll;
	    /**
	     * Emit a signal and invoke its connected slots.
	     *
	     * @param signal - The signal of interest.
	     *
	     * @param args - The args to pass to the connected slots.
	     *
	     * #### Notes
	     * Slots are invoked synchronously in connection order.
	     *
	     * Exceptions thrown by connected slots will be caught and logged.
	     */
	    function emit(signal, args) {
	        // If there are no receivers, there is nothing to do.
	        var receivers = receiversForSender.get(signal.sender);
	        if (!receivers || receivers.length === 0) {
	            return;
	        }
	        // Invoke the slots for connections with a matching signal.
	        // Any connections added during emission are not invoked.
	        for (var i = 0, n = receivers.length; i < n; ++i) {
	            var connection = receivers[i];
	            if (connection.signal === signal) {
	                invokeSlot(connection, args);
	            }
	        }
	    }
	    Private.emit = emit;
	    /**
	     * A weak mapping of sender to array of receiver connections.
	     */
	    var receiversForSender = new WeakMap();
	    /**
	     * A weak mapping of receiver to array of sender connections.
	     */
	    var sendersForReceiver = new WeakMap();
	    /**
	     * A set of connection arrays which are pending cleanup.
	     */
	    var dirtySet = new Set();
	    /**
	     * A function to schedule an event loop callback.
	     */
	    var schedule = (function () {
	        var ok = typeof requestAnimationFrame === 'function';
	        return ok ? requestAnimationFrame : setImmediate;
	    })();
	    /**
	     * Find a connection which matches the given parameters.
	     */
	    function findConnection(connections, signal, slot, thisArg) {
	        return algorithm_1.find(connections, function (connection) { return (connection.signal === signal &&
	            connection.slot === slot &&
	            connection.thisArg === thisArg); });
	    }
	    /**
	     * Invoke a slot with the given parameters.
	     *
	     * The connection is assumed to be valid.
	     *
	     * Exceptions in the slot will be caught and logged.
	     */
	    function invokeSlot(connection, args) {
	        var signal = connection.signal, slot = connection.slot, thisArg = connection.thisArg;
	        try {
	            slot.call(thisArg, signal.sender, args);
	        }
	        catch (err) {
	            Private.exceptionHandler(err);
	        }
	    }
	    /**
	     * Schedule a cleanup of a connection array.
	     *
	     * This will add the array to the dirty set and schedule a deferred
	     * cleanup of the array contents. On cleanup, any connection with a
	     * `null` signal will be removed from the array.
	     */
	    function scheduleCleanup(array) {
	        if (dirtySet.size === 0) {
	            schedule(cleanupDirtySet);
	        }
	        dirtySet.add(array);
	    }
	    /**
	     * Cleanup the connection lists in the dirty set.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupDirtySet() {
	        dirtySet.forEach(cleanupConnections);
	        dirtySet.clear();
	    }
	    /**
	     * Cleanup the dirty connections in a connections array.
	     *
	     * This will remove any connection with a `null` signal.
	     *
	     * This function should only be invoked asynchronously, when the
	     * stack frame is guaranteed to not be on the path of user code.
	     */
	    function cleanupConnections(connections) {
	        algorithm_1.ArrayExt.removeAllWhere(connections, isDeadConnection);
	    }
	    /**
	     * Test whether a connection is dead.
	     *
	     * A dead connection has a `null` signal.
	     */
	    function isDeadConnection(connection) {
	        return connection.signal === null;
	    }
	})(Private || (Private = {}));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('timers-browserify@2.0.2/main.js').setImmediate))
})
/** END DEFINE BLOCK for @phosphor/signaling@1.2.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/widget.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/widget.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.1.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var title_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/title.js');
	/**
	 * The base class of the Phosphor widget hierarchy.
	 *
	 * #### Notes
	 * This class will typically be subclassed in order to create a useful
	 * widget. However, it can be used directly to host externally created
	 * content.
	 */
	var Widget = (function () {
	    /**
	     * Construct a new widget.
	     *
	     * @param options - The options for initializing the widget.
	     */
	    function Widget(options) {
	        if (options === void 0) { options = {}; }
	        this._flags = 0;
	        this._layout = null;
	        this._parent = null;
	        this._disposed = new signaling_1.Signal(this);
	        this.node = Private.createNode(options);
	        this.addClass('p-Widget');
	    }
	    /**
	     * Dispose of the widget and its descendant widgets.
	     *
	     * #### Notes
	     * It is unsafe to use the widget after it has been disposed.
	     *
	     * All calls made to this method after the first are a no-op.
	     */
	    Widget.prototype.dispose = function () {
	        // Do nothing if the widget is already disposed.
	        if (this.isDisposed) {
	            return;
	        }
	        // Set the disposed flag and emit the disposed signal.
	        this.setFlag(Widget.Flag.IsDisposed);
	        this._disposed.emit(undefined);
	        // Remove or detach the widget if necessary.
	        if (this.parent) {
	            this.parent = null;
	        }
	        else if (this.isAttached) {
	            Widget.detach(this);
	        }
	        // Dispose of the widget layout.
	        if (this._layout) {
	            this._layout.dispose();
	            this._layout = null;
	        }
	        // Clear the extra data associated with the widget.
	        signaling_1.Signal.clearData(this);
	        messaging_1.MessageLoop.clearData(this);
	        properties_1.AttachedProperty.clearData(this);
	    };
	    Object.defineProperty(Widget.prototype, "disposed", {
	        /**
	         * A signal emitted when the widget is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isDisposed", {
	        /**
	         * Test whether the widget has been disposed.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsDisposed);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isAttached", {
	        /**
	         * Test whether the widget's node is attached to the DOM.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsAttached);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isHidden", {
	        /**
	         * Test whether the widget is explicitly hidden.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsHidden);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "isVisible", {
	        /**
	         * Test whether the widget is visible.
	         *
	         * #### Notes
	         * A widget is visible when it is attached to the DOM, is not
	         * explicitly hidden, and has no explicitly hidden ancestors.
	         */
	        get: function () {
	            return this.testFlag(Widget.Flag.IsVisible);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "title", {
	        /**
	         * The title object for the widget.
	         *
	         * #### Notes
	         * The title object is used by some container widgets when displaying
	         * the widget alongside some title, such as a tab panel or side bar.
	         *
	         * Since not all widgets will use the title, it is created on demand.
	         *
	         * The `owner` property of the title is set to this widget.
	         */
	        get: function () {
	            return Private.titleProperty.get(this);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "id", {
	        /**
	         * Get the id of the widget's DOM node.
	         */
	        get: function () {
	            return this.node.id;
	        },
	        /**
	         * Set the id of the widget's DOM node.
	         */
	        set: function (value) {
	            this.node.id = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "dataset", {
	        /**
	         * The dataset for the widget's DOM node.
	         */
	        get: function () {
	            return this.node.dataset;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "parent", {
	        /**
	         * Get the parent of the widget.
	         */
	        get: function () {
	            return this._parent;
	        },
	        /**
	         * Set the parent of the widget.
	         *
	         * #### Notes
	         * Children are typically added to a widget by using a layout, which
	         * means user code will not normally set the parent widget directly.
	         *
	         * The widget will be automatically removed from its old parent.
	         *
	         * This is a no-op if there is no effective parent change.
	         */
	        set: function (value) {
	            if (this._parent === value) {
	                return;
	            }
	            if (value && this.contains(value)) {
	                throw new Error('Invalid parent widget.');
	            }
	            if (this._parent && !this._parent.isDisposed) {
	                var msg = new Widget.ChildMessage('child-removed', this);
	                messaging_1.MessageLoop.sendMessage(this._parent, msg);
	            }
	            this._parent = value;
	            if (this._parent && !this._parent.isDisposed) {
	                var msg = new Widget.ChildMessage('child-added', this);
	                messaging_1.MessageLoop.sendMessage(this._parent, msg);
	            }
	            if (!this.isDisposed) {
	                messaging_1.MessageLoop.sendMessage(this, Widget.Msg.ParentChanged);
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Widget.prototype, "layout", {
	        /**
	         * Get the layout for the widget.
	         */
	        get: function () {
	            return this._layout;
	        },
	        /**
	         * Set the layout for the widget.
	         *
	         * #### Notes
	         * The layout is single-use only. It cannot be changed after the
	         * first assignment.
	         *
	         * The layout is disposed automatically when the widget is disposed.
	         */
	        set: function (value) {
	            if (this._layout === value) {
	                return;
	            }
	            if (this.testFlag(Widget.Flag.DisallowLayout)) {
	                throw new Error('Cannot set widget layout.');
	            }
	            if (this._layout) {
	                throw new Error('Cannot change widget layout.');
	            }
	            if (value.parent) {
	                throw new Error('Cannot change layout parent.');
	            }
	            this._layout = value;
	            value.parent = this;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the widget's children.
	     *
	     * @returns A new iterator over the children of the widget.
	     *
	     * #### Notes
	     * The widget must have a populated layout in order to have children.
	     *
	     * If a layout is not installed, the returned iterator will be empty.
	     */
	    Widget.prototype.children = function () {
	        return this._layout ? this._layout.iter() : algorithm_1.empty();
	    };
	    /**
	     * Test whether a widget is a descendant of this widget.
	     *
	     * @param widget - The descendant widget of interest.
	     *
	     * @returns `true` if the widget is a descendant, `false` otherwise.
	     */
	    Widget.prototype.contains = function (widget) {
	        for (var value = widget; value; value = value._parent) {
	            if (value === this) {
	                return true;
	            }
	        }
	        return false;
	    };
	    /**
	     * Test whether the widget's DOM node has the given class name.
	     *
	     * @param name - The class name of interest.
	     *
	     * @returns `true` if the node has the class, `false` otherwise.
	     */
	    Widget.prototype.hasClass = function (name) {
	        return this.node.classList.contains(name);
	    };
	    /**
	     * Add a class name to the widget's DOM node.
	     *
	     * @param name - The class name to add to the node.
	     *
	     * #### Notes
	     * If the class name is already added to the node, this is a no-op.
	     *
	     * The class name must not contain whitespace.
	     */
	    Widget.prototype.addClass = function (name) {
	        this.node.classList.add(name);
	    };
	    /**
	     * Remove a class name from the widget's DOM node.
	     *
	     * @param name - The class name to remove from the node.
	     *
	     * #### Notes
	     * If the class name is not yet added to the node, this is a no-op.
	     *
	     * The class name must not contain whitespace.
	     */
	    Widget.prototype.removeClass = function (name) {
	        this.node.classList.remove(name);
	    };
	    /**
	     * Toggle a class name on the widget's DOM node.
	     *
	     * @param name - The class name to toggle on the node.
	     *
	     * @param force - Whether to force add the class (`true`) or force
	     *   remove the class (`false`). If not provided, the presence of
	     *   the class will be toggled from its current state.
	     *
	     * @returns `true` if the class is now present, `false` otherwise.
	     *
	     * #### Notes
	     * The class name must not contain whitespace.
	     */
	    Widget.prototype.toggleClass = function (name, force) {
	        if (force === true) {
	            this.node.classList.add(name);
	            return true;
	        }
	        if (force === false) {
	            this.node.classList.remove(name);
	            return false;
	        }
	        return this.node.classList.toggle(name);
	    };
	    /**
	     * Post an `'update-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for posting the message.
	     */
	    Widget.prototype.update = function () {
	        messaging_1.MessageLoop.postMessage(this, Widget.Msg.UpdateRequest);
	    };
	    /**
	     * Post a `'fit-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for posting the message.
	     */
	    Widget.prototype.fit = function () {
	        messaging_1.MessageLoop.postMessage(this, Widget.Msg.FitRequest);
	    };
	    /**
	     * Post an `'activate-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for posting the message.
	     */
	    Widget.prototype.activate = function () {
	        messaging_1.MessageLoop.postMessage(this, Widget.Msg.ActivateRequest);
	    };
	    /**
	     * Send a `'close-request'` message to the widget.
	     *
	     * #### Notes
	     * This is a simple convenience method for sending the message.
	     */
	    Widget.prototype.close = function () {
	        messaging_1.MessageLoop.sendMessage(this, Widget.Msg.CloseRequest);
	    };
	    /**
	     * Show the widget and make it visible to its parent widget.
	     *
	     * #### Notes
	     * This causes the [[isHidden]] property to be `false`.
	     *
	     * If the widget is not explicitly hidden, this is a no-op.
	     */
	    Widget.prototype.show = function () {
	        if (!this.testFlag(Widget.Flag.IsHidden)) {
	            return;
	        }
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.BeforeShow);
	        }
	        this.clearFlag(Widget.Flag.IsHidden);
	        this.removeClass('p-mod-hidden');
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.AfterShow);
	        }
	        if (this.parent) {
	            var msg = new Widget.ChildMessage('child-shown', this);
	            messaging_1.MessageLoop.sendMessage(this.parent, msg);
	        }
	    };
	    /**
	     * Hide the widget and make it hidden to its parent widget.
	     *
	     * #### Notes
	     * This causes the [[isHidden]] property to be `true`.
	     *
	     * If the widget is explicitly hidden, this is a no-op.
	     */
	    Widget.prototype.hide = function () {
	        if (this.testFlag(Widget.Flag.IsHidden)) {
	            return;
	        }
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.BeforeHide);
	        }
	        this.setFlag(Widget.Flag.IsHidden);
	        this.addClass('p-mod-hidden');
	        if (this.isAttached && (!this.parent || this.parent.isVisible)) {
	            messaging_1.MessageLoop.sendMessage(this, Widget.Msg.AfterHide);
	        }
	        if (this.parent) {
	            var msg = new Widget.ChildMessage('child-hidden', this);
	            messaging_1.MessageLoop.sendMessage(this.parent, msg);
	        }
	    };
	    /**
	     * Show or hide the widget according to a boolean value.
	     *
	     * @param hidden - `true` to hide the widget, or `false` to show it.
	     *
	     * #### Notes
	     * This is a convenience method for `hide()` and `show()`.
	     */
	    Widget.prototype.setHidden = function (hidden) {
	        if (hidden) {
	            this.hide();
	        }
	        else {
	            this.show();
	        }
	    };
	    /**
	     * Test whether the given widget flag is set.
	     *
	     * #### Notes
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.testFlag = function (flag) {
	        return (this._flags & flag) !== 0;
	    };
	    /**
	     * Set the given widget flag.
	     *
	     * #### Notes
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.setFlag = function (flag) {
	        this._flags |= flag;
	    };
	    /**
	     * Clear the given widget flag.
	     *
	     * #### Notes
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.clearFlag = function (flag) {
	        this._flags &= ~flag;
	    };
	    /**
	     * Process a message sent to the widget.
	     *
	     * @param msg - The message sent to the widget.
	     *
	     * #### Notes
	     * Subclasses may reimplement this method as needed.
	     */
	    Widget.prototype.processMessage = function (msg) {
	        switch (msg.type) {
	            case 'resize':
	                this.notifyLayout(msg);
	                this.onResize(msg);
	                break;
	            case 'update-request':
	                this.notifyLayout(msg);
	                this.onUpdateRequest(msg);
	                break;
	            case 'fit-request':
	                this.notifyLayout(msg);
	                this.onFitRequest(msg);
	                break;
	            case 'before-show':
	                this.notifyLayout(msg);
	                this.onBeforeShow(msg);
	                break;
	            case 'after-show':
	                this.setFlag(Widget.Flag.IsVisible);
	                this.notifyLayout(msg);
	                this.onAfterShow(msg);
	                break;
	            case 'before-hide':
	                this.notifyLayout(msg);
	                this.onBeforeHide(msg);
	                break;
	            case 'after-hide':
	                this.clearFlag(Widget.Flag.IsVisible);
	                this.notifyLayout(msg);
	                this.onAfterHide(msg);
	                break;
	            case 'before-attach':
	                this.notifyLayout(msg);
	                this.onBeforeAttach(msg);
	                break;
	            case 'after-attach':
	                if (!this.isHidden && (!this.parent || this.parent.isVisible)) {
	                    this.setFlag(Widget.Flag.IsVisible);
	                }
	                this.setFlag(Widget.Flag.IsAttached);
	                this.notifyLayout(msg);
	                this.onAfterAttach(msg);
	                break;
	            case 'before-detach':
	                this.notifyLayout(msg);
	                this.onBeforeDetach(msg);
	                break;
	            case 'after-detach':
	                this.clearFlag(Widget.Flag.IsVisible);
	                this.clearFlag(Widget.Flag.IsAttached);
	                this.notifyLayout(msg);
	                this.onAfterDetach(msg);
	                break;
	            case 'activate-request':
	                this.notifyLayout(msg);
	                this.onActivateRequest(msg);
	                break;
	            case 'close-request':
	                this.notifyLayout(msg);
	                this.onCloseRequest(msg);
	                break;
	            case 'child-added':
	                this.notifyLayout(msg);
	                this.onChildAdded(msg);
	                break;
	            case 'child-removed':
	                this.notifyLayout(msg);
	                this.onChildRemoved(msg);
	                break;
	            default:
	                this.notifyLayout(msg);
	                break;
	        }
	    };
	    /**
	     * Invoke the message processing routine of the widget's layout.
	     *
	     * @param msg - The message to dispatch to the layout.
	     *
	     * #### Notes
	     * This is a no-op if the widget does not have a layout.
	     *
	     * This will not typically be called directly by user code.
	     */
	    Widget.prototype.notifyLayout = function (msg) {
	        if (this._layout) {
	            this._layout.processParentMessage(msg);
	        }
	    };
	    /**
	     * A message handler invoked on a `'close-request'` message.
	     *
	     * #### Notes
	     * The default implementation unparents or detaches the widget.
	     */
	    Widget.prototype.onCloseRequest = function (msg) {
	        if (this.parent) {
	            this.parent = null;
	        }
	        else if (this.isAttached) {
	            Widget.detach(this);
	        }
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onResize = function (msg) { };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onUpdateRequest = function (msg) { };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onFitRequest = function (msg) { };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onActivateRequest = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeShow = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterShow = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeHide = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-hide'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterHide = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeAttach = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterAttach = function (msg) { };
	    /**
	     * A message handler invoked on a `'before-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onBeforeDetach = function (msg) { };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onAfterDetach = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onChildAdded = function (msg) { };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     *
	     * #### Notes
	     * The default implementation of this handler is a no-op.
	     */
	    Widget.prototype.onChildRemoved = function (msg) { };
	    return Widget;
	}());
	exports.Widget = Widget;
	/**
	 * The namespace for the `Widget` class statics.
	 */
	(function (Widget) {
	    /**
	     * An enum of widget bit flags.
	     */
	    var Flag;
	    (function (Flag) {
	        /**
	         * The widget has been disposed.
	         */
	        Flag[Flag["IsDisposed"] = 1] = "IsDisposed";
	        /**
	         * The widget is attached to the DOM.
	         */
	        Flag[Flag["IsAttached"] = 2] = "IsAttached";
	        /**
	         * The widget is hidden.
	         */
	        Flag[Flag["IsHidden"] = 4] = "IsHidden";
	        /**
	         * The widget is visible.
	         */
	        Flag[Flag["IsVisible"] = 8] = "IsVisible";
	        /**
	         * A layout cannot be set on the widget.
	         */
	        Flag[Flag["DisallowLayout"] = 16] = "DisallowLayout";
	    })(Flag = Widget.Flag || (Widget.Flag = {}));
	    /**
	     * A collection of stateless messages related to widgets.
	     */
	    var Msg;
	    (function (Msg) {
	        /**
	         * A singleton `'before-show'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it becomes visible.
	         *
	         * This message is **not** sent when the widget is being attached.
	         */
	        Msg.BeforeShow = new messaging_1.Message('before-show');
	        /**
	         * A singleton `'after-show'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it becomes visible.
	         *
	         * This message is **not** sent when the widget is being attached.
	         */
	        Msg.AfterShow = new messaging_1.Message('after-show');
	        /**
	         * A singleton `'before-hide'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it becomes not-visible.
	         *
	         * This message is **not** sent when the widget is being detached.
	         */
	        Msg.BeforeHide = new messaging_1.Message('before-hide');
	        /**
	         * A singleton `'after-hide'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it becomes not-visible.
	         *
	         * This message is **not** sent when the widget is being detached.
	         */
	        Msg.AfterHide = new messaging_1.Message('after-hide');
	        /**
	         * A singleton `'before-attach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it is attached.
	         */
	        Msg.BeforeAttach = new messaging_1.Message('before-attach');
	        /**
	         * A singleton `'after-attach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it is attached.
	         */
	        Msg.AfterAttach = new messaging_1.Message('after-attach');
	        /**
	         * A singleton `'before-detach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget before it is detached.
	         */
	        Msg.BeforeDetach = new messaging_1.Message('before-detach');
	        /**
	         * A singleton `'after-detach'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget after it is detached.
	         */
	        Msg.AfterDetach = new messaging_1.Message('after-detach');
	        /**
	         * A singleton `'parent-changed'` message.
	         *
	         * #### Notes
	         * This message is sent to a widget when its parent has changed.
	         */
	        Msg.ParentChanged = new messaging_1.Message('parent-changed');
	        /**
	         * A singleton conflatable `'update-request'` message.
	         *
	         * #### Notes
	         * This message can be dispatched to supporting widgets in order to
	         * update their content based on the current widget state. Not all
	         * widgets will respond to messages of this type.
	         *
	         * For widgets with a layout, this message will inform the layout to
	         * update the position and size of its child widgets.
	         */
	        Msg.UpdateRequest = new messaging_1.ConflatableMessage('update-request');
	        /**
	         * A singleton conflatable `'fit-request'` message.
	         *
	         * #### Notes
	         * For widgets with a layout, this message will inform the layout to
	         * recalculate its size constraints to fit the space requirements of
	         * its child widgets, and to update their position and size. Not all
	         * layouts will respond to messages of this type.
	         */
	        Msg.FitRequest = new messaging_1.ConflatableMessage('fit-request');
	        /**
	         * A singleton conflatable `'activate-request'` message.
	         *
	         * #### Notes
	         * This message should be dispatched to a widget when it should
	         * perform the actions necessary to activate the widget, which
	         * may include focusing its node or descendant node.
	         */
	        Msg.ActivateRequest = new messaging_1.ConflatableMessage('activate-request');
	        /**
	         * A singleton conflatable `'close-request'` message.
	         *
	         * #### Notes
	         * This message should be dispatched to a widget when it should close
	         * and remove itself from the widget hierarchy.
	         */
	        Msg.CloseRequest = new messaging_1.ConflatableMessage('close-request');
	    })(Msg = Widget.Msg || (Widget.Msg = {}));
	    /**
	     * A message class for child related messages.
	     */
	    var ChildMessage = (function (_super) {
	        __extends(ChildMessage, _super);
	        /**
	         * Construct a new child message.
	         *
	         * @param type - The message type.
	         *
	         * @param child - The child widget for the message.
	         */
	        function ChildMessage(type, child) {
	            var _this = _super.call(this, type) || this;
	            _this.child = child;
	            return _this;
	        }
	        return ChildMessage;
	    }(messaging_1.Message));
	    Widget.ChildMessage = ChildMessage;
	    /**
	     * A message class for `'resize'` messages.
	     */
	    var ResizeMessage = (function (_super) {
	        __extends(ResizeMessage, _super);
	        /**
	         * Construct a new resize message.
	         *
	         * @param width - The **offset width** of the widget, or `-1` if
	         *   the width is not known.
	         *
	         * @param height - The **offset height** of the widget, or `-1` if
	         *   the height is not known.
	         */
	        function ResizeMessage(width, height) {
	            var _this = _super.call(this, 'resize') || this;
	            _this.width = width;
	            _this.height = height;
	            return _this;
	        }
	        return ResizeMessage;
	    }(messaging_1.Message));
	    Widget.ResizeMessage = ResizeMessage;
	    /**
	     * The namespace for the `ResizeMessage` class statics.
	     */
	    (function (ResizeMessage) {
	        /**
	         * A singleton `'resize'` message with an unknown size.
	         */
	        ResizeMessage.UnknownSize = new ResizeMessage(-1, -1);
	    })(ResizeMessage = Widget.ResizeMessage || (Widget.ResizeMessage = {}));
	    /**
	     * Attach a widget to a host DOM node.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param host - The DOM node to use as the widget's host.
	     *
	     * @param ref - The child of `host` to use as the reference element.
	     *   If this is provided, the widget will be inserted before this
	     *   node in the host. The default is `null`, which will cause the
	     *   widget to be added as the last child of the host.
	     *
	     * #### Notes
	     * This will throw an error if the widget is not a root widget, if
	     * the widget is already attached, or if the host is not attached
	     * to the DOM.
	     */
	    function attach(widget, host, ref) {
	        if (ref === void 0) { ref = null; }
	        if (widget.parent) {
	            throw new Error('Cannot attach a child widget.');
	        }
	        if (widget.isAttached || document.body.contains(widget.node)) {
	            throw new Error('Widget is already attached.');
	        }
	        if (!document.body.contains(host)) {
	            throw new Error('Host is not attached.');
	        }
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.BeforeAttach);
	        host.insertBefore(widget.node, ref);
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.AfterAttach);
	    }
	    Widget.attach = attach;
	    /**
	     * Detach the widget from its host DOM node.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * This will throw an error if the widget is not a root widget,
	     * or if the widget is not attached to the DOM.
	     */
	    function detach(widget) {
	        if (widget.parent) {
	            throw new Error('Cannot detach a child widget.');
	        }
	        if (!widget.isAttached || !document.body.contains(widget.node)) {
	            throw new Error('Widget is not attached.');
	        }
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.BeforeDetach);
	        widget.node.parentNode.removeChild(widget.node);
	        messaging_1.MessageLoop.sendMessage(widget, Widget.Msg.AfterDetach);
	    }
	    Widget.detach = detach;
	})(Widget = exports.Widget || (exports.Widget = {}));
	exports.Widget = Widget;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * An attached property for the widget title object.
	     */
	    Private.titleProperty = new properties_1.AttachedProperty({
	        name: 'title',
	        create: function (owner) { return new title_1.Title({ owner: owner }); },
	    });
	    /**
	     * Create a DOM node for the given widget options.
	     */
	    function createNode(options) {
	        return options.node || document.createElement('div');
	    }
	    Private.createNode = createNode;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/widget.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/title.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/title.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	/**
	 * An object which holds data related to an object's title.
	 *
	 * #### Notes
	 * A title object is intended to hold the data necessary to display a
	 * header for a particular object. A common example is the `TabPanel`,
	 * which uses the widget title to populate the tab for a child widget.
	 */
	var Title = (function () {
	    /**
	     * Construct a new title.
	     *
	     * @param options - The options for initializing the title.
	     */
	    function Title(options) {
	        this._label = '';
	        this._caption = '';
	        this._mnemonic = -1;
	        this._iconClass = '';
	        this._iconLabel = '';
	        this._className = '';
	        this._closable = false;
	        this._changed = new signaling_1.Signal(this);
	        this.owner = options.owner;
	        if (options.label !== undefined) {
	            this._label = options.label;
	        }
	        if (options.mnemonic !== undefined) {
	            this._mnemonic = options.mnemonic;
	        }
	        if (options.icon !== undefined) {
	            this._iconClass = options.icon;
	        }
	        if (options.iconClass !== undefined) {
	            this._iconClass = options.iconClass;
	        }
	        if (options.iconLabel !== undefined) {
	            this._iconLabel = options.iconLabel;
	        }
	        if (options.caption !== undefined) {
	            this._caption = options.caption;
	        }
	        if (options.className !== undefined) {
	            this._className = options.className;
	        }
	        if (options.closable !== undefined) {
	            this._closable = options.closable;
	        }
	        this._dataset = options.dataset || {};
	    }
	    Object.defineProperty(Title.prototype, "changed", {
	        /**
	         * A signal emitted when the state of the title changes.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "label", {
	        /**
	         * Get the label for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._label;
	        },
	        /**
	         * Set the label for the title.
	         */
	        set: function (value) {
	            if (this._label === value) {
	                return;
	            }
	            this._label = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "mnemonic", {
	        /**
	         * Get the mnemonic index for the title.
	         *
	         * #### Notes
	         * The default value is `-1`.
	         */
	        get: function () {
	            return this._mnemonic;
	        },
	        /**
	         * Set the mnemonic index for the title.
	         */
	        set: function (value) {
	            if (this._mnemonic === value) {
	                return;
	            }
	            this._mnemonic = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "icon", {
	        /**
	         * @deprecated Use `iconClass` instead.
	         */
	        get: function () {
	            return this.iconClass;
	        },
	        /**
	         * @deprecated Use `iconClass` instead.
	         */
	        set: function (value) {
	            this.iconClass = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "iconClass", {
	        /**
	         * Get the icon class name for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._iconClass;
	        },
	        /**
	         * Set the icon class name for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            if (this._iconClass === value) {
	                return;
	            }
	            this._iconClass = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "iconLabel", {
	        /**
	         * Get the icon label for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._iconLabel;
	        },
	        /**
	         * Set the icon label for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            if (this._iconLabel === value) {
	                return;
	            }
	            this._iconLabel = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "caption", {
	        /**
	         * Get the caption for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._caption;
	        },
	        /**
	         * Set the caption for the title.
	         */
	        set: function (value) {
	            if (this._caption === value) {
	                return;
	            }
	            this._caption = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "className", {
	        /**
	         * Get the extra class name for the title.
	         *
	         * #### Notes
	         * The default value is an empty string.
	         */
	        get: function () {
	            return this._className;
	        },
	        /**
	         * Set the extra class name for the title.
	         *
	         * #### Notes
	         * Multiple class names can be separated with whitespace.
	         */
	        set: function (value) {
	            if (this._className === value) {
	                return;
	            }
	            this._className = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "closable", {
	        /**
	         * Get the closable state for the title.
	         *
	         * #### Notes
	         * The default value is `false`.
	         */
	        get: function () {
	            return this._closable;
	        },
	        /**
	         * Set the closable state for the title.
	         *
	         * #### Notes
	         * This controls the presence of a close icon when applicable.
	         */
	        set: function (value) {
	            if (this._closable === value) {
	                return;
	            }
	            this._closable = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Title.prototype, "dataset", {
	        /**
	         * Get the dataset for the title.
	         *
	         * #### Notes
	         * The default value is an empty dataset.
	         */
	        get: function () {
	            return this._dataset;
	        },
	        /**
	         * Set the dataset for the title.
	         *
	         * #### Notes
	         * This controls the data attributes when applicable.
	         */
	        set: function (value) {
	            if (this._dataset === value) {
	                return;
	            }
	            this._dataset = value;
	            this._changed.emit(undefined);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return Title;
	}());
	exports.Title = Title;
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/title.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/panellayout.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/panellayout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var layout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/layout.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A concrete layout implementation suitable for many use cases.
	 *
	 * #### Notes
	 * This class is suitable as a base class for implementing a variety of
	 * layouts, but can also be used directly with standard CSS to layout a
	 * collection of widgets.
	 */
	var PanelLayout = (function (_super) {
	    __extends(PanelLayout, _super);
	    function PanelLayout() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._widgets = [];
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This will clear and dispose all widgets in the layout.
	     *
	     * All reimplementations should call the superclass method.
	     *
	     * This method is called automatically when the parent is disposed.
	     */
	    PanelLayout.prototype.dispose = function () {
	        while (this._widgets.length > 0) {
	            this._widgets.pop().dispose();
	        }
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(PanelLayout.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the layout.
	         */
	        get: function () {
	            return this._widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the widgets in the layout.
	     *
	     * @returns A new iterator over the widgets in the layout.
	     */
	    PanelLayout.prototype.iter = function () {
	        return algorithm_1.iter(this._widgets);
	    };
	    /**
	     * Add a widget to the end of the layout.
	     *
	     * @param widget - The widget to add to the layout.
	     *
	     * #### Notes
	     * If the widget is already contained in the layout, it will be moved.
	     */
	    PanelLayout.prototype.addWidget = function (widget) {
	        this.insertWidget(this._widgets.length, widget);
	    };
	    /**
	     * Insert a widget into the layout at the specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into the layout.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the widgets.
	     *
	     * If the widget is already added to the layout, it will be moved.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    PanelLayout.prototype.insertWidget = function (index, widget) {
	        // Remove the widget from its current parent. This is a no-op
	        // if the widget's parent is already the layout parent widget.
	        widget.parent = this.parent;
	        // Look up the current index of the widget.
	        var i = this._widgets.indexOf(widget);
	        // Clamp the insert index to the array bounds.
	        var j = Math.max(0, Math.min(index, this._widgets.length));
	        // If the widget is not in the array, insert it.
	        if (i === -1) {
	            // Insert the widget into the array.
	            algorithm_1.ArrayExt.insert(this._widgets, j, widget);
	            // If the layout is parented, attach the widget to the DOM.
	            if (this.parent) {
	                this.attachWidget(j, widget);
	            }
	            // There is nothing more to do.
	            return;
	        }
	        // Otherwise, the widget exists in the array and should be moved.
	        // Adjust the index if the location is at the end of the array.
	        if (j === this._widgets.length) {
	            j--;
	        }
	        // Bail if there is no effective move.
	        if (i === j) {
	            return;
	        }
	        // Move the widget to the new location.
	        algorithm_1.ArrayExt.move(this._widgets, i, j);
	        // If the layout is parented, move the widget in the DOM.
	        if (this.parent) {
	            this.moveWidget(i, j, widget);
	        }
	    };
	    /**
	     * Remove a widget from the layout.
	     *
	     * @param widget - The widget to remove from the layout.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     */
	    PanelLayout.prototype.removeWidget = function (widget) {
	        this.removeWidgetAt(this._widgets.indexOf(widget));
	    };
	    /**
	     * Remove the widget at a given index from the layout.
	     *
	     * @param index - The index of the widget to remove.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    PanelLayout.prototype.removeWidgetAt = function (index) {
	        // Remove the widget from the array.
	        var widget = algorithm_1.ArrayExt.removeAt(this._widgets, index);
	        // If the layout is parented, detach the widget from the DOM.
	        if (widget && this.parent) {
	            this.detachWidget(index, widget);
	        }
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    PanelLayout.prototype.init = function () {
	        var _this = this;
	        _super.prototype.init.call(this);
	        algorithm_1.each(this, function (widget, index) {
	            _this.attachWidget(index, widget);
	        });
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This method is called automatically by the panel layout at the
	     * appropriate time. It should not be called directly by user code.
	     *
	     * The default implementation adds the widgets's node to the parent's
	     * node at the proper location, and sends the appropriate attach
	     * messages to the widget if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the widget's
	     * node is added to the parent's node.
	     */
	    PanelLayout.prototype.attachWidget = function (index, widget) {
	        // Look up the next sibling reference node.
	        var ref = this.parent.node.children[index];
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Insert the widget's node before the sibling.
	        this.parent.node.insertBefore(widget.node, ref);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This method is called automatically by the panel layout at the
	     * appropriate time. It should not be called directly by user code.
	     *
	     * The default implementation moves the widget's node to the proper
	     * location in the parent's node and sends the appropriate attach and
	     * detach messages to the widget if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the widget's
	     * node is moved in the parent's node.
	     */
	    PanelLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` and  message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Look up the next sibling reference node.
	        var ref = this.parent.node.children[toIndex];
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Insert the widget's node before the sibling.
	        this.parent.node.insertBefore(widget.node, ref);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This method is called automatically by the panel layout at the
	     * appropriate time. It should not be called directly by user code.
	     *
	     * The default implementation removes the widget's node from the
	     * parent's node, and sends the appropriate detach messages to the
	     * widget if the parent is attached to the DOM.
	     *
	     * Subclasses may reimplement this method to control how the widget's
	     * node is removed from the parent's node.
	     */
	    PanelLayout.prototype.detachWidget = function (index, widget) {
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	    };
	    return PanelLayout;
	}(layout_1.Layout));
	exports.PanelLayout = PanelLayout;
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/panellayout.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/boxpanel.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/boxpanel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var boxlayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/boxlayout.js');
	var panel_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/panel.js');
	/**
	 * A panel which arranges its widgets in a single row or column.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[BoxLayout]].
	 */
	var BoxPanel = (function (_super) {
	    __extends(BoxPanel, _super);
	    /**
	     * Construct a new box panel.
	     *
	     * @param options - The options for initializing the box panel.
	     */
	    function BoxPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { layout: Private.createLayout(options) }) || this;
	        _this.addClass('p-BoxPanel');
	        return _this;
	    }
	    Object.defineProperty(BoxPanel.prototype, "direction", {
	        /**
	         * Get the layout direction for the box panel.
	         */
	        get: function () {
	            return this.layout.direction;
	        },
	        /**
	         * Set the layout direction for the box panel.
	         */
	        set: function (value) {
	            this.layout.direction = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxPanel.prototype, "alignment", {
	        /**
	         * Get the content alignment for the box panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        get: function () {
	            return this.layout.alignment;
	        },
	        /**
	         * Set the content alignment for the box panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire box layout.
	         */
	        set: function (value) {
	            this.layout.alignment = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(BoxPanel.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the box panel.
	         */
	        get: function () {
	            return this.layout.spacing;
	        },
	        /**
	         * Set the inter-element spacing for the box panel.
	         */
	        set: function (value) {
	            this.layout.spacing = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    BoxPanel.prototype.onChildAdded = function (msg) {
	        msg.child.addClass('p-BoxPanel-child');
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    BoxPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass('p-BoxPanel-child');
	    };
	    return BoxPanel;
	}(panel_1.Panel));
	exports.BoxPanel = BoxPanel;
	/**
	 * The namespace for the `BoxPanel` class statics.
	 */
	(function (BoxPanel) {
	    /**
	     * Get the box panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box panel stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return boxlayout_1.BoxLayout.getStretch(widget);
	    }
	    BoxPanel.getStretch = getStretch;
	    /**
	     * Set the box panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        boxlayout_1.BoxLayout.setStretch(widget, value);
	    }
	    BoxPanel.setStretch = setStretch;
	    /**
	     * Get the box panel size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The box panel size basis for the widget.
	     */
	    function getSizeBasis(widget) {
	        return boxlayout_1.BoxLayout.getSizeBasis(widget);
	    }
	    BoxPanel.getSizeBasis = getSizeBasis;
	    /**
	     * Set the box panel size basis for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the size basis.
	     */
	    function setSizeBasis(widget, value) {
	        boxlayout_1.BoxLayout.setSizeBasis(widget, value);
	    }
	    BoxPanel.setSizeBasis = setSizeBasis;
	})(BoxPanel = exports.BoxPanel || (exports.BoxPanel = {}));
	exports.BoxPanel = BoxPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a box layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new boxlayout_1.BoxLayout(options);
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/boxpanel.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/panel.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/panel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var panellayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/panellayout.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A simple and convenient panel widget class.
	 *
	 * #### Notes
	 * This class is suitable as a base class for implementing a variety of
	 * convenience panel widgets, but can also be used directly with CSS to
	 * arrange a collection of widgets.
	 *
	 * This class provides a convenience wrapper around a [[PanelLayout]].
	 */
	var Panel = (function (_super) {
	    __extends(Panel, _super);
	    /**
	     * Construct a new panel.
	     *
	     * @param options - The options for initializing the panel.
	     */
	    function Panel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this.addClass('p-Panel');
	        _this.layout = Private.createLayout(options);
	        return _this;
	    }
	    Object.defineProperty(Panel.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the panel.
	         */
	        get: function () {
	            return this.layout.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a widget to the end of the panel.
	     *
	     * @param widget - The widget to add to the panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     */
	    Panel.prototype.addWidget = function (widget) {
	        this.layout.addWidget(widget);
	    };
	    /**
	     * Insert a widget at the specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     */
	    Panel.prototype.insertWidget = function (index, widget) {
	        this.layout.insertWidget(index, widget);
	    };
	    return Panel;
	}(widget_1.Widget));
	exports.Panel = Panel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a panel layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new panellayout_1.PanelLayout();
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/panel.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/commandpalette.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/commandpalette.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.1.1/lib/index.js');
	var commands_1 = __jupyter_require__('@phosphor/commands@^1.2.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var virtualdom_1 = __jupyter_require__('@phosphor/virtualdom@^1.1.1/lib/index.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A widget which displays command items as a searchable palette.
	 */
	var CommandPalette = (function (_super) {
	    __extends(CommandPalette, _super);
	    /**
	     * Construct a new command palette.
	     *
	     * @param options - The options for initializing the palette.
	     */
	    function CommandPalette(options) {
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._activeIndex = -1;
	        _this._items = [];
	        _this._results = null;
	        _this.addClass('p-CommandPalette');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.commands = options.commands;
	        _this.renderer = options.renderer || CommandPalette.defaultRenderer;
	        _this.commands.commandChanged.connect(_this._onGenericChange, _this);
	        _this.commands.keyBindingChanged.connect(_this._onGenericChange, _this);
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    CommandPalette.prototype.dispose = function () {
	        this._items.length = 0;
	        this._results = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(CommandPalette.prototype, "searchNode", {
	        /**
	         * The command palette search node.
	         *
	         * #### Notes
	         * This is the node which contains the search-related elements.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-CommandPalette-search')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "inputNode", {
	        /**
	         * The command palette input node.
	         *
	         * #### Notes
	         * This is the actual input node for the search area.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-CommandPalette-input')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "contentNode", {
	        /**
	         * The command palette content node.
	         *
	         * #### Notes
	         * This is the node which holds the command item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-CommandPalette-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandPalette.prototype, "items", {
	        /**
	         * A read-only array of the command items in the palette.
	         */
	        get: function () {
	            return this._items;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a command item to the command palette.
	     *
	     * @param options - The options for creating the command item.
	     *
	     * @returns The command item added to the palette.
	     */
	    CommandPalette.prototype.addItem = function (options) {
	        // Create a new command item for the options.
	        var item = Private.createItem(this.commands, options);
	        // Add the item to the array.
	        this._items.push(item);
	        // Refresh the search results.
	        this.refresh();
	        // Return the item added to the palette.
	        return item;
	    };
	    /**
	     * Remove an item from the command palette.
	     *
	     * @param item - The item to remove from the palette.
	     *
	     * #### Notes
	     * This is a no-op if the item is not in the palette.
	     */
	    CommandPalette.prototype.removeItem = function (item) {
	        this.removeItemAt(this._items.indexOf(item));
	    };
	    /**
	     * Remove the item at a given index from the command palette.
	     *
	     * @param index - The index of the item to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    CommandPalette.prototype.removeItemAt = function (index) {
	        // Remove the item from the array.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Bail if the index is out of range.
	        if (!item) {
	            return;
	        }
	        // Refresh the search results.
	        this.refresh();
	    };
	    /**
	     * Remove all items from the command palette.
	     */
	    CommandPalette.prototype.clearItems = function () {
	        // Bail if there is nothing to remove.
	        if (this._items.length === 0) {
	            return;
	        }
	        // Clear the array of items.
	        this._items.length = 0;
	        // Refresh the search results.
	        this.refresh();
	    };
	    /**
	     * Clear the search results and schedule an update.
	     *
	     * #### Notes
	     * This should be called whenever the search results of the palette
	     * should be updated.
	     *
	     * This is typically called automatically by the palette as needed,
	     * but can be called manually if the input text is programatically
	     * changed.
	     *
	     * The rendered results are updated asynchronously.
	     */
	    CommandPalette.prototype.refresh = function () {
	        this._results = null;
	        this.update();
	    };
	    /**
	     * Handle the DOM events for the command palette.
	     *
	     * @param event - The DOM event sent to the command palette.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the command palette's DOM node.
	     * It should not be called directly by user code.
	     */
	    CommandPalette.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'input':
	                this.refresh();
	                break;
	            case 'focus':
	            case 'blur':
	                this._toggleFocused();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    CommandPalette.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('click', this);
	        this.node.addEventListener('keydown', this);
	        this.node.addEventListener('input', this);
	        this.node.addEventListener('focus', this, true);
	        this.node.addEventListener('blur', this, true);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    CommandPalette.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('click', this);
	        this.node.removeEventListener('keydown', this);
	        this.node.removeEventListener('input', this);
	        this.node.removeEventListener('focus', this, true);
	        this.node.removeEventListener('blur', this, true);
	    };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     */
	    CommandPalette.prototype.onActivateRequest = function (msg) {
	        if (this.isAttached) {
	            var input = this.inputNode;
	            input.focus();
	            input.select();
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    CommandPalette.prototype.onUpdateRequest = function (msg) {
	        // Fetch the current query text and content node.
	        var query = this.inputNode.value;
	        var contentNode = this.contentNode;
	        // Ensure the search results are generated.
	        var results = this._results;
	        if (!results) {
	            // Generate and store the new search results.
	            results = this._results = Private.search(this._items, query);
	            // Reset the active index.
	            this._activeIndex = (query ? algorithm_1.ArrayExt.findFirstIndex(results, Private.canActivate) : -1);
	        }
	        // If there is no query and no results, clear the content.
	        if (!query && results.length === 0) {
	            virtualdom_1.VirtualDOM.render(null, contentNode);
	            return;
	        }
	        // If the is a query but no results, render the empty message.
	        if (query && results.length === 0) {
	            var content_1 = this.renderer.renderEmptyMessage({ query: query });
	            virtualdom_1.VirtualDOM.render(content_1, contentNode);
	            return;
	        }
	        // Create the render content for the search results.
	        var renderer = this.renderer;
	        var activeIndex = this._activeIndex;
	        var content = new Array(results.length);
	        for (var i = 0, n = results.length; i < n; ++i) {
	            var result = results[i];
	            if (result.type === 'header') {
	                var indices = result.indices;
	                var category = result.category;
	                content[i] = renderer.renderHeader({ category: category, indices: indices });
	            }
	            else {
	                var item = result.item;
	                var indices = result.indices;
	                var active = i === activeIndex;
	                content[i] = renderer.renderItem({ item: item, indices: indices, active: active });
	            }
	        }
	        // Render the search result content.
	        virtualdom_1.VirtualDOM.render(content, contentNode);
	        // Adjust the scroll position as needed.
	        if (activeIndex < 0 || activeIndex >= results.length) {
	            contentNode.scrollTop = 0;
	        }
	        else {
	            var element = contentNode.children[activeIndex];
	            domutils_1.ElementExt.scrollIntoViewIfNeeded(contentNode, element);
	        }
	    };
	    /**
	     * Handle the `'click'` event for the command palette.
	     */
	    CommandPalette.prototype._evtClick = function (event) {
	        // Bail if the click is not the left button.
	        if (event.button !== 0) {
	            return;
	        }
	        // Find the index of the item which was clicked.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return node.contains(event.target);
	        });
	        // Bail if the click was not on an item.
	        if (index === -1) {
	            return;
	        }
	        // Kill the event when a content item is clicked.
	        event.preventDefault();
	        event.stopPropagation();
	        // Execute the item if possible.
	        this._execute(index);
	    };
	    /**
	     * Handle the `'keydown'` event for the command palette.
	     */
	    CommandPalette.prototype._evtKeyDown = function (event) {
	        if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
	            return;
	        }
	        switch (event.keyCode) {
	            case 13:
	                event.preventDefault();
	                event.stopPropagation();
	                this._execute(this._activeIndex);
	                break;
	            case 38:
	                event.preventDefault();
	                event.stopPropagation();
	                this._activatePreviousItem();
	                break;
	            case 40:
	                event.preventDefault();
	                event.stopPropagation();
	                this._activateNextItem();
	                break;
	        }
	    };
	    /**
	     * Activate the next enabled command item.
	     */
	    CommandPalette.prototype._activateNextItem = function () {
	        // Bail if there are no search results.
	        if (!this._results || this._results.length === 0) {
	            return;
	        }
	        // Find the next enabled item index.
	        var ai = this._activeIndex;
	        var n = this._results.length;
	        var start = ai < n - 1 ? ai + 1 : 0;
	        var stop = start === 0 ? n - 1 : start - 1;
	        this._activeIndex = algorithm_1.ArrayExt.findFirstIndex(this._results, Private.canActivate, start, stop);
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Activate the previous enabled command item.
	     */
	    CommandPalette.prototype._activatePreviousItem = function () {
	        // Bail if there are no search results.
	        if (!this._results || this._results.length === 0) {
	            return;
	        }
	        // Find the previous enabled item index.
	        var ai = this._activeIndex;
	        var n = this._results.length;
	        var start = ai <= 0 ? n - 1 : ai - 1;
	        var stop = start === n - 1 ? 0 : start + 1;
	        this._activeIndex = algorithm_1.ArrayExt.findLastIndex(this._results, Private.canActivate, start, stop);
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Execute the command item at the given index, if possible.
	     */
	    CommandPalette.prototype._execute = function (index) {
	        // Bail if there are no search results.
	        if (!this._results) {
	            return;
	        }
	        // Bail if the index is out of range.
	        var part = this._results[index];
	        if (!part) {
	            return;
	        }
	        // Update the search text if the item is a header.
	        if (part.type === 'header') {
	            var input = this.inputNode;
	            input.value = part.category.toLowerCase() + " ";
	            input.focus();
	            this.refresh();
	            return;
	        }
	        // Bail if item is not enabled.
	        if (!part.item.isEnabled) {
	            return;
	        }
	        // Execute the item.
	        this.commands.execute(part.item.command, part.item.args);
	        // Clear the query text.
	        this.inputNode.value = '';
	        // Refresh the search results.
	        this.refresh();
	    };
	    /**
	     * Toggle the focused modifier based on the input node focus state.
	     */
	    CommandPalette.prototype._toggleFocused = function () {
	        var focused = document.activeElement === this.inputNode;
	        this.toggleClass('p-mod-focused', focused);
	    };
	    /**
	     * A signal handler for generic command changes.
	     */
	    CommandPalette.prototype._onGenericChange = function () {
	        this.refresh();
	    };
	    return CommandPalette;
	}(widget_1.Widget));
	exports.CommandPalette = CommandPalette;
	/**
	 * The namespace for the `CommandPalette` class statics.
	 */
	(function (CommandPalette) {
	    /**
	     * The default implementation of `IRenderer`.
	     */
	    var Renderer = (function () {
	        function Renderer() {
	        }
	        /**
	         * Render the virtual element for a command palette header.
	         *
	         * @param data - The data to use for rendering the header.
	         *
	         * @returns A virtual element representing the header.
	         */
	        Renderer.prototype.renderHeader = function (data) {
	            var content = this.formatHeader(data);
	            return virtualdom_1.h.li({ className: 'p-CommandPalette-header' }, content);
	        };
	        /**
	         * Render the virtual element for a command palette item.
	         *
	         * @param data - The data to use for rendering the item.
	         *
	         * @returns A virtual element representing the item.
	         */
	        Renderer.prototype.renderItem = function (data) {
	            var className = this.createItemClass(data);
	            var dataset = this.createItemDataset(data);
	            return (virtualdom_1.h.li({ className: className, dataset: dataset }, this.renderItemShortcut(data), this.renderItemLabel(data), this.renderItemCaption(data)));
	        };
	        /**
	         * Render the empty results message for a command palette.
	         *
	         * @param data - The data to use for rendering the message.
	         *
	         * @returns A virtual element representing the message.
	         */
	        Renderer.prototype.renderEmptyMessage = function (data) {
	            var content = this.formatEmptyMessage(data);
	            return virtualdom_1.h.li({ className: 'p-CommandPalette-emptyMessage' }, content);
	        };
	        /**
	         * Render the shortcut for a command palette item.
	         *
	         * @param data - The data to use for rendering the shortcut.
	         *
	         * @returns A virtual element representing the shortcut.
	         */
	        Renderer.prototype.renderItemShortcut = function (data) {
	            var content = this.formatItemShortcut(data);
	            return virtualdom_1.h.div({ className: 'p-CommandPalette-itemShortcut' }, content);
	        };
	        /**
	         * Render the label for a command palette item.
	         *
	         * @param data - The data to use for rendering the label.
	         *
	         * @returns A virtual element representing the label.
	         */
	        Renderer.prototype.renderItemLabel = function (data) {
	            var content = this.formatItemLabel(data);
	            return virtualdom_1.h.div({ className: 'p-CommandPalette-itemLabel' }, content);
	        };
	        /**
	         * Render the caption for a command palette item.
	         *
	         * @param data - The data to use for rendering the caption.
	         *
	         * @returns A virtual element representing the caption.
	         */
	        Renderer.prototype.renderItemCaption = function (data) {
	            var content = this.formatItemCaption(data);
	            return virtualdom_1.h.div({ className: 'p-CommandPalette-itemCaption' }, content);
	        };
	        /**
	         * Create the class name for the command palette item.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the command palette item.
	         */
	        Renderer.prototype.createItemClass = function (data) {
	            // Set up the initial class name.
	            var name = 'p-CommandPalette-item';
	            // Add the boolean state classes.
	            if (!data.item.isEnabled) {
	                name += ' p-mod-disabled';
	            }
	            if (data.item.isToggled) {
	                name += ' p-mod-toggled';
	            }
	            if (data.active) {
	                name += ' p-mod-active';
	            }
	            // Add the extra class.
	            var extra = data.item.className;
	            if (extra) {
	                name += " " + extra;
	            }
	            // Return the complete class name.
	            return name;
	        };
	        /**
	         * Create the dataset for the command palette item.
	         *
	         * @param data - The data to use for creating the dataset.
	         *
	         * @returns The dataset for the command palette item.
	         */
	        Renderer.prototype.createItemDataset = function (data) {
	            return __assign({}, data.item.dataset, { command: data.item.command });
	        };
	        /**
	         * Create the render content for the header node.
	         *
	         * @param data - The data to use for the header content.
	         *
	         * @returns The content to add to the header node.
	         */
	        Renderer.prototype.formatHeader = function (data) {
	            if (!data.indices || data.indices.length === 0) {
	                return data.category;
	            }
	            return algorithm_1.StringExt.highlight(data.category, data.indices, virtualdom_1.h.mark);
	        };
	        /**
	         * Create the render content for the empty message node.
	         *
	         * @param data - The data to use for the empty message content.
	         *
	         * @returns The content to add to the empty message node.
	         */
	        Renderer.prototype.formatEmptyMessage = function (data) {
	            return "No commands found that match '" + data.query + "'";
	        };
	        /**
	         * Create the render content for the item shortcut node.
	         *
	         * @param data - The data to use for the shortcut content.
	         *
	         * @returns The content to add to the shortcut node.
	         */
	        Renderer.prototype.formatItemShortcut = function (data) {
	            var kb = data.item.keyBinding;
	            return kb ? kb.keys.map(Private.formatKeystroke).join(', ') : null;
	        };
	        /**
	         * Create the render content for the item label node.
	         *
	         * @param data - The data to use for the label content.
	         *
	         * @returns The content to add to the label node.
	         */
	        Renderer.prototype.formatItemLabel = function (data) {
	            if (!data.indices || data.indices.length === 0) {
	                return data.item.label;
	            }
	            return algorithm_1.StringExt.highlight(data.item.label, data.indices, virtualdom_1.h.mark);
	        };
	        /**
	         * Create the render content for the item caption node.
	         *
	         * @param data - The data to use for the caption content.
	         *
	         * @returns The content to add to the caption node.
	         */
	        Renderer.prototype.formatItemCaption = function (data) {
	            return data.item.caption;
	        };
	        return Renderer;
	    }());
	    CommandPalette.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    CommandPalette.defaultRenderer = new Renderer();
	})(CommandPalette = exports.CommandPalette || (exports.CommandPalette = {}));
	exports.CommandPalette = CommandPalette;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the DOM node for a command palette.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var search = document.createElement('div');
	        var wrapper = document.createElement('div');
	        var input = document.createElement('input');
	        var content = document.createElement('ul');
	        search.className = 'p-CommandPalette-search';
	        wrapper.className = 'p-CommandPalette-wrapper';
	        input.className = 'p-CommandPalette-input';
	        content.className = 'p-CommandPalette-content';
	        input.spellcheck = false;
	        wrapper.appendChild(input);
	        search.appendChild(wrapper);
	        node.appendChild(search);
	        node.appendChild(content);
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Create a new command item from a command registry and options.
	     */
	    function createItem(commands, options) {
	        return new CommandItem(commands, options);
	    }
	    Private.createItem = createItem;
	    /**
	     * Format a keystroke for display on the local system.
	     */
	    function formatKeystroke(keystroke) {
	        var mods = '';
	        var parts = commands_1.CommandRegistry.parseKeystroke(keystroke);
	        if (domutils_1.Platform.IS_MAC) {
	            if (parts.ctrl) {
	                mods += '\u2303 ';
	            }
	            if (parts.alt) {
	                mods += '\u2325 ';
	            }
	            if (parts.shift) {
	                mods += '\u21E7 ';
	            }
	            if (parts.cmd) {
	                mods += '\u2318 ';
	            }
	        }
	        else {
	            if (parts.ctrl) {
	                mods += 'Ctrl+';
	            }
	            if (parts.alt) {
	                mods += 'Alt+';
	            }
	            if (parts.shift) {
	                mods += 'Shift+';
	            }
	        }
	        return mods + parts.key;
	    }
	    Private.formatKeystroke = formatKeystroke;
	    /**
	     * Search an array of command items for fuzzy matches.
	     */
	    function search(items, query) {
	        // Fuzzy match the items for the query.
	        var scores = matchItems(items, query);
	        // Sort the items based on their score.
	        scores.sort(scoreCmp);
	        // Create the results for the search.
	        return createResults(scores);
	    }
	    Private.search = search;
	    /**
	     * Test whether a result item can be activated.
	     */
	    function canActivate(result) {
	        return result.type === 'item' && result.item.isEnabled;
	    }
	    Private.canActivate = canActivate;
	    /**
	     * Normalize a category for a command item.
	     */
	    function normalizeCategory(category) {
	        return category.trim().replace(/\s+/g, ' ');
	    }
	    /**
	     * Normalize the query text for a fuzzy search.
	     */
	    function normalizeQuery(text) {
	        return text.replace(/\s+/g, '').toLowerCase();
	    }
	    /**
	     * Perform a fuzzy match on an array of command items.
	     */
	    function matchItems(items, query) {
	        // Normalize the query text to lower case with no whitespace.
	        query = normalizeQuery(query);
	        // Create the array to hold the scores.
	        var scores = [];
	        // Iterate over the items and match against the query.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Ignore items which are not visible.
	            var item = items[i];
	            if (!item.isVisible) {
	                continue;
	            }
	            // If the query is empty, all items are matched by default.
	            if (!query) {
	                scores.push({
	                    matchType: 3 /* Default */,
	                    categoryIndices: null,
	                    labelIndices: null,
	                    score: 0, item: item
	                });
	                continue;
	            }
	            // Run the fuzzy search for the item and query.
	            var score = fuzzySearch(item, query);
	            // Ignore the item if it is not a match.
	            if (!score) {
	                continue;
	            }
	            // Penalize disabled items.
	            // TODO - push disabled items all the way down in sort cmp?
	            if (!item.isEnabled) {
	                score.score += 1000;
	            }
	            // Add the score to the results.
	            scores.push(score);
	        }
	        // Return the final array of scores.
	        return scores;
	    }
	    /**
	     * Perform a fuzzy search on a single command item.
	     */
	    function fuzzySearch(item, query) {
	        // Create the source text to be searched.
	        var category = item.category.toLowerCase();
	        var label = item.label.toLowerCase();
	        var source = category + " " + label;
	        // Set up the match score and indices array.
	        var score = Infinity;
	        var indices = null;
	        // The regex for search word boundaries
	        var rgx = /\b\w/g;
	        // Search the source by word boundary.
	        while (true) {
	            // Find the next word boundary in the source.
	            var rgxMatch = rgx.exec(source);
	            // Break if there is no more source context.
	            if (!rgxMatch) {
	                break;
	            }
	            // Run the string match on the relevant substring.
	            var match = algorithm_1.StringExt.matchSumOfDeltas(source, query, rgxMatch.index);
	            // Break if there is no match.
	            if (!match) {
	                break;
	            }
	            // Update the match if the score is better.
	            if (match && match.score <= score) {
	                score = match.score;
	                indices = match.indices;
	            }
	        }
	        // Bail if there was no match.
	        if (!indices || score === Infinity) {
	            return null;
	        }
	        // Compute the pivot index between category and label text.
	        var pivot = category.length + 1;
	        // Find the slice index to separate matched indices.
	        var j = algorithm_1.ArrayExt.lowerBound(indices, pivot, function (a, b) { return a - b; });
	        // Extract the matched category and label indices.
	        var categoryIndices = indices.slice(0, j);
	        var labelIndices = indices.slice(j);
	        // Adjust the label indices for the pivot offset.
	        for (var i = 0, n = labelIndices.length; i < n; ++i) {
	            labelIndices[i] -= pivot;
	        }
	        // Handle a pure label match.
	        if (categoryIndices.length === 0) {
	            return {
	                matchType: 0 /* Label */,
	                categoryIndices: null,
	                labelIndices: labelIndices,
	                score: score, item: item
	            };
	        }
	        // Handle a pure category match.
	        if (labelIndices.length === 0) {
	            return {
	                matchType: 1 /* Category */,
	                categoryIndices: categoryIndices,
	                labelIndices: null,
	                score: score, item: item
	            };
	        }
	        // Handle a split match.
	        return {
	            matchType: 2 /* Split */,
	            categoryIndices: categoryIndices,
	            labelIndices: labelIndices,
	            score: score, item: item
	        };
	    }
	    /**
	     * A sort comparison function for a match score.
	     */
	    function scoreCmp(a, b) {
	        // First compare based on the match type
	        var m1 = a.matchType - b.matchType;
	        if (m1 !== 0) {
	            return m1;
	        }
	        // Otherwise, compare based on the match score.
	        var d1 = a.score - b.score;
	        if (d1 !== 0) {
	            return d1;
	        }
	        // Find the match index based on the match type.
	        var i1 = 0;
	        var i2 = 0;
	        switch (a.matchType) {
	            case 0 /* Label */:
	                i1 = a.labelIndices[0];
	                i2 = b.labelIndices[0];
	                break;
	            case 1 /* Category */:
	            case 2 /* Split */:
	                i1 = a.categoryIndices[0];
	                i2 = b.categoryIndices[0];
	                break;
	        }
	        // Compare based on the match index.
	        if (i1 !== i2) {
	            return i1 - i2;
	        }
	        // Otherwise, compare by category.
	        var d2 = a.item.category.localeCompare(b.item.category);
	        if (d2 !== 0) {
	            return d2;
	        }
	        // Otherwise, compare by rank.
	        var r1 = a.item.rank;
	        var r2 = b.item.rank;
	        if (r1 !== r2) {
	            return r1 < r2 ? -1 : 1; // Infinity safe
	        }
	        // Finally, compare by label.
	        return a.item.label.localeCompare(b.item.label);
	    }
	    /**
	     * Create the results from an array of sorted scores.
	     */
	    function createResults(scores) {
	        // Set up an array to track which scores have been visited.
	        var visited = new Array(scores.length);
	        algorithm_1.ArrayExt.fill(visited, false);
	        // Set up the search results array.
	        var results = [];
	        // Iterate over each score in the array.
	        for (var i = 0, n = scores.length; i < n; ++i) {
	            // Ignore a score which has already been processed.
	            if (visited[i]) {
	                continue;
	            }
	            // Extract the current item and indices.
	            var _a = scores[i], item = _a.item, categoryIndices = _a.categoryIndices;
	            // Extract the category for the current item.
	            var category = item.category;
	            // Add the header result for the category.
	            results.push({ type: 'header', category: category, indices: categoryIndices });
	            // Find the rest of the scores with the same category.
	            for (var j = i; j < n; ++j) {
	                // Ignore a score which has already been processed.
	                if (visited[j]) {
	                    continue;
	                }
	                // Extract the data for the current score.
	                var _b = scores[j], item_1 = _b.item, labelIndices = _b.labelIndices;
	                // Ignore an item with a different category.
	                if (item_1.category !== category) {
	                    continue;
	                }
	                // Create the item result for the score.
	                results.push({ type: 'item', item: item_1, indices: labelIndices });
	                // Mark the score as processed.
	                visited[j] = true;
	            }
	        }
	        // Return the final results.
	        return results;
	    }
	    /**
	     * A concrete implementation of `CommandPalette.IItem`.
	     */
	    var CommandItem = (function () {
	        /**
	         * Construct a new command item.
	         */
	        function CommandItem(commands, options) {
	            this._commands = commands;
	            this.category = normalizeCategory(options.category);
	            this.command = options.command;
	            this.args = options.args || coreutils_1.JSONExt.emptyObject;
	            this.rank = options.rank !== undefined ? options.rank : Infinity;
	        }
	        Object.defineProperty(CommandItem.prototype, "label", {
	            /**
	             * The display label for the command item.
	             */
	            get: function () {
	                return this._commands.label(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "caption", {
	            /**
	             * The display caption for the command item.
	             */
	            get: function () {
	                return this._commands.caption(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "className", {
	            /**
	             * The extra class name for the command item.
	             */
	            get: function () {
	                return this._commands.className(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "dataset", {
	            /**
	             * The dataset for the command item.
	             */
	            get: function () {
	                return this._commands.dataset(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "isEnabled", {
	            /**
	             * Whether the command item is enabled.
	             */
	            get: function () {
	                return this._commands.isEnabled(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "isToggled", {
	            /**
	             * Whether the command item is toggled.
	             */
	            get: function () {
	                return this._commands.isToggled(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "isVisible", {
	            /**
	             * Whether the command item is visible.
	             */
	            get: function () {
	                return this._commands.isVisible(this.command, this.args);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(CommandItem.prototype, "keyBinding", {
	            /**
	             * The key binding for the command item.
	             */
	            get: function () {
	                var _a = this, command = _a.command, args = _a.args;
	                return algorithm_1.ArrayExt.findLastValue(this._commands.keyBindings, function (kb) {
	                    return kb.command === command && coreutils_1.JSONExt.deepEqual(kb.args, args);
	                }) || null;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        return CommandItem;
	    }());
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/commandpalette.js **/


/** START DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/index.js **/
jupyter.define('@phosphor/coreutils@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	__export(__jupyter_require__('@phosphor/coreutils@1.1.1/lib/json.js'));
	__export(__jupyter_require__('@phosphor/coreutils@1.1.1/lib/mime.js'));
	__export(__jupyter_require__('@phosphor/coreutils@1.1.1/lib/promise.js'));
	__export(__jupyter_require__('@phosphor/coreutils@1.1.1/lib/token.js'));
	
})
/** END DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/json.js **/
jupyter.define('@phosphor/coreutils@1.1.1/lib/json.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The namespace for JSON-specific functions.
	 */
	var JSONExt;
	(function (JSONExt) {
	    /**
	     * A shared frozen empty JSONObject
	     */
	    JSONExt.emptyObject = Object.freeze({});
	    /**
	     * A shared frozen empty JSONArray
	     */
	    JSONExt.emptyArray = Object.freeze([]);
	    /**
	     * Test whether a JSON value is a primitive.
	     *
	     * @param value - The JSON value of interest.
	     *
	     * @returns `true` if the value is a primitive,`false` otherwise.
	     */
	    function isPrimitive(value) {
	        return (value === null ||
	            typeof value === 'boolean' ||
	            typeof value === 'number' ||
	            typeof value === 'string');
	    }
	    JSONExt.isPrimitive = isPrimitive;
	    /**
	     * Test whether a JSON value is an array.
	     *
	     * @param value - The JSON value of interest.
	     *
	     * @returns `true` if the value is a an array, `false` otherwise.
	     */
	    function isArray(value) {
	        return Array.isArray(value);
	    }
	    JSONExt.isArray = isArray;
	    /**
	     * Test whether a JSON value is an object.
	     *
	     * @param value - The JSON value of interest.
	     *
	     * @returns `true` if the value is a an object, `false` otherwise.
	     */
	    function isObject(value) {
	        return !isPrimitive(value) && !isArray(value);
	    }
	    JSONExt.isObject = isObject;
	    /**
	     * Compare two JSON values for deep equality.
	     *
	     * @param first - The first JSON value of interest.
	     *
	     * @param second - The second JSON value of interest.
	     *
	     * @returns `true` if the values are equivalent, `false` otherwise.
	     */
	    function deepEqual(first, second) {
	        // Check referential and primitive equality first.
	        if (first === second) {
	            return true;
	        }
	        // If one is a primitive, the `===` check ruled out the other.
	        if (isPrimitive(first) || isPrimitive(second)) {
	            return false;
	        }
	        // Test whether they are arrays.
	        var a1 = isArray(first);
	        var a2 = isArray(second);
	        // Bail if the types are different.
	        if (a1 !== a2) {
	            return false;
	        }
	        // If they are both arrays, compare them.
	        if (a1 && a2) {
	            return deepArrayEqual(first, second);
	        }
	        // At this point, they must both be objects.
	        return deepObjectEqual(first, second);
	    }
	    JSONExt.deepEqual = deepEqual;
	    function deepCopy(value) {
	        // Do nothing for primitive values.
	        if (isPrimitive(value)) {
	            return value;
	        }
	        // Deep copy an array.
	        if (isArray(value)) {
	            return deepArrayCopy(value);
	        }
	        // Deep copy an object.
	        return deepObjectCopy(value);
	    }
	    JSONExt.deepCopy = deepCopy;
	    /**
	     * Compare two JSON arrays for deep equality.
	     */
	    function deepArrayEqual(first, second) {
	        // Check referential equality first.
	        if (first === second) {
	            return true;
	        }
	        // Test the arrays for equal length.
	        if (first.length !== second.length) {
	            return false;
	        }
	        // Compare the values for equality.
	        for (var i = 0, n = first.length; i < n; ++i) {
	            if (!deepEqual(first[i], second[i])) {
	                return false;
	            }
	        }
	        // At this point, the arrays are equal.
	        return true;
	    }
	    /**
	     * Compare two JSON objects for deep equality.
	     */
	    function deepObjectEqual(first, second) {
	        // Check referential equality first.
	        if (first === second) {
	            return true;
	        }
	        // Check for the first object's keys in the second object.
	        for (var key in first) {
	            if (!(key in second)) {
	                return false;
	            }
	        }
	        // Check for the second object's keys in the first object.
	        for (var key in second) {
	            if (!(key in first)) {
	                return false;
	            }
	        }
	        // Compare the values for equality.
	        for (var key in first) {
	            if (!deepEqual(first[key], second[key])) {
	                return false;
	            }
	        }
	        // At this point, the objects are equal.
	        return true;
	    }
	    /**
	     * Create a deep copy of a JSON array.
	     */
	    function deepArrayCopy(value) {
	        var result = new Array(value.length);
	        for (var i = 0, n = value.length; i < n; ++i) {
	            result[i] = deepCopy(value[i]);
	        }
	        return result;
	    }
	    /**
	     * Create a deep copy of a JSON object.
	     */
	    function deepObjectCopy(value) {
	        var result = {};
	        for (var key in value) {
	            result[key] = deepCopy(value[key]);
	        }
	        return result;
	    }
	})(JSONExt = exports.JSONExt || (exports.JSONExt = {}));
	
})
/** END DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/json.js **/


/** START DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/mime.js **/
jupyter.define('@phosphor/coreutils@1.1.1/lib/mime.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * An object which stores MIME data for general application use.
	 *
	 * #### Notes
	 * This class does not attempt to enforce "correctness" of MIME types
	 * and their associated data. Since this class is designed to transfer
	 * arbitrary data and objects within the same application, it assumes
	 * that the user provides correct and accurate data.
	 */
	var MimeData = (function () {
	    function MimeData() {
	        this._types = [];
	        this._values = [];
	    }
	    /**
	     * Get an array of the MIME types contained within the dataset.
	     *
	     * @returns A new array of the MIME types, in order of insertion.
	     */
	    MimeData.prototype.types = function () {
	        return this._types.slice();
	    };
	    /**
	     * Test whether the dataset has an entry for the given type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * @returns `true` if the dataset contains a value for the given
	     *   MIME type, `false` otherwise.
	     */
	    MimeData.prototype.hasData = function (mime) {
	        return this._types.indexOf(mime) !== -1;
	    };
	    /**
	     * Get the data value for the given MIME type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * @returns The value for the given MIME type, or `undefined` if
	     *   the dataset does not contain a value for the type.
	     */
	    MimeData.prototype.getData = function (mime) {
	        var i = this._types.indexOf(mime);
	        return i !== -1 ? this._values[i] : undefined;
	    };
	    /**
	     * Set the data value for the given MIME type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * @param data - The data value for the given MIME type.
	     *
	     * #### Notes
	     * This will overwrite any previous entry for the MIME type.
	     */
	    MimeData.prototype.setData = function (mime, data) {
	        this.clearData(mime);
	        this._types.push(mime);
	        this._values.push(data);
	    };
	    /**
	     * Remove the data entry for the given MIME type.
	     *
	     * @param mime - The MIME type of interest.
	     *
	     * #### Notes
	     * This is a no-op if there is no entry for the given MIME type.
	     */
	    MimeData.prototype.clearData = function (mime) {
	        var i = this._types.indexOf(mime);
	        if (i !== -1) {
	            this._types.splice(i, 1);
	            this._values.splice(i, 1);
	        }
	    };
	    /**
	     * Remove all data entries from the dataset.
	     */
	    MimeData.prototype.clear = function () {
	        this._types.length = 0;
	        this._values.length = 0;
	    };
	    return MimeData;
	}());
	exports.MimeData = MimeData;
	
})
/** END DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/mime.js **/


/** START DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/promise.js **/
jupyter.define('@phosphor/coreutils@1.1.1/lib/promise.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A class which wraps a promise into a delegate object.
	 *
	 * #### Notes
	 * This class is useful when the logic to resolve or reject a promise
	 * cannot be defined at the point where the promise is created.
	 */
	var PromiseDelegate = (function () {
	    /**
	     * Construct a new promise delegate.
	     */
	    function PromiseDelegate() {
	        var _this = this;
	        this.promise = new Promise(function (resolve, reject) {
	            _this._resolve = resolve;
	            _this._reject = reject;
	        });
	    }
	    /**
	     * Resolve the wrapped promise with the given value.
	     *
	     * @param value - The value to use for resolving the promise.
	     */
	    PromiseDelegate.prototype.resolve = function (value) {
	        var resolve = this._resolve;
	        resolve(value);
	    };
	    /**
	     * Reject the wrapped promise with the given value.
	     *
	     * @reason - The reason for rejecting the promise.
	     */
	    PromiseDelegate.prototype.reject = function (reason) {
	        var reject = this._reject;
	        reject(reason);
	    };
	    return PromiseDelegate;
	}());
	exports.PromiseDelegate = PromiseDelegate;
	
})
/** END DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/promise.js **/


/** START DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/token.js **/
jupyter.define('@phosphor/coreutils@1.1.1/lib/token.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A runtime object which captures compile-time type information.
	 *
	 * #### Notes
	 * A token captures the compile-time type of an interface or class in
	 * an object which can be used at runtime in a type-safe fashion.
	 */
	var Token = (function () {
	    /**
	     * Construct a new token.
	     *
	     * @param name - A human readable name for the token.
	     */
	    function Token(name) {
	        this.name = name;
	        this._tokenStructuralPropertyT = null;
	    }
	    return Token;
	}());
	exports.Token = Token;
	
})
/** END DEFINE BLOCK for @phosphor/coreutils@1.1.1/lib/token.js **/


/** START DEFINE BLOCK for @phosphor/commands@1.2.1/lib/index.js **/
jupyter.define('@phosphor/commands@1.2.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.1.1/lib/index.js');
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var keyboard_1 = __jupyter_require__('@phosphor/keyboard@^1.1.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	/**
	 * An object which manages a collection of commands.
	 *
	 * #### Notes
	 * A command registry can be used to populate a variety of action-based
	 * widgets, such as command palettes, menus, and toolbars.
	 */
	var CommandRegistry = (function () {
	    /**
	     * Construct a new command registry.
	     */
	    function CommandRegistry() {
	        this._timerID = 0;
	        this._replaying = false;
	        this._keystrokes = [];
	        this._keydownEvents = [];
	        this._keyBindings = [];
	        this._exactKeyMatch = null;
	        this._commands = Object.create(null);
	        this._commandChanged = new signaling_1.Signal(this);
	        this._commandExecuted = new signaling_1.Signal(this);
	        this._keyBindingChanged = new signaling_1.Signal(this);
	    }
	    Object.defineProperty(CommandRegistry.prototype, "commandChanged", {
	        /**
	         * A signal emitted when a command has changed.
	         *
	         * #### Notes
	         * This signal is useful for visual representations of commands which
	         * need to refresh when the state of a relevant command has changed.
	         */
	        get: function () {
	            return this._commandChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandRegistry.prototype, "commandExecuted", {
	        /**
	         * A signal emitted when a command has executed.
	         *
	         * #### Notes
	         * Care should be taken when consuming this signal. It is intended to
	         * be used largely for debugging and logging purposes. It should not
	         * be (ab)used for general purpose spying on command execution.
	         */
	        get: function () {
	            return this._commandExecuted;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandRegistry.prototype, "keyBindingChanged", {
	        /**
	         * A signal emitted when a key binding is changed.
	         */
	        get: function () {
	            return this._keyBindingChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommandRegistry.prototype, "keyBindings", {
	        /**
	         * A read-only array of the key bindings in the registry.
	         */
	        get: function () {
	            return this._keyBindings;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * List the ids of the registered commands.
	     *
	     * @returns A new array of the registered command ids.
	     */
	    CommandRegistry.prototype.listCommands = function () {
	        return Object.keys(this._commands);
	    };
	    /**
	     * Test whether a specific command is registered.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @returns `true` if the command is registered, `false` otherwise.
	     */
	    CommandRegistry.prototype.hasCommand = function (id) {
	        return id in this._commands;
	    };
	    /**
	     * Add a command to the registry.
	     *
	     * @param id - The unique id of the command.
	     *
	     * @param options - The options for the command.
	     *
	     * @returns A disposable which will remove the command.
	     *
	     * @throws An error if the given `id` is already registered.
	     */
	    CommandRegistry.prototype.addCommand = function (id, options) {
	        var _this = this;
	        // Throw an error if the id is already registered.
	        if (id in this._commands) {
	            throw new Error("Command '" + id + "' already registered.");
	        }
	        // Add the command to the registry.
	        this._commands[id] = Private.createCommand(options);
	        // Emit the `commandChanged` signal.
	        this._commandChanged.emit({ id: id, type: 'added' });
	        // Return a disposable which will remove the command.
	        return new disposable_1.DisposableDelegate(function () {
	            // Remove the command from the registry.
	            delete _this._commands[id];
	            // Emit the `commandChanged` signal.
	            _this._commandChanged.emit({ id: id, type: 'removed' });
	        });
	    };
	    /**
	     * Notify listeners that the state of a command has changed.
	     *
	     * @param id - The id of the command which has changed.
	     *
	     * @throws An error if the given `id` is not registered.
	     *
	     * #### Notes
	     * This method should be called by the command author whenever the
	     * application state changes such that the results of the command
	     * metadata functions may have changed.
	     *
	     * This will cause the `commandChanged` signal to be emitted.
	     */
	    CommandRegistry.prototype.notifyCommandChanged = function (id) {
	        if (!(id in this._commands)) {
	            throw new Error("Command '" + id + "' is not registered.");
	        }
	        this._commandChanged.emit({ id: id, type: 'changed' });
	    };
	    /**
	     * Get the display label for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The display label for the command, or an empty string
	     *   if the command is not registered.
	     */
	    CommandRegistry.prototype.label = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.label.call(undefined, args) : '';
	    };
	    /**
	     * Get the mnemonic index for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The mnemonic index for the command, or `-1` if the
	     *   command is not registered.
	     */
	    CommandRegistry.prototype.mnemonic = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.mnemonic.call(undefined, args) : -1;
	    };
	    /**
	     * @deprecated Use `iconClass()` instead.
	     */
	    CommandRegistry.prototype.icon = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        return this.iconClass(id, args);
	    };
	    /**
	     * Get the icon class for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The icon class for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.iconClass = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.iconClass.call(undefined, args) : '';
	    };
	    /**
	     * Get the icon label for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The icon label for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.iconLabel = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.iconLabel.call(undefined, args) : '';
	    };
	    /**
	     * Get the short form caption for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The caption for the command, or an empty string if the
	     *   command is not registered.
	     */
	    CommandRegistry.prototype.caption = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.caption.call(undefined, args) : '';
	    };
	    /**
	     * Get the usage help text for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The usage text for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.usage = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.usage.call(undefined, args) : '';
	    };
	    /**
	     * Get the extra class name for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The class name for the command, or an empty string if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.className = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.className.call(undefined, args) : '';
	    };
	    /**
	     * Get the dataset for a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns The dataset for the command, or an empty dataset if
	     *   the command is not registered.
	     */
	    CommandRegistry.prototype.dataset = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.dataset.call(undefined, args) : {};
	    };
	    /**
	     * Test whether a specific command is enabled.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A boolean indicating whether the command is enabled,
	     *   or `false` if the command is not registered.
	     */
	    CommandRegistry.prototype.isEnabled = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.isEnabled.call(undefined, args) : false;
	    };
	    /**
	     * Test whether a specific command is toggled.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A boolean indicating whether the command is toggled,
	     *   or `false` if the command is not registered.
	     */
	    CommandRegistry.prototype.isToggled = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.isToggled.call(undefined, args) : false;
	    };
	    /**
	     * Test whether a specific command is visible.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A boolean indicating whether the command is visible,
	     *   or `false` if the command is not registered.
	     */
	    CommandRegistry.prototype.isVisible = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        var cmd = this._commands[id];
	        return cmd ? cmd.isVisible.call(undefined, args) : false;
	    };
	    /**
	     * Execute a specific command.
	     *
	     * @param id - The id of the command of interest.
	     *
	     * @param args - The arguments for the command.
	     *
	     * @returns A promise which resolves with the result of the command.
	     *
	     * #### Notes
	     * The promise will reject if the command throws an exception,
	     * or if the command is not registered.
	     */
	    CommandRegistry.prototype.execute = function (id, args) {
	        if (args === void 0) { args = coreutils_1.JSONExt.emptyObject; }
	        // Reject if the command is not registered.
	        var cmd = this._commands[id];
	        if (!cmd) {
	            return Promise.reject(new Error("Command '" + id + "' not registered."));
	        }
	        // Execute the command and reject if an exception is thrown.
	        var value;
	        try {
	            value = cmd.execute.call(undefined, args);
	        }
	        catch (err) {
	            value = Promise.reject(err);
	        }
	        // Create the return promise which resolves the result.
	        var result = Promise.resolve(value);
	        // Emit the command executed signal.
	        this._commandExecuted.emit({ id: id, args: args, result: result });
	        // Return the result promise to the caller.
	        return result;
	    };
	    /**
	     * Add a key binding to the registry.
	     *
	     * @param options - The options for creating the key binding.
	     *
	     * @returns A disposable which removes the added key binding.
	     *
	     * #### Notes
	     * If multiple key bindings are registered for the same sequence, the
	     * binding with the highest selector specificity is executed first. A
	     * tie is broken by using the most recently added key binding.
	     *
	     * Ambiguous key bindings are resolved with a timeout. As an example,
	     * suppose two key bindings are registered: one with the key sequence
	     * `['Ctrl D']`, and another with `['Ctrl D', 'Ctrl W']`. If the user
	     * presses `Ctrl D`, the first binding cannot be immediately executed
	     * since the user may intend to complete the chord with `Ctrl W`. For
	     * such cases, a timer is used to allow the chord to be completed. If
	     * the chord is not completed before the timeout, the first binding
	     * is executed.
	     */
	    CommandRegistry.prototype.addKeyBinding = function (options) {
	        var _this = this;
	        // Create the binding for the given options.
	        var binding = Private.createKeyBinding(options);
	        // Add the key binding to the bindings array.
	        this._keyBindings.push(binding);
	        // Emit the `bindingChanged` signal.
	        this._keyBindingChanged.emit({ binding: binding, type: 'added' });
	        // Return a disposable which will remove the binding.
	        return new disposable_1.DisposableDelegate(function () {
	            // Remove the binding from the array.
	            algorithm_1.ArrayExt.removeFirstOf(_this._keyBindings, binding);
	            // Emit the `bindingChanged` signal.
	            _this._keyBindingChanged.emit({ binding: binding, type: 'removed' });
	        });
	    };
	    /**
	     * Process a `'keydown'` event and invoke a matching key binding.
	     *
	     * @param event - The event object for a `'keydown'` event.
	     *
	     * #### Notes
	     * This should be called in response to a `'keydown'` event in order
	     * to invoke the command for the best matching key binding.
	     *
	     * The registry **does not** install its own listener for `'keydown'`
	     * events. This allows the application full control over the nodes
	     * and phase for which the registry processes `'keydown'` events.
	     */
	    CommandRegistry.prototype.processKeydownEvent = function (event) {
	        // Bail immediately if playing back keystrokes.
	        if (this._replaying) {
	            return;
	        }
	        // Get the normalized keystroke for the event.
	        var keystroke = CommandRegistry.keystrokeForKeydownEvent(event);
	        // If the keystroke is not valid for the keyboard layout, replay
	        // any suppressed events and clear the pending state.
	        if (!keystroke) {
	            this._replayKeydownEvents();
	            this._clearPendingState();
	            return;
	        }
	        // Add the keystroke to the current key sequence.
	        this._keystrokes.push(keystroke);
	        // Find the exact and partial matches for the key sequence.
	        var _a = Private.matchKeyBinding(this._keyBindings, this._keystrokes, event), exact = _a.exact, partial = _a.partial;
	        // If there is no exact match and no partial match, replay
	        // any suppressed events and clear the pending state.
	        if (!exact && !partial) {
	            this._replayKeydownEvents();
	            this._clearPendingState();
	            return;
	        }
	        // Stop propagation of the event. If there is only a partial match,
	        // the event will be replayed if a final exact match never occurs.
	        event.preventDefault();
	        event.stopPropagation();
	        // If there is an exact match but no partial match, the exact match
	        // can be dispatched immediately. The pending state is cleared so
	        // the next key press starts from the default state.
	        if (exact && !partial) {
	            this._executeKeyBinding(exact);
	            this._clearPendingState();
	            return;
	        }
	        // If there is both an exact match and a partial match, the exact
	        // match is stored for future dispatch in case the timer expires
	        // before a more specific match is triggered.
	        if (exact) {
	            this._exactKeyMatch = exact;
	        }
	        // Store the event for possible playback in the future.
	        this._keydownEvents.push(event);
	        // (Re)start the timer to dispatch the most recent exact match
	        // in case the partial match fails to result in an exact match.
	        this._startTimer();
	    };
	    /**
	     * Start or restart the pending timeout.
	     */
	    CommandRegistry.prototype._startTimer = function () {
	        var _this = this;
	        this._clearTimer();
	        this._timerID = setTimeout(function () {
	            _this._onPendingTimeout();
	        }, Private.CHORD_TIMEOUT);
	    };
	    /**
	     * Clear the pending timeout.
	     */
	    CommandRegistry.prototype._clearTimer = function () {
	        if (this._timerID !== 0) {
	            clearTimeout(this._timerID);
	            this._timerID = 0;
	        }
	    };
	    /**
	     * Replay the keydown events which were suppressed.
	     */
	    CommandRegistry.prototype._replayKeydownEvents = function () {
	        if (this._keydownEvents.length === 0) {
	            return;
	        }
	        this._replaying = true;
	        this._keydownEvents.forEach(Private.replayKeyEvent);
	        this._replaying = false;
	    };
	    /**
	     * Execute the command for the given key binding.
	     *
	     * If the command is missing or disabled, a warning will be logged.
	     */
	    CommandRegistry.prototype._executeKeyBinding = function (binding) {
	        var command = binding.command, args = binding.args;
	        if (!this.hasCommand(command) || !this.isEnabled(command, args)) {
	            var word = this.hasCommand(command) ? 'enabled' : 'registered';
	            var keys = binding.keys.join(', ');
	            var msg1 = "Cannot execute key binding '" + keys + "':";
	            var msg2 = "command '" + command + "' is not " + word + ".";
	            console.warn(msg1 + " " + msg2);
	            return;
	        }
	        this.execute(command, args);
	    };
	    /**
	     * Clear the internal pending state.
	     */
	    CommandRegistry.prototype._clearPendingState = function () {
	        this._clearTimer();
	        this._exactKeyMatch = null;
	        this._keystrokes.length = 0;
	        this._keydownEvents.length = 0;
	    };
	    /**
	     * Handle the partial match timeout.
	     */
	    CommandRegistry.prototype._onPendingTimeout = function () {
	        this._timerID = 0;
	        if (this._exactKeyMatch) {
	            this._executeKeyBinding(this._exactKeyMatch);
	        }
	        else {
	            this._replayKeydownEvents();
	        }
	        this._clearPendingState();
	    };
	    return CommandRegistry;
	}());
	exports.CommandRegistry = CommandRegistry;
	/**
	 * The namespace for the `CommandRegistry` class statics.
	 */
	(function (CommandRegistry) {
	    /**
	     * Parse a keystroke into its constituent components.
	     *
	     * @param keystroke - The keystroke of interest.
	     *
	     * @returns The parsed components of the keystroke.
	     *
	     * #### Notes
	     * The keystroke should be of the form:
	     *   `[<modifier 1> [<modifier 2> [<modifier N> ]]]<primary key>`
	     *
	     * The supported modifiers are: `Accel`, `Alt`, `Cmd`, `Ctrl`, and
	     * `Shift`. The `Accel` modifier is translated to `Cmd` on Mac and
	     * `Ctrl` on all other platforms.
	     *
	     * The parsing is tolerant and will not throw exceptions. Notably:
	     *   - Duplicate modifiers are ignored.
	     *   - Extra primary keys are ignored.
	     *   - The order of modifiers and primary key is irrelevant.
	     *   - The keystroke parts should be separated by whitespace.
	     *   - The keystroke is case sensitive.
	     */
	    function parseKeystroke(keystroke) {
	        var key = '';
	        var alt = false;
	        var cmd = false;
	        var ctrl = false;
	        var shift = false;
	        for (var _i = 0, _a = keystroke.split(/\s+/); _i < _a.length; _i++) {
	            var token = _a[_i];
	            if (token === 'Accel') {
	                if (domutils_1.Platform.IS_MAC) {
	                    cmd = true;
	                }
	                else {
	                    ctrl = true;
	                }
	            }
	            else if (token === 'Alt') {
	                alt = true;
	            }
	            else if (token === 'Cmd') {
	                cmd = true;
	            }
	            else if (token === 'Ctrl') {
	                ctrl = true;
	            }
	            else if (token === 'Shift') {
	                shift = true;
	            }
	            else if (token.length > 0) {
	                key = token;
	            }
	        }
	        return { cmd: cmd, ctrl: ctrl, alt: alt, shift: shift, key: key };
	    }
	    CommandRegistry.parseKeystroke = parseKeystroke;
	    /**
	     * Normalize a keystroke into a canonical representation.
	     *
	     * @param keystroke - The keystroke of interest.
	     *
	     * @returns The normalized representation of the keystroke.
	     *
	     * #### Notes
	     * This normalizes the keystroke by removing duplicate modifiers and
	     * extra primary keys, and assembling the parts in a canonical order.
	     *
	     * The `Cmd` modifier is ignored on non-Mac platforms.
	     */
	    function normalizeKeystroke(keystroke) {
	        var mods = '';
	        var parts = parseKeystroke(keystroke);
	        if (parts.ctrl) {
	            mods += 'Ctrl ';
	        }
	        if (parts.alt) {
	            mods += 'Alt ';
	        }
	        if (parts.shift) {
	            mods += 'Shift ';
	        }
	        if (parts.cmd && domutils_1.Platform.IS_MAC) {
	            mods += 'Cmd ';
	        }
	        return mods + parts.key;
	    }
	    CommandRegistry.normalizeKeystroke = normalizeKeystroke;
	    /**
	     * Create a normalized keystroke for a `'keydown'` event.
	     *
	     * @param event - The event object for a `'keydown'` event.
	     *
	     * @returns A normalized keystroke, or an empty string if the event
	     *   does not represent a valid keystroke for the given layout.
	     */
	    function keystrokeForKeydownEvent(event) {
	        var key = keyboard_1.getKeyboardLayout().keyForKeydownEvent(event);
	        if (!key) {
	            return '';
	        }
	        var mods = '';
	        if (event.ctrlKey) {
	            mods += 'Ctrl ';
	        }
	        if (event.altKey) {
	            mods += 'Alt ';
	        }
	        if (event.shiftKey) {
	            mods += 'Shift ';
	        }
	        if (event.metaKey && domutils_1.Platform.IS_MAC) {
	            mods += 'Cmd ';
	        }
	        return mods + key;
	    }
	    CommandRegistry.keystrokeForKeydownEvent = keystrokeForKeydownEvent;
	})(CommandRegistry = exports.CommandRegistry || (exports.CommandRegistry = {}));
	exports.CommandRegistry = CommandRegistry;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The timeout in ms for triggering a key binding chord.
	     */
	    Private.CHORD_TIMEOUT = 1000;
	    /**
	     * Create a normalized command from an options object.
	     */
	    function createCommand(options) {
	        return {
	            execute: options.execute,
	            label: asFunc(options.label, emptyStringFunc),
	            mnemonic: asFunc(options.mnemonic, negativeOneFunc),
	            iconClass: asFunc(options.iconClass || options.icon, emptyStringFunc),
	            iconLabel: asFunc(options.iconLabel, emptyStringFunc),
	            caption: asFunc(options.caption, emptyStringFunc),
	            usage: asFunc(options.usage, emptyStringFunc),
	            className: asFunc(options.className, emptyStringFunc),
	            dataset: asFunc(options.dataset, emptyDatasetFunc),
	            isEnabled: options.isEnabled || trueFunc,
	            isToggled: options.isToggled || falseFunc,
	            isVisible: options.isVisible || trueFunc
	        };
	    }
	    Private.createCommand = createCommand;
	    /**
	     * Create a key binding object from key binding options.
	     */
	    function createKeyBinding(options) {
	        return {
	            keys: normalizeKeys(options),
	            selector: validateSelector(options),
	            command: options.command,
	            args: options.args || coreutils_1.JSONExt.emptyObject
	        };
	    }
	    Private.createKeyBinding = createKeyBinding;
	    /**
	     * Find the key bindings which match a key sequence.
	     *
	     * This returns a match result which contains the best exact matching
	     * binding, and a flag which indicates if there are partial matches.
	     */
	    function matchKeyBinding(bindings, keys, event) {
	        // The current best exact match.
	        var exact = null;
	        // Whether a partial match has been found.
	        var partial = false;
	        // The match distance for the exact match.
	        var distance = Infinity;
	        // The specificity for the exact match.
	        var specificity = 0;
	        // Iterate over the bindings and search for the best match.
	        for (var i = 0, n = bindings.length; i < n; ++i) {
	            // Lookup the current binding.
	            var binding = bindings[i];
	            // Check whether the key binding sequence is a match.
	            var sqm = matchSequence(binding.keys, keys);
	            // If there is no match, the binding is ignored.
	            if (sqm === 0 /* None */) {
	                continue;
	            }
	            // If it is a partial match and no other partial match has been
	            // found, ensure the selector matches and set the partial flag.
	            if (sqm === 2 /* Partial */) {
	                if (!partial && targetDistance(binding.selector, event) !== -1) {
	                    partial = true;
	                }
	                continue;
	            }
	            // Ignore the match if the selector doesn't match, or if the
	            // matched node is farther away than the current best match.
	            var td = targetDistance(binding.selector, event);
	            if (td === -1 || td > distance) {
	                continue;
	            }
	            // Get the specificity for the selector.
	            var sp = domutils_1.Selector.calculateSpecificity(binding.selector);
	            // Update the best match if this match is stronger.
	            if (!exact || td < distance || sp >= specificity) {
	                exact = binding;
	                distance = td;
	                specificity = sp;
	            }
	        }
	        // Return the match result.
	        return { exact: exact, partial: partial };
	    }
	    Private.matchKeyBinding = matchKeyBinding;
	    /**
	     * Replay a keyboard event.
	     *
	     * This synthetically dispatches a clone of the keyboard event.
	     */
	    function replayKeyEvent(event) {
	        event.target.dispatchEvent(cloneKeyboardEvent(event));
	    }
	    Private.replayKeyEvent = replayKeyEvent;
	    /**
	     * A singleton empty string function.
	     */
	    var emptyStringFunc = function () { return ''; };
	    /**
	     * A singleton `-1` number function
	     */
	    var negativeOneFunc = function () { return -1; };
	    /**
	     * A singleton true boolean function.
	     */
	    var trueFunc = function () { return true; };
	    /**
	     * A singleton false boolean function.
	     */
	    var falseFunc = function () { return false; };
	    /**
	     * A singleton empty dataset function.
	     */
	    var emptyDatasetFunc = function () { return ({}); };
	    /**
	     * Cast a value or command func to a command func.
	     */
	    function asFunc(value, dfault) {
	        if (value === undefined) {
	            return dfault;
	        }
	        if (typeof value === 'function') {
	            return value;
	        }
	        return function () { return value; };
	    }
	    /**
	     * Get the platform-specific normalized keys for an options object.
	     */
	    function normalizeKeys(options) {
	        var keys;
	        if (domutils_1.Platform.IS_WIN) {
	            keys = options.winKeys || options.keys;
	        }
	        else if (domutils_1.Platform.IS_MAC) {
	            keys = options.macKeys || options.keys;
	        }
	        else {
	            keys = options.linuxKeys || options.keys;
	        }
	        return keys.map(CommandRegistry.normalizeKeystroke);
	    }
	    /**
	     * Validate the selector for an options object.
	     *
	     * This returns the validated selector, or throws if the selector is
	     * invalid or contains commas.
	     */
	    function validateSelector(options) {
	        if (options.selector.indexOf(',') !== -1) {
	            throw new Error("Selector cannot contain commas: " + options.selector);
	        }
	        if (!domutils_1.Selector.isValid(options.selector)) {
	            throw new Error("Invalid selector: " + options.selector);
	        }
	        return options.selector;
	    }
	    ;
	    /**
	     * Test whether a key binding sequence matches a key sequence.
	     *
	     * Returns a `SequenceMatch` value indicating the type of match.
	     */
	    function matchSequence(bindKeys, userKeys) {
	        if (bindKeys.length < userKeys.length) {
	            return 0 /* None */;
	        }
	        for (var i = 0, n = userKeys.length; i < n; ++i) {
	            if (bindKeys[i] !== userKeys[i]) {
	                return 0 /* None */;
	            }
	        }
	        if (bindKeys.length > userKeys.length) {
	            return 2 /* Partial */;
	        }
	        return 1 /* Exact */;
	    }
	    /**
	     * Find the distance from the target node to the first matching node.
	     *
	     * This traverses the event path from `target` to `currentTarget` and
	     * computes the distance from `target` to the first node which matches
	     * the CSS selector. If no match is found, `-1` is returned.
	     */
	    function targetDistance(selector, event) {
	        var targ = event.target;
	        var curr = event.currentTarget;
	        for (var dist = 0; targ !== null; targ = targ.parentElement, ++dist) {
	            if (domutils_1.Selector.matches(targ, selector)) {
	                return dist;
	            }
	            if (targ === curr) {
	                return -1;
	            }
	        }
	        return -1;
	    }
	    /**
	     * Clone a keyboard event.
	     */
	    function cloneKeyboardEvent(event) {
	        // A custom event is required because Chrome nulls out the
	        // `keyCode` field in user-generated `KeyboardEvent` types.
	        var clone = document.createEvent('Event');
	        var bubbles = event.bubbles || true;
	        var cancelable = event.cancelable || true;
	        clone.initEvent(event.type || 'keydown', bubbles, cancelable);
	        clone.key = event.key || '';
	        clone.keyCode = event.keyCode || 0;
	        clone.which = event.keyCode || 0;
	        clone.ctrlKey = event.ctrlKey || false;
	        clone.altKey = event.altKey || false;
	        clone.shiftKey = event.shiftKey || false;
	        clone.metaKey = event.metaKey || false;
	        clone.view = event.view || window;
	        return clone;
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/commands@1.2.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/disposable@1.1.1/lib/index.js **/
jupyter.define('@phosphor/disposable@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	/**
	 * A disposable object which delegates to a callback function.
	 */
	var DisposableDelegate = (function () {
	    /**
	     * Construct a new disposable delegate.
	     *
	     * @param fn - The callback function to invoke on dispose.
	     */
	    function DisposableDelegate(fn) {
	        this._fn = fn;
	    }
	    Object.defineProperty(DisposableDelegate.prototype, "isDisposed", {
	        /**
	         * Test whether the delegate has been disposed.
	         */
	        get: function () {
	            return !this._fn;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the delegate and invoke the callback function.
	     */
	    DisposableDelegate.prototype.dispose = function () {
	        if (!this._fn) {
	            return;
	        }
	        var fn = this._fn;
	        this._fn = null;
	        fn();
	    };
	    return DisposableDelegate;
	}());
	exports.DisposableDelegate = DisposableDelegate;
	/**
	 * An object which manages a collection of disposable items.
	 */
	var DisposableSet = (function () {
	    /**
	     * Construct a new disposable set.
	     */
	    function DisposableSet() {
	        this._disposed = false;
	        this._items = new Set();
	    }
	    Object.defineProperty(DisposableSet.prototype, "isDisposed", {
	        /**
	         * Test whether the set has been disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the set and the items it contains.
	     *
	     * #### Notes
	     * Items are disposed in the order they are added to the set.
	     */
	    DisposableSet.prototype.dispose = function () {
	        if (this._disposed) {
	            return;
	        }
	        this._disposed = true;
	        this._items.forEach(function (item) { item.dispose(); });
	        this._items.clear();
	    };
	    /**
	     * Test whether the set contains a specific item.
	     *
	     * @param item - The item of interest.
	     *
	     * @returns `true` if the set contains the item, `false` otherwise.
	     */
	    DisposableSet.prototype.contains = function (item) {
	        return this._items.has(item);
	    };
	    /**
	     * Add a disposable item to the set.
	     *
	     * @param item - The item to add to the set.
	     *
	     * #### Notes
	     * If the item is already contained in the set, this is a no-op.
	     */
	    DisposableSet.prototype.add = function (item) {
	        this._items.add(item);
	    };
	    /**
	     * Remove a disposable item from the set.
	     *
	     * @param item - The item to remove from the set.
	     *
	     * #### Notes
	     * If the item is not contained in the set, this is a no-op.
	     */
	    DisposableSet.prototype.remove = function (item) {
	        this._items.delete(item);
	    };
	    /**
	     * Remove all items from the set.
	     */
	    DisposableSet.prototype.clear = function () {
	        this._items.clear();
	    };
	    return DisposableSet;
	}());
	exports.DisposableSet = DisposableSet;
	/**
	 * The namespace for the `DisposableSet` class statics.
	 */
	(function (DisposableSet) {
	    /**
	     * Create a disposable set from an iterable of items.
	     *
	     * @param items - The iterable or array-like object of interest.
	     *
	     * @returns A new disposable initialized with the given items.
	     */
	    function from(items) {
	        var set = new DisposableSet();
	        algorithm_1.each(items, function (item) { set.add(item); });
	        return set;
	    }
	    DisposableSet.from = from;
	})(DisposableSet = exports.DisposableSet || (exports.DisposableSet = {}));
	exports.DisposableSet = DisposableSet;
	
})
/** END DEFINE BLOCK for @phosphor/disposable@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/keyboard@1.1.1/lib/index.js **/
jupyter.define('@phosphor/keyboard@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Get the global application keyboard layout instance.
	 *
	 * @returns The keyboard layout for use by the application.
	 *
	 * #### Notes
	 * The default keyboard layout is US-English.
	 */
	function getKeyboardLayout() {
	    return Private.keyboardLayout;
	}
	exports.getKeyboardLayout = getKeyboardLayout;
	/**
	 * Set the global application keyboard layout instance.
	 *
	 * @param - The keyboard layout for use by the application.
	 *
	 * #### Notes
	 * The keyboard layout should typically be set on application startup
	 * to a layout which is appropriate for the user's system.
	 */
	function setKeyboardLayout(layout) {
	    Private.keyboardLayout = layout;
	}
	exports.setKeyboardLayout = setKeyboardLayout;
	/**
	 * A concrete implementation of [[IKeyboardLayout]] based on keycodes.
	 *
	 * The `keyCode` property of a `'keydown'` event is a browser and OS
	 * specific representation of the physical key (not character) which
	 * was pressed on a keyboard. While not the most convenient API, it
	 * is currently the only one which works reliably on all browsers.
	 *
	 * This class accepts a user-defined mapping of keycode to key, which
	 * allows for reliable shortcuts tailored to the user's system.
	 */
	var KeycodeLayout = (function () {
	    /**
	     * Construct a new keycode layout.
	     *
	     * @param name - The human readable name for the layout.
	     *
	     * @param codes - A mapping of keycode to key value.
	     */
	    function KeycodeLayout(name, codes) {
	        this.name = name;
	        this._codes = codes;
	        this._keys = KeycodeLayout.extractKeys(codes);
	    }
	    /**
	     * Get an array of the key values supported by the layout.
	     *
	     * @returns A new array of the supported key values.
	     */
	    KeycodeLayout.prototype.keys = function () {
	        return Object.keys(this._keys);
	    };
	    /**
	     * Test whether the given key is a valid value for the layout.
	     *
	     * @param key - The user provided key to test for validity.
	     *
	     * @returns `true` if the key is valid, `false` otherwise.
	     */
	    KeycodeLayout.prototype.isValidKey = function (key) {
	        return key in this._keys;
	    };
	    /**
	     * Get the key for a `'keydown'` event.
	     *
	     * @param event - The event object for a `'keydown'` event.
	     *
	     * @returns The associated key value, or an empty string if
	     *   the event does not represent a valid primary key.
	     */
	    KeycodeLayout.prototype.keyForKeydownEvent = function (event) {
	        return this._codes[event.keyCode] || '';
	    };
	    return KeycodeLayout;
	}());
	exports.KeycodeLayout = KeycodeLayout;
	/**
	 * The namespace for the `KeycodeLayout` class statics.
	 */
	(function (KeycodeLayout) {
	    /**
	     * Extract the set of keys from a code map.
	     *
	     * @param code - The code map of interest.
	     *
	     * @returns A set of the keys in the code map.
	     */
	    function extractKeys(codes) {
	        var keys = Object.create(null);
	        for (var c in codes) {
	            keys[codes[c]] = true;
	        }
	        return keys;
	    }
	    KeycodeLayout.extractKeys = extractKeys;
	})(KeycodeLayout = exports.KeycodeLayout || (exports.KeycodeLayout = {}));
	exports.KeycodeLayout = KeycodeLayout;
	/**
	 * A keycode-based keyboard layout for US English keyboards.
	 *
	 * This layout is valid for the following OS/Browser combinations.
	 *
	 * - Windows
	 *   - Chrome
	 *   - Firefox
	 *   - IE
	 *
	 * - OSX
	 *   - Chrome
	 *   - Firefox
	 *   - Safari
	 *
	 * - Linux
	 *   - Chrome
	 *   - Firefox
	 *
	 * Other combinations may also work, but are untested.
	 */
	exports.EN_US = new KeycodeLayout('en-us', {
	    8: 'Backspace',
	    9: 'Tab',
	    13: 'Enter',
	    19: 'Pause',
	    27: 'Escape',
	    32: 'Space',
	    33: 'PageUp',
	    34: 'PageDown',
	    35: 'End',
	    36: 'Home',
	    37: 'ArrowLeft',
	    38: 'ArrowUp',
	    39: 'ArrowRight',
	    40: 'ArrowDown',
	    45: 'Insert',
	    46: 'Delete',
	    48: '0',
	    49: '1',
	    50: '2',
	    51: '3',
	    52: '4',
	    53: '5',
	    54: '6',
	    55: '7',
	    56: '8',
	    57: '9',
	    59: ';',
	    61: '=',
	    65: 'A',
	    66: 'B',
	    67: 'C',
	    68: 'D',
	    69: 'E',
	    70: 'F',
	    71: 'G',
	    72: 'H',
	    73: 'I',
	    74: 'J',
	    75: 'K',
	    76: 'L',
	    77: 'M',
	    78: 'N',
	    79: 'O',
	    80: 'P',
	    81: 'Q',
	    82: 'R',
	    83: 'S',
	    84: 'T',
	    85: 'U',
	    86: 'V',
	    87: 'W',
	    88: 'X',
	    89: 'Y',
	    90: 'Z',
	    93: 'ContextMenu',
	    96: '0',
	    97: '1',
	    98: '2',
	    99: '3',
	    100: '4',
	    101: '5',
	    102: '6',
	    103: '7',
	    104: '8',
	    105: '9',
	    106: '*',
	    107: '+',
	    109: '-',
	    110: '.',
	    111: '/',
	    112: 'F1',
	    113: 'F2',
	    114: 'F3',
	    115: 'F4',
	    116: 'F5',
	    117: 'F6',
	    118: 'F7',
	    119: 'F8',
	    120: 'F9',
	    121: 'F10',
	    122: 'F11',
	    123: 'F12',
	    173: '-',
	    186: ';',
	    187: '=',
	    188: ',',
	    189: '-',
	    190: '.',
	    191: '/',
	    192: '`',
	    219: '[',
	    220: '\\',
	    221: ']',
	    222: '\''
	});
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The global keyboard layout instance.
	     */
	    Private.keyboardLayout = exports.EN_US;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/keyboard@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/virtualdom@1.1.1/lib/index.js **/
jupyter.define('@phosphor/virtualdom@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	/**
	 * A virtual node which represents plain text content.
	 *
	 * #### Notes
	 * User code will not typically create a `VirtualText` node directly.
	 * Instead, the `h()` function will be used to create an element tree.
	 */
	var VirtualText = (function () {
	    /**
	     * Construct a new virtual text node.
	     *
	     * @param content - The text content for the node.
	     */
	    function VirtualText(content) {
	        /**
	         * The type of the node.
	         *
	         * This value can be used as a type guard for discriminating the
	         * `VirtualNode` union type.
	         */
	        this.type = 'text';
	        this.content = content;
	    }
	    return VirtualText;
	}());
	exports.VirtualText = VirtualText;
	/**
	 * A virtual node which represents an HTML element.
	 *
	 * #### Notes
	 * User code will not typically create a `VirtualElement` node directly.
	 * Instead, the `h()` function will be used to create an element tree.
	 */
	var VirtualElement = (function () {
	    /**
	     * Construct a new virtual element node.
	     *
	     * @param tag - The element tag name.
	     *
	     * @param attrs - The element attributes.
	     *
	     * @param children - The element children.
	     */
	    function VirtualElement(tag, attrs, children) {
	        /**
	         * The type of the node.
	         *
	         * This value can be used as a type guard for discriminating the
	         * `VirtualNode` union type.
	         */
	        this.type = 'element';
	        this.tag = tag;
	        this.attrs = attrs;
	        this.children = children;
	    }
	    return VirtualElement;
	}());
	exports.VirtualElement = VirtualElement;
	function h(tag) {
	    var attrs = {};
	    var children = [];
	    for (var i = 1, n = arguments.length; i < n; ++i) {
	        var arg = arguments[i];
	        if (typeof arg === 'string') {
	            children.push(new VirtualText(arg));
	        }
	        else if (arg instanceof VirtualText) {
	            children.push(arg);
	        }
	        else if (arg instanceof VirtualElement) {
	            children.push(arg);
	        }
	        else if (arg instanceof Array) {
	            extend(children, arg);
	        }
	        else if (i === 1 && arg && typeof arg === 'object') {
	            attrs = arg;
	        }
	    }
	    return new VirtualElement(tag, attrs, children);
	    function extend(array, values) {
	        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
	            var child = values_1[_i];
	            if (typeof child === 'string') {
	                array.push(new VirtualText(child));
	            }
	            else if (child instanceof VirtualText) {
	                array.push(child);
	            }
	            else if (child instanceof VirtualElement) {
	                array.push(child);
	            }
	        }
	    }
	}
	exports.h = h;
	/**
	 * The namespace for the `h` function statics.
	 */
	(function (h) {
	    h.a = h.bind(undefined, 'a');
	    h.abbr = h.bind(undefined, 'abbr');
	    h.address = h.bind(undefined, 'address');
	    h.area = h.bind(undefined, 'area');
	    h.article = h.bind(undefined, 'article');
	    h.aside = h.bind(undefined, 'aside');
	    h.audio = h.bind(undefined, 'audio');
	    h.b = h.bind(undefined, 'b');
	    h.bdi = h.bind(undefined, 'bdi');
	    h.bdo = h.bind(undefined, 'bdo');
	    h.blockquote = h.bind(undefined, 'blockquote');
	    h.br = h.bind(undefined, 'br');
	    h.button = h.bind(undefined, 'button');
	    h.canvas = h.bind(undefined, 'canvas');
	    h.caption = h.bind(undefined, 'caption');
	    h.cite = h.bind(undefined, 'cite');
	    h.code = h.bind(undefined, 'code');
	    h.col = h.bind(undefined, 'col');
	    h.colgroup = h.bind(undefined, 'colgroup');
	    h.data = h.bind(undefined, 'data');
	    h.datalist = h.bind(undefined, 'datalist');
	    h.dd = h.bind(undefined, 'dd');
	    h.del = h.bind(undefined, 'del');
	    h.dfn = h.bind(undefined, 'dfn');
	    h.div = h.bind(undefined, 'div');
	    h.dl = h.bind(undefined, 'dl');
	    h.dt = h.bind(undefined, 'dt');
	    h.em = h.bind(undefined, 'em');
	    h.embed = h.bind(undefined, 'embed');
	    h.fieldset = h.bind(undefined, 'fieldset');
	    h.figcaption = h.bind(undefined, 'figcaption');
	    h.figure = h.bind(undefined, 'figure');
	    h.footer = h.bind(undefined, 'footer');
	    h.form = h.bind(undefined, 'form');
	    h.h1 = h.bind(undefined, 'h1');
	    h.h2 = h.bind(undefined, 'h2');
	    h.h3 = h.bind(undefined, 'h3');
	    h.h4 = h.bind(undefined, 'h4');
	    h.h5 = h.bind(undefined, 'h5');
	    h.h6 = h.bind(undefined, 'h6');
	    h.header = h.bind(undefined, 'header');
	    h.hr = h.bind(undefined, 'hr');
	    h.i = h.bind(undefined, 'i');
	    h.iframe = h.bind(undefined, 'iframe');
	    h.img = h.bind(undefined, 'img');
	    h.input = h.bind(undefined, 'input');
	    h.ins = h.bind(undefined, 'ins');
	    h.kbd = h.bind(undefined, 'kbd');
	    h.label = h.bind(undefined, 'label');
	    h.legend = h.bind(undefined, 'legend');
	    h.li = h.bind(undefined, 'li');
	    h.main = h.bind(undefined, 'main');
	    h.map = h.bind(undefined, 'map');
	    h.mark = h.bind(undefined, 'mark');
	    h.meter = h.bind(undefined, 'meter');
	    h.nav = h.bind(undefined, 'nav');
	    h.noscript = h.bind(undefined, 'noscript');
	    h.object = h.bind(undefined, 'object');
	    h.ol = h.bind(undefined, 'ol');
	    h.optgroup = h.bind(undefined, 'optgroup');
	    h.option = h.bind(undefined, 'option');
	    h.output = h.bind(undefined, 'output');
	    h.p = h.bind(undefined, 'p');
	    h.param = h.bind(undefined, 'param');
	    h.pre = h.bind(undefined, 'pre');
	    h.progress = h.bind(undefined, 'progress');
	    h.q = h.bind(undefined, 'q');
	    h.rp = h.bind(undefined, 'rp');
	    h.rt = h.bind(undefined, 'rt');
	    h.ruby = h.bind(undefined, 'ruby');
	    h.s = h.bind(undefined, 's');
	    h.samp = h.bind(undefined, 'samp');
	    h.section = h.bind(undefined, 'section');
	    h.select = h.bind(undefined, 'select');
	    h.small = h.bind(undefined, 'small');
	    h.source = h.bind(undefined, 'source');
	    h.span = h.bind(undefined, 'span');
	    h.strong = h.bind(undefined, 'strong');
	    h.sub = h.bind(undefined, 'sub');
	    h.summary = h.bind(undefined, 'summary');
	    h.sup = h.bind(undefined, 'sup');
	    h.table = h.bind(undefined, 'table');
	    h.tbody = h.bind(undefined, 'tbody');
	    h.td = h.bind(undefined, 'td');
	    h.textarea = h.bind(undefined, 'textarea');
	    h.tfoot = h.bind(undefined, 'tfoot');
	    h.th = h.bind(undefined, 'th');
	    h.thead = h.bind(undefined, 'thead');
	    h.time = h.bind(undefined, 'time');
	    h.title = h.bind(undefined, 'title');
	    h.tr = h.bind(undefined, 'tr');
	    h.track = h.bind(undefined, 'track');
	    h.u = h.bind(undefined, 'u');
	    h.ul = h.bind(undefined, 'ul');
	    h.var_ = h.bind(undefined, 'var');
	    h.video = h.bind(undefined, 'video');
	    h.wbr = h.bind(undefined, 'wbr');
	})(h = exports.h || (exports.h = {}));
	/**
	 * The namespace for the virtual DOM rendering functions.
	 */
	var VirtualDOM;
	(function (VirtualDOM) {
	    /**
	     * Create a real DOM element from a virtual element node.
	     *
	     * @param node - The virtual element node to realize.
	     *
	     * @returns A new DOM element for the given virtual element node.
	     *
	     * #### Notes
	     * This creates a brand new *real* DOM element with a structure which
	     * matches the given virtual DOM node.
	     *
	     * If virtual diffing is desired, use the `render` function instead.
	     */
	    function realize(node) {
	        return Private.createDOMNode(node);
	    }
	    VirtualDOM.realize = realize;
	    /**
	     * Render virtual DOM content into a host element.
	     *
	     * @param content - The virtual DOM content to render.
	     *
	     * @param host - The host element for the rendered content.
	     *
	     * #### Notes
	     * This renders the delta from the previous rendering. It assumes that
	     * the content of the host element is not manipulated by external code.
	     *
	     * Providing `null` content will clear the rendering.
	     *
	     * Externally modifying the provided content or the host element will
	     * result in undefined rendering behavior.
	     */
	    function render(content, host) {
	        var oldContent = Private.hostMap.get(host) || [];
	        var newContent = Private.asContentArray(content);
	        Private.hostMap.set(host, newContent);
	        Private.updateContent(host, oldContent, newContent);
	    }
	    VirtualDOM.render = render;
	})(VirtualDOM = exports.VirtualDOM || (exports.VirtualDOM = {}));
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A weak mapping of host element to virtual DOM content.
	     */
	    Private.hostMap = new WeakMap();
	    /**
	     * Cast a content value to a content array.
	     */
	    function asContentArray(value) {
	        if (!value) {
	            return [];
	        }
	        if (value instanceof Array) {
	            return value;
	        }
	        return [value];
	    }
	    Private.asContentArray = asContentArray;
	    function createDOMNode(node) {
	        // Create a text node for a virtual text node.
	        if (node.type === 'text') {
	            return document.createTextNode(node.content);
	        }
	        // Create the HTML element with the specified tag.
	        var element = document.createElement(node.tag);
	        // Add the attributes for the new element.
	        addAttrs(element, node.attrs);
	        // Recursively populate the element with child content.
	        for (var i = 0, n = node.children.length; i < n; ++i) {
	            element.appendChild(createDOMNode(node.children[i]));
	        }
	        // Return the populated element.
	        return element;
	    }
	    Private.createDOMNode = createDOMNode;
	    /**
	     * Update a host element with the delta of the virtual content.
	     *
	     * This is the core "diff" algorithm. There is no explicit "patch"
	     * phase. The host is patched at each step as the diff progresses.
	     */
	    function updateContent(host, oldContent, newContent) {
	        // Bail early if the content is identical.
	        if (oldContent === newContent) {
	            return;
	        }
	        // Collect the old keyed elems into a mapping.
	        var oldKeyed = collectKeys(host, oldContent);
	        // Create a copy of the old content which can be modified in-place.
	        var oldCopy = oldContent.slice();
	        // Update the host with the new content. The diff always proceeds
	        // forward and never modifies a previously visited index. The old
	        // copy array is modified in-place to reflect the changes made to
	        // the host children. This causes the stale nodes to be pushed to
	        // the end of the host node and removed at the end of the loop.
	        var currElem = host.firstChild;
	        var newCount = newContent.length;
	        for (var i = 0; i < newCount; ++i) {
	            // If the old content is exhausted, create a new node.
	            if (i >= oldCopy.length) {
	                host.appendChild(createDOMNode(newContent[i]));
	                continue;
	            }
	            // Lookup the old and new virtual nodes.
	            var oldVNode = oldCopy[i];
	            var newVNode = newContent[i];
	            // If both elements are identical, there is nothing to do.
	            if (oldVNode === newVNode) {
	                currElem = currElem.nextSibling;
	                continue;
	            }
	            // Handle the simplest case of in-place text update first.
	            if (oldVNode.type === 'text' && newVNode.type === 'text') {
	                currElem.textContent = newVNode.content;
	                currElem = currElem.nextSibling;
	                continue;
	            }
	            // If the old or new node is a text node, the other node is now
	            // known to be an element node, so create and insert a new node.
	            if (oldVNode.type === 'text' || newVNode.type === 'text') {
	                algorithm_1.ArrayExt.insert(oldCopy, i, newVNode);
	                host.insertBefore(createDOMNode(newVNode), currElem);
	                continue;
	            }
	            // At this point, both nodes are known to be element nodes.
	            // If the new elem is keyed, move an old keyed elem to the proper
	            // location before proceeding with the diff. The search can start
	            // at the current index, since the unmatched old keyed elems are
	            // pushed forward in the old copy array.
	            var newKey = newVNode.attrs.key;
	            if (newKey && newKey in oldKeyed) {
	                var pair = oldKeyed[newKey];
	                if (pair.vNode !== oldVNode) {
	                    algorithm_1.ArrayExt.move(oldCopy, oldCopy.indexOf(pair.vNode, i + 1), i);
	                    host.insertBefore(pair.element, currElem);
	                    oldVNode = pair.vNode;
	                    currElem = pair.element;
	                }
	            }
	            // If both elements are identical, there is nothing to do.
	            if (oldVNode === newVNode) {
	                currElem = currElem.nextSibling;
	                continue;
	            }
	            // If the old elem is keyed and does not match the new elem key,
	            // create a new node. This is necessary since the old keyed elem
	            // may be matched at a later point in the diff.
	            var oldKey = oldVNode.attrs.key;
	            if (oldKey && oldKey !== newKey) {
	                algorithm_1.ArrayExt.insert(oldCopy, i, newVNode);
	                host.insertBefore(createDOMNode(newVNode), currElem);
	                continue;
	            }
	            // If the tags are different, create a new node.
	            if (oldVNode.tag !== newVNode.tag) {
	                algorithm_1.ArrayExt.insert(oldCopy, i, newVNode);
	                host.insertBefore(createDOMNode(newVNode), currElem);
	                continue;
	            }
	            // At this point, the element can be updated in-place.
	            // Update the element attributes.
	            updateAttrs(currElem, oldVNode.attrs, newVNode.attrs);
	            // Update the element content.
	            updateContent(currElem, oldVNode.children, newVNode.children);
	            // Step to the next sibling element.
	            currElem = currElem.nextSibling;
	        }
	        // Dispose of the old nodes pushed to the end of the host.
	        for (var i = oldCopy.length - newCount; i > 0; --i) {
	            host.removeChild(host.lastChild);
	        }
	    }
	    Private.updateContent = updateContent;
	    /**
	     * A set of special-cased attribute names.
	     */
	    var specialAttrs = {
	        'key': true,
	        'className': true,
	        'htmlFor': true,
	        'dataset': true,
	        'style': true,
	    };
	    /**
	     * Add element attributes to a newly created HTML element.
	     */
	    function addAttrs(element, attrs) {
	        // Add the inline event listeners and node attributes.
	        for (var name_1 in attrs) {
	            if (name_1 in specialAttrs) {
	                continue;
	            }
	            if (name_1.substr(0, 2) === 'on') {
	                element[name_1] = attrs[name_1];
	            }
	            else {
	                element.setAttribute(name_1, attrs[name_1]);
	            }
	        }
	        // Add the element `class` attribute.
	        if (attrs.className !== undefined) {
	            element.setAttribute('class', attrs.className);
	        }
	        // Add the element `for` attribute.
	        if (attrs.htmlFor !== undefined) {
	            element.setAttribute('for', attrs.htmlFor);
	        }
	        // Add the dataset values.
	        if (attrs.dataset) {
	            addDataset(element, attrs.dataset);
	        }
	        // Add the inline styles.
	        if (attrs.style) {
	            addStyle(element, attrs.style);
	        }
	    }
	    /**
	     * Update the element attributes of an HTML element.
	     */
	    function updateAttrs(element, oldAttrs, newAttrs) {
	        // Do nothing if the attrs are the same object.
	        if (oldAttrs === newAttrs) {
	            return;
	        }
	        // Setup the strongly typed loop variable.
	        var name;
	        // Remove attributes and listeners which no longer exist.
	        for (name in oldAttrs) {
	            if (name in specialAttrs || name in newAttrs) {
	                continue;
	            }
	            if (name.substr(0, 2) === 'on') {
	                element[name] = null;
	            }
	            else {
	                element.removeAttribute(name);
	            }
	        }
	        // Add and update new and existing attributes and listeners.
	        for (name in newAttrs) {
	            if (name in specialAttrs || oldAttrs[name] === newAttrs[name]) {
	                continue;
	            }
	            if (name.substr(0, 2) === 'on') {
	                element[name] = newAttrs[name];
	            }
	            else {
	                element.setAttribute(name, newAttrs[name]);
	            }
	        }
	        // Update the element `class` attribute.
	        if (oldAttrs.className !== newAttrs.className) {
	            if (newAttrs.className !== undefined) {
	                element.setAttribute('class', newAttrs.className);
	            }
	            else {
	                element.removeAttribute('class');
	            }
	        }
	        // Add the element `for` attribute.
	        if (oldAttrs.htmlFor !== newAttrs.htmlFor) {
	            if (newAttrs.htmlFor !== undefined) {
	                element.setAttribute('for', newAttrs.htmlFor);
	            }
	            else {
	                element.removeAttribute('for');
	            }
	        }
	        // Update the dataset values.
	        if (oldAttrs.dataset !== newAttrs.dataset) {
	            updateDataset(element, oldAttrs.dataset || {}, newAttrs.dataset || {});
	        }
	        // Update the inline styles.
	        if (oldAttrs.style !== newAttrs.style) {
	            updateStyle(element, oldAttrs.style || {}, newAttrs.style || {});
	        }
	    }
	    /**
	     * Add dataset values to a newly created HTML element.
	     */
	    function addDataset(element, dataset) {
	        for (var name_2 in dataset) {
	            element.setAttribute("data-" + name_2, dataset[name_2]);
	        }
	    }
	    /**
	     * Update the dataset values of an HTML element.
	     */
	    function updateDataset(element, oldDataset, newDataset) {
	        for (var name_3 in oldDataset) {
	            if (!(name_3 in newDataset)) {
	                element.removeAttribute("data-" + name_3);
	            }
	        }
	        for (var name_4 in newDataset) {
	            if (oldDataset[name_4] !== newDataset[name_4]) {
	                element.setAttribute("data-" + name_4, newDataset[name_4]);
	            }
	        }
	    }
	    /**
	     * Add inline style values to a newly created HTML element.
	     */
	    function addStyle(element, style) {
	        var elemStyle = element.style;
	        var name;
	        for (name in style) {
	            elemStyle[name] = style[name];
	        }
	    }
	    /**
	     * Update the inline style values of an HTML element.
	     */
	    function updateStyle(element, oldStyle, newStyle) {
	        var elemStyle = element.style;
	        var name;
	        for (name in oldStyle) {
	            if (!(name in newStyle)) {
	                elemStyle[name] = '';
	            }
	        }
	        for (name in newStyle) {
	            if (oldStyle[name] !== newStyle[name]) {
	                elemStyle[name] = newStyle[name];
	            }
	        }
	    }
	    /**
	     * Collect a mapping of keyed elements for the host content.
	     */
	    function collectKeys(host, content) {
	        var node = host.firstChild;
	        var keyMap = Object.create(null);
	        for (var _i = 0, content_1 = content; _i < content_1.length; _i++) {
	            var vNode = content_1[_i];
	            if (vNode.type === 'element' && vNode.attrs.key) {
	                keyMap[vNode.attrs.key] = { vNode: vNode, element: node };
	            }
	            node = node.nextSibling;
	        }
	        return keyMap;
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/virtualdom@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/contextmenu.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/contextmenu.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var menu_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/menu.js');
	/**
	 * An object which implements a universal context menu.
	 *
	 * #### Notes
	 * The items shown in the context menu are determined by CSS selector
	 * matching against the DOM hierarchy at the site of the mouse click.
	 * This is similar in concept to how keyboard shortcuts are matched
	 * in the command registry.
	 */
	var ContextMenu = (function () {
	    /**
	     * Construct a new context menu.
	     *
	     * @param options - The options for initializing the menu.
	     */
	    function ContextMenu(options) {
	        this._idTick = 0;
	        this._items = [];
	        this.menu = new menu_1.Menu(options);
	    }
	    /**
	     * Add an item to the context menu.
	     *
	     * @param options - The options for creating the item.
	     *
	     * @returns A disposable which will remove the item from the menu.
	     */
	    ContextMenu.prototype.addItem = function (options) {
	        var _this = this;
	        // Create an item from the given options.
	        var item = Private.createItem(options, this._idTick++);
	        // Add the item to the internal array.
	        this._items.push(item);
	        // Return a disposable which will remove the item.
	        return new disposable_1.DisposableDelegate(function () {
	            algorithm_1.ArrayExt.removeFirstOf(_this._items, item);
	        });
	    };
	    /**
	     * Open the context menu in response to a `'contextmenu'` event.
	     *
	     * @param event - The `'contextmenu'` event of interest.
	     *
	     * @returns `true` if the menu was opened, or `false` if no items
	     *   matched the event and the menu was not opened.
	     *
	     * #### Notes
	     * This method will populate the context menu with items which match
	     * the propagation path of the event, then open the menu at the mouse
	     * position indicated by the event.
	     */
	    ContextMenu.prototype.open = function (event) {
	        var _this = this;
	        // Clear the current contents of the context menu.
	        this.menu.clearItems();
	        // Bail early if there are no items to match.
	        if (this._items.length === 0) {
	            return false;
	        }
	        // Find the matching items for the event.
	        var items = Private.matchItems(this._items, event);
	        // Bail if there are no matching items.
	        if (!items || items.length === 0) {
	            return false;
	        }
	        // Add the filtered items to the menu.
	        algorithm_1.each(items, function (item) { _this.menu.addItem(item); });
	        // Open the context menu at the current mouse position.
	        this.menu.open(event.clientX, event.clientY);
	        // Indicate success.
	        return true;
	    };
	    return ContextMenu;
	}());
	exports.ContextMenu = ContextMenu;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a normalized context menu item from an options object.
	     */
	    function createItem(options, id) {
	        var selector = validateSelector(options.selector);
	        var rank = options.rank !== undefined ? options.rank : Infinity;
	        return __assign({}, options, { selector: selector, rank: rank, id: id });
	    }
	    Private.createItem = createItem;
	    /**
	     * Find the items which match a context menu event.
	     *
	     * The results are sorted by DOM level, specificity, and rank.
	     */
	    function matchItems(items, event) {
	        // Look up the target of the event.
	        var target = event.target;
	        // Bail if there is no target.
	        if (!target) {
	            return null;
	        }
	        // Look up the current target of the event.
	        var currentTarget = event.currentTarget;
	        // Bail if there is no current target.
	        if (!currentTarget) {
	            return null;
	        }
	        // There are some third party libraries that cause the `target` to
	        // be detached from the DOM before Phosphor can process the event.
	        // If that happens, search for a new target node by point. If that
	        // node is still dangling, bail.
	        if (!currentTarget.contains(target)) {
	            target = document.elementFromPoint(event.clientX, event.clientY);
	            if (!target || !currentTarget.contains(target)) {
	                return null;
	            }
	        }
	        // Set up the result array.
	        var result = [];
	        // Copy the items array to allow in-place modification.
	        var availableItems = items.slice();
	        // Walk up the DOM hierarchy searching for matches.
	        while (target !== null) {
	            // Set up the match array for this DOM level.
	            var matches = [];
	            // Search the remaining items for matches.
	            for (var i = 0, n = availableItems.length; i < n; ++i) {
	                // Fetch the item.
	                var item = availableItems[i];
	                // Skip items which are already consumed.
	                if (!item) {
	                    continue;
	                }
	                // Skip items which do not match the element.
	                if (!domutils_1.Selector.matches(target, item.selector)) {
	                    continue;
	                }
	                // Add the matched item to the result for this DOM level.
	                matches.push(item);
	                // Mark the item as consumed.
	                availableItems[i] = null;
	            }
	            // Sort the matches for this level and add them to the results.
	            if (matches.length !== 0) {
	                matches.sort(itemCmp);
	                result.push.apply(result, matches);
	            }
	            // Stop searching at the limits of the DOM range.
	            if (target === currentTarget) {
	                break;
	            }
	            // Step to the parent DOM level.
	            target = target.parentElement;
	        }
	        // Return the matched and sorted results.
	        return result;
	    }
	    Private.matchItems = matchItems;
	    /**
	     * Validate the selector for a menu item.
	     *
	     * This returns the validated selector, or throws if the selector is
	     * invalid or contains commas.
	     */
	    function validateSelector(selector) {
	        if (selector.indexOf(',') !== -1) {
	            throw new Error("Selector cannot contain commas: " + selector);
	        }
	        if (!domutils_1.Selector.isValid(selector)) {
	            throw new Error("Invalid selector: " + selector);
	        }
	        return selector;
	    }
	    /**
	     * A sort comparison function for a context menu item.
	     */
	    function itemCmp(a, b) {
	        // Sort first based on selector specificity.
	        var s1 = domutils_1.Selector.calculateSpecificity(a.selector);
	        var s2 = domutils_1.Selector.calculateSpecificity(b.selector);
	        if (s1 !== s2) {
	            return s2 - s1;
	        }
	        // If specificities are equal, sort based on rank.
	        var r1 = a.rank;
	        var r2 = b.rank;
	        if (r1 !== r2) {
	            return r1 < r2 ? -1 : 1; // Infinity-safe
	        }
	        // When all else fails, sort by item id.
	        return a.id - b.id;
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/contextmenu.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/menu.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/menu.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var commands_1 = __jupyter_require__('@phosphor/commands@^1.2.1/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var keyboard_1 = __jupyter_require__('@phosphor/keyboard@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var virtualdom_1 = __jupyter_require__('@phosphor/virtualdom@^1.1.1/lib/index.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A widget which displays items as a canonical menu.
	 */
	var Menu = (function (_super) {
	    __extends(Menu, _super);
	    /**
	     * Construct a new menu.
	     *
	     * @param options - The options for initializing the menu.
	     */
	    function Menu(options) {
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._childIndex = -1;
	        _this._activeIndex = -1;
	        _this._openTimerID = 0;
	        _this._closeTimerID = 0;
	        _this._items = [];
	        _this._childMenu = null;
	        _this._parentMenu = null;
	        _this._aboutToClose = new signaling_1.Signal(_this);
	        _this._menuRequested = new signaling_1.Signal(_this);
	        _this.addClass('p-Menu');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.commands = options.commands;
	        _this.renderer = options.renderer || Menu.defaultRenderer;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the menu.
	     */
	    Menu.prototype.dispose = function () {
	        this.close();
	        this._items.length = 0;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(Menu.prototype, "aboutToClose", {
	        /**
	         * A signal emitted just before the menu is closed.
	         *
	         * #### Notes
	         * This signal is emitted when the menu receives a `'close-request'`
	         * message, just before it removes itself from the DOM.
	         *
	         * This signal is not emitted if the menu is already detached from
	         * the DOM when it receives the `'close-request'` message.
	         */
	        get: function () {
	            return this._aboutToClose;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "menuRequested", {
	        /**
	         * A signal emitted when a new menu is requested by the user.
	         *
	         * #### Notes
	         * This signal is emitted whenever the user presses the right or left
	         * arrow keys, and a submenu cannot be opened or closed in response.
	         *
	         * This signal is useful when implementing menu bars in order to open
	         * the next or previous menu in response to a user key press.
	         *
	         * This signal is only emitted for the root menu in a hierarchy.
	         */
	        get: function () {
	            return this._menuRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "parentMenu", {
	        /**
	         * The parent menu of the menu.
	         *
	         * #### Notes
	         * This is `null` unless the menu is an open submenu.
	         */
	        get: function () {
	            return this._parentMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "childMenu", {
	        /**
	         * The child menu of the menu.
	         *
	         * #### Notes
	         * This is `null` unless the menu has an open submenu.
	         */
	        get: function () {
	            return this._childMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "rootMenu", {
	        /**
	         * The root menu of the menu hierarchy.
	         */
	        get: function () {
	            var menu = this;
	            while (menu._parentMenu) {
	                menu = menu._parentMenu;
	            }
	            return menu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "leafMenu", {
	        /**
	         * The leaf menu of the menu hierarchy.
	         */
	        get: function () {
	            var menu = this;
	            while (menu._childMenu) {
	                menu = menu._childMenu;
	            }
	            return menu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "contentNode", {
	        /**
	         * The menu content node.
	         *
	         * #### Notes
	         * This is the node which holds the menu item nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-Menu-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "activeItem", {
	        /**
	         * Get the currently active menu item.
	         */
	        get: function () {
	            return this._items[this._activeIndex] || null;
	        },
	        /**
	         * Set the currently active menu item.
	         *
	         * #### Notes
	         * If the item cannot be activated, the item will be set to `null`.
	         */
	        set: function (value) {
	            this.activeIndex = value ? this._items.indexOf(value) : -1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "activeIndex", {
	        /**
	         * Get the index of the currently active menu item.
	         *
	         * #### Notes
	         * This will be `-1` if no menu item is active.
	         */
	        get: function () {
	            return this._activeIndex;
	        },
	        /**
	         * Set the index of the currently active menu item.
	         *
	         * #### Notes
	         * If the item cannot be activated, the index will be set to `-1`.
	         */
	        set: function (value) {
	            // Adjust the value for an out of range index.
	            if (value < 0 || value >= this._items.length) {
	                value = -1;
	            }
	            // Ensure the item can be activated.
	            if (value !== -1 && !Private.canActivate(this._items[value])) {
	                value = -1;
	            }
	            // Bail if the index will not change.
	            if (this._activeIndex === value) {
	                return;
	            }
	            // Update the active index.
	            this._activeIndex = value;
	            // schedule an update of the items.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Menu.prototype, "items", {
	        /**
	         * A read-only array of the menu items in the menu.
	         */
	        get: function () {
	            return this._items;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Activate the next selectable item in the menu.
	     *
	     * #### Notes
	     * If no item is selectable, the index will be set to `-1`.
	     */
	    Menu.prototype.activateNextItem = function () {
	        var n = this._items.length;
	        var ai = this._activeIndex;
	        var start = ai < n - 1 ? ai + 1 : 0;
	        var stop = start === 0 ? n - 1 : start - 1;
	        this.activeIndex = algorithm_1.ArrayExt.findFirstIndex(this._items, Private.canActivate, start, stop);
	    };
	    /**
	     * Activate the previous selectable item in the menu.
	     *
	     * #### Notes
	     * If no item is selectable, the index will be set to `-1`.
	     */
	    Menu.prototype.activatePreviousItem = function () {
	        var n = this._items.length;
	        var ai = this._activeIndex;
	        var start = ai <= 0 ? n - 1 : ai - 1;
	        var stop = start === n - 1 ? 0 : start + 1;
	        this.activeIndex = algorithm_1.ArrayExt.findLastIndex(this._items, Private.canActivate, start, stop);
	    };
	    /**
	     * Trigger the active menu item.
	     *
	     * #### Notes
	     * If the active item is a submenu, it will be opened and the first
	     * item will be activated.
	     *
	     * If the active item is a command, the command will be executed.
	     *
	     * If the menu is not attached, this is a no-op.
	     *
	     * If there is no active item, this is a no-op.
	     */
	    Menu.prototype.triggerActiveItem = function () {
	        // Bail if the menu is not attached.
	        if (!this.isAttached) {
	            return;
	        }
	        // Bail if there is no active item.
	        var item = this.activeItem;
	        if (!item) {
	            return;
	        }
	        // Cancel the pending timers.
	        this._cancelOpenTimer();
	        this._cancelCloseTimer();
	        // If the item is a submenu, open it.
	        if (item.type === 'submenu') {
	            this._openChildMenu(true);
	            return;
	        }
	        // Close the root menu before executing the command.
	        this.rootMenu.close();
	        // Execute the command for the item.
	        var command = item.command, args = item.args;
	        if (this.commands.isEnabled(command, args)) {
	            this.commands.execute(command, args);
	        }
	        else {
	            console.log("Command '" + command + "' is disabled.");
	        }
	    };
	    /**
	     * Add a menu item to the end of the menu.
	     *
	     * @param options - The options for creating the menu item.
	     *
	     * @returns The menu item added to the menu.
	     */
	    Menu.prototype.addItem = function (options) {
	        return this.insertItem(this._items.length, options);
	    };
	    /**
	     * Insert a menu item into the menu at the specified index.
	     *
	     * @param index - The index at which to insert the item.
	     *
	     * @param options - The options for creating the menu item.
	     *
	     * @returns The menu item added to the menu.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the items.
	     */
	    Menu.prototype.insertItem = function (index, options) {
	        // Close the menu if it's attached.
	        if (this.isAttached) {
	            this.close();
	        }
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Clamp the insert index to the array bounds.
	        var i = Math.max(0, Math.min(index, this._items.length));
	        // Create the item for the options.
	        var item = Private.createItem(this, options);
	        // Insert the item into the array.
	        algorithm_1.ArrayExt.insert(this._items, i, item);
	        // Schedule an update of the items.
	        this.update();
	        // Return the item added to the menu.
	        return item;
	    };
	    /**
	     * Remove an item from the menu.
	     *
	     * @param item - The item to remove from the menu.
	     *
	     * #### Notes
	     * This is a no-op if the item is not in the menu.
	     */
	    Menu.prototype.removeItem = function (item) {
	        this.removeItemAt(this._items.indexOf(item));
	    };
	    /**
	     * Remove the item at a given index from the menu.
	     *
	     * @param index - The index of the item to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    Menu.prototype.removeItemAt = function (index) {
	        // Close the menu if it's attached.
	        if (this.isAttached) {
	            this.close();
	        }
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Remove the item from the array.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Bail if the index is out of range.
	        if (!item) {
	            return;
	        }
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Remove all menu items from the menu.
	     */
	    Menu.prototype.clearItems = function () {
	        // Close the menu if it's attached.
	        if (this.isAttached) {
	            this.close();
	        }
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Bail if there is nothing to remove.
	        if (this._items.length === 0) {
	            return;
	        }
	        // Clear the items.
	        this._items.length = 0;
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Open the menu at the specified location.
	     *
	     * @param x - The client X coordinate of the menu location.
	     *
	     * @param y - The client Y coordinate of the menu location.
	     *
	     * @param options - The additional options for opening the menu.
	     *
	     * #### Notes
	     * The menu will be opened at the given location unless it will not
	     * fully fit on the screen. If it will not fit, it will be adjusted
	     * to fit naturally on the screen.
	     *
	     * This is a no-op if the menu is already attached to the DOM.
	     */
	    Menu.prototype.open = function (x, y, options) {
	        if (options === void 0) { options = {}; }
	        // Bail early if the menu is already attached.
	        if (this.isAttached) {
	            return;
	        }
	        // Extract the position options.
	        var forceX = options.forceX || false;
	        var forceY = options.forceY || false;
	        // Open the menu as a root menu.
	        Private.openRootMenu(this, x, y, forceX, forceY);
	        // Activate the menu to accept keyboard input.
	        this.activate();
	    };
	    /**
	     * Handle the DOM events for the menu.
	     *
	     * @param event - The DOM event sent to the menu.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the menu's DOM nodes. It should
	     * not be called directly by user code.
	     */
	    Menu.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseenter':
	                this._evtMouseEnter(event);
	                break;
	            case 'mouseleave':
	                this._evtMouseLeave(event);
	                break;
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    Menu.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('keydown', this);
	        this.node.addEventListener('mouseup', this);
	        this.node.addEventListener('mousemove', this);
	        this.node.addEventListener('mouseenter', this);
	        this.node.addEventListener('mouseleave', this);
	        this.node.addEventListener('contextmenu', this);
	        document.addEventListener('mousedown', this, true);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    Menu.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('keydown', this);
	        this.node.removeEventListener('mouseup', this);
	        this.node.removeEventListener('mousemove', this);
	        this.node.removeEventListener('mouseenter', this);
	        this.node.removeEventListener('mouseleave', this);
	        this.node.removeEventListener('contextmenu', this);
	        document.removeEventListener('mousedown', this, true);
	    };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     */
	    Menu.prototype.onActivateRequest = function (msg) {
	        if (this.isAttached) {
	            this.node.focus();
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    Menu.prototype.onUpdateRequest = function (msg) {
	        var items = this._items;
	        var renderer = this.renderer;
	        var activeIndex = this._activeIndex;
	        var collapsedFlags = Private.computeCollapsed(items);
	        var content = new Array(items.length);
	        for (var i = 0, n = items.length; i < n; ++i) {
	            var item = items[i];
	            var active = i === activeIndex;
	            var collapsed = collapsedFlags[i];
	            content[i] = renderer.renderItem({ item: item, active: active, collapsed: collapsed });
	        }
	        virtualdom_1.VirtualDOM.render(content, this.contentNode);
	    };
	    /**
	     * A message handler invoked on a `'close-request'` message.
	     */
	    Menu.prototype.onCloseRequest = function (msg) {
	        // Cancel the pending timers.
	        this._cancelOpenTimer();
	        this._cancelCloseTimer();
	        // Reset the active index.
	        this.activeIndex = -1;
	        // Close any open child menu.
	        var childMenu = this._childMenu;
	        if (childMenu) {
	            this._childIndex = -1;
	            this._childMenu = null;
	            childMenu._parentMenu = null;
	            childMenu.close();
	        }
	        // Remove this menu from its parent and activate the parent.
	        var parentMenu = this._parentMenu;
	        if (parentMenu) {
	            this._parentMenu = null;
	            parentMenu._childIndex = -1;
	            parentMenu._childMenu = null;
	            parentMenu.activate();
	        }
	        // Emit the `aboutToClose` signal if the menu is attached.
	        if (this.isAttached) {
	            this._aboutToClose.emit(undefined);
	        }
	        // Finish closing the menu.
	        _super.prototype.onCloseRequest.call(this, msg);
	    };
	    /**
	     * Handle the `'keydown'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtKeyDown = function (event) {
	        // A menu handles all keydown events.
	        event.preventDefault();
	        event.stopPropagation();
	        // Fetch the key code for the event.
	        var kc = event.keyCode;
	        // Enter
	        if (kc === 13) {
	            this.triggerActiveItem();
	            return;
	        }
	        // Escape
	        if (kc === 27) {
	            this.close();
	            return;
	        }
	        // Left Arrow
	        if (kc === 37) {
	            if (this._parentMenu) {
	                this.close();
	            }
	            else {
	                this._menuRequested.emit('previous');
	            }
	            return;
	        }
	        // Up Arrow
	        if (kc === 38) {
	            this.activatePreviousItem();
	            return;
	        }
	        // Right Arrow
	        if (kc === 39) {
	            var item = this.activeItem;
	            if (item && item.type === 'submenu') {
	                this.triggerActiveItem();
	            }
	            else {
	                this.rootMenu._menuRequested.emit('next');
	            }
	            return;
	        }
	        // Down Arrow
	        if (kc === 40) {
	            this.activateNextItem();
	            return;
	        }
	        // Get the pressed key character.
	        var key = keyboard_1.getKeyboardLayout().keyForKeydownEvent(event);
	        // Bail if the key is not valid.
	        if (!key) {
	            return;
	        }
	        // Search for the next best matching mnemonic item.
	        var start = this._activeIndex + 1;
	        var result = Private.findMnemonic(this._items, key, start);
	        // Handle the requested mnemonic based on the search results.
	        // If exactly one mnemonic is matched, that item is triggered.
	        // Otherwise, the next mnemonic is activated if available,
	        // followed by the auto mnemonic if available.
	        if (result.index !== -1 && !result.multiple) {
	            this.activeIndex = result.index;
	            this.triggerActiveItem();
	        }
	        else if (result.index !== -1) {
	            this.activeIndex = result.index;
	        }
	        else if (result.auto !== -1) {
	            this.activeIndex = result.auto;
	        }
	    };
	    /**
	     * Handle the `'mouseup'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseUp = function (event) {
	        if (event.button !== 0) {
	            return;
	        }
	        event.preventDefault();
	        event.stopPropagation();
	        this.triggerActiveItem();
	    };
	    /**
	     * Handle the `'mousemove'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseMove = function (event) {
	        // Hit test the item nodes for the item under the mouse.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return domutils_1.ElementExt.hitTest(node, event.clientX, event.clientY);
	        });
	        // Bail early if the mouse is already over the active index.
	        if (index === this._activeIndex) {
	            return;
	        }
	        // Update and coerce the active index.
	        this.activeIndex = index;
	        index = this.activeIndex;
	        // If the index is the current child index, cancel the timers.
	        if (index === this._childIndex) {
	            this._cancelOpenTimer();
	            this._cancelCloseTimer();
	            return;
	        }
	        // If a child menu is currently open, start the close timer.
	        if (this._childIndex !== -1) {
	            this._startCloseTimer();
	        }
	        // Cancel the open timer to give a full delay for opening.
	        this._cancelOpenTimer();
	        // Bail if the active item is not a valid submenu item.
	        var item = this.activeItem;
	        if (!item || item.type !== 'submenu' || !item.submenu) {
	            return;
	        }
	        // Start the open timer to open the active item submenu.
	        this._startOpenTimer();
	    };
	    /**
	     * Handle the `'mouseenter'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseEnter = function (event) {
	        // Synchronize the active ancestor items.
	        for (var menu = this._parentMenu; menu; menu = menu._parentMenu) {
	            menu._cancelOpenTimer();
	            menu._cancelCloseTimer();
	            menu.activeIndex = menu._childIndex;
	        }
	    };
	    /**
	     * Handle the `'mouseleave'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the menu node.
	     */
	    Menu.prototype._evtMouseLeave = function (event) {
	        // Cancel any pending submenu opening.
	        this._cancelOpenTimer();
	        // If there is no open child menu, just reset the active index.
	        if (!this._childMenu) {
	            this.activeIndex = -1;
	            return;
	        }
	        // If the mouse is over the child menu, cancel the close timer.
	        var clientX = event.clientX, clientY = event.clientY;
	        if (domutils_1.ElementExt.hitTest(this._childMenu.node, clientX, clientY)) {
	            this._cancelCloseTimer();
	            return;
	        }
	        // Otherwise, reset the active index and start the close timer.
	        this.activeIndex = -1;
	        this._startCloseTimer();
	    };
	    /**
	     * Handle the `'mousedown'` event for the menu.
	     *
	     * #### Notes
	     * This listener is attached to the document node.
	     */
	    Menu.prototype._evtMouseDown = function (event) {
	        // Bail if the menu is not a root menu.
	        if (this._parentMenu) {
	            return;
	        }
	        // The mouse button which is pressed is irrelevant. If the press
	        // is not on a menu, the entire hierarchy is closed and the event
	        // is allowed to propagate. This allows other code to act on the
	        // event, such as focusing the clicked element.
	        if (Private.hitTestMenus(this, event.clientX, event.clientY)) {
	            event.preventDefault();
	            event.stopPropagation();
	        }
	        else {
	            this.close();
	        }
	    };
	    /**
	     * Open the child menu at the active index immediately.
	     *
	     * If a different child menu is already open, it will be closed,
	     * even if the active item is not a valid submenu.
	     */
	    Menu.prototype._openChildMenu = function (activateFirst) {
	        if (activateFirst === void 0) { activateFirst = false; }
	        // If the item is not a valid submenu, close the child menu.
	        var item = this.activeItem;
	        if (!item || item.type !== 'submenu' || !item.submenu) {
	            this._closeChildMenu();
	            return;
	        }
	        // Do nothing if the child menu will not change.
	        var submenu = item.submenu;
	        if (submenu === this._childMenu) {
	            return;
	        }
	        // Ensure the current child menu is closed.
	        this._closeChildMenu();
	        // Update the private child state.
	        this._childMenu = submenu;
	        this._childIndex = this._activeIndex;
	        // Set the parent menu reference for the child.
	        submenu._parentMenu = this;
	        // Ensure the menu is updated and lookup the item node.
	        messaging_1.MessageLoop.sendMessage(this, widget_1.Widget.Msg.UpdateRequest);
	        var itemNode = this.contentNode.children[this._activeIndex];
	        // Open the submenu at the active node.
	        Private.openSubmenu(submenu, itemNode);
	        // Activate the first item if desired.
	        if (activateFirst) {
	            submenu.activeIndex = -1;
	            submenu.activateNextItem();
	        }
	        // Activate the child menu.
	        submenu.activate();
	    };
	    /**
	     * Close the child menu immediately.
	     *
	     * This is a no-op if a child menu is not open.
	     */
	    Menu.prototype._closeChildMenu = function () {
	        if (this._childMenu) {
	            this._childMenu.close();
	        }
	    };
	    /**
	     * Start the open timer, unless it is already pending.
	     */
	    Menu.prototype._startOpenTimer = function () {
	        var _this = this;
	        if (this._openTimerID === 0) {
	            this._openTimerID = setTimeout(function () {
	                _this._openTimerID = 0;
	                _this._openChildMenu();
	            }, Private.TIMER_DELAY);
	        }
	    };
	    /**
	     * Start the close timer, unless it is already pending.
	     */
	    Menu.prototype._startCloseTimer = function () {
	        var _this = this;
	        if (this._closeTimerID === 0) {
	            this._closeTimerID = setTimeout(function () {
	                _this._closeTimerID = 0;
	                _this._closeChildMenu();
	            }, Private.TIMER_DELAY);
	        }
	    };
	    /**
	     * Cancel the open timer, if the timer is pending.
	     */
	    Menu.prototype._cancelOpenTimer = function () {
	        if (this._openTimerID !== 0) {
	            clearTimeout(this._openTimerID);
	            this._openTimerID = 0;
	        }
	    };
	    /**
	     * Cancel the close timer, if the timer is pending.
	     */
	    Menu.prototype._cancelCloseTimer = function () {
	        if (this._closeTimerID !== 0) {
	            clearTimeout(this._closeTimerID);
	            this._closeTimerID = 0;
	        }
	    };
	    return Menu;
	}(widget_1.Widget));
	exports.Menu = Menu;
	/**
	 * The namespace for the `Menu` class statics.
	 */
	(function (Menu) {
	    /**
	     * The default implementation of `IRenderer`.
	     *
	     * #### Notes
	     * Subclasses are free to reimplement rendering methods as needed.
	     */
	    var Renderer = (function () {
	        /**
	         * Construct a new renderer.
	         */
	        function Renderer() {
	        }
	        /**
	         * Render the virtual element for a menu item.
	         *
	         * @param data - The data to use for rendering the item.
	         *
	         * @returns A virtual element representing the item.
	         */
	        Renderer.prototype.renderItem = function (data) {
	            var className = this.createItemClass(data);
	            var dataset = this.createItemDataset(data);
	            return (virtualdom_1.h.li({ className: className, dataset: dataset }, this.renderIcon(data), this.renderLabel(data), this.renderShortcut(data), this.renderSubmenu(data)));
	        };
	        /**
	         * Render the icon element for a menu item.
	         *
	         * @param data - The data to use for rendering the icon.
	         *
	         * @returns A virtual element representing the item icon.
	         */
	        Renderer.prototype.renderIcon = function (data) {
	            var className = this.createIconClass(data);
	            return virtualdom_1.h.div({ className: className }, data.item.iconLabel);
	        };
	        /**
	         * Render the label element for a menu item.
	         *
	         * @param data - The data to use for rendering the label.
	         *
	         * @returns A virtual element representing the item label.
	         */
	        Renderer.prototype.renderLabel = function (data) {
	            var content = this.formatLabel(data);
	            return virtualdom_1.h.div({ className: 'p-Menu-itemLabel' }, content);
	        };
	        /**
	         * Render the shortcut element for a menu item.
	         *
	         * @param data - The data to use for rendering the shortcut.
	         *
	         * @returns A virtual element representing the item shortcut.
	         */
	        Renderer.prototype.renderShortcut = function (data) {
	            var content = this.formatShortcut(data);
	            return virtualdom_1.h.div({ className: 'p-Menu-itemShortcut' }, content);
	        };
	        /**
	         * Render the submenu icon element for a menu item.
	         *
	         * @param data - The data to use for rendering the submenu icon.
	         *
	         * @returns A virtual element representing the submenu icon.
	         */
	        Renderer.prototype.renderSubmenu = function (data) {
	            return virtualdom_1.h.div({ className: 'p-Menu-itemSubmenuIcon' });
	        };
	        /**
	         * Create the class name for the menu item.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the menu item.
	         */
	        Renderer.prototype.createItemClass = function (data) {
	            // Setup the initial class name.
	            var name = 'p-Menu-item';
	            // Add the boolean state classes.
	            if (!data.item.isEnabled) {
	                name += ' p-mod-disabled';
	            }
	            if (data.item.isToggled) {
	                name += ' p-mod-toggled';
	            }
	            if (!data.item.isVisible) {
	                name += ' p-mod-hidden';
	            }
	            if (data.active) {
	                name += ' p-mod-active';
	            }
	            if (data.collapsed) {
	                name += ' p-mod-collapsed';
	            }
	            // Add the extra class.
	            var extra = data.item.className;
	            if (extra) {
	                name += " " + extra;
	            }
	            // Return the complete class name.
	            return name;
	        };
	        /**
	         * Create the dataset for the menu item.
	         *
	         * @param data - The data to use for creating the dataset.
	         *
	         * @returns The dataset for the menu item.
	         */
	        Renderer.prototype.createItemDataset = function (data) {
	            var result;
	            var _a = data.item, type = _a.type, command = _a.command, dataset = _a.dataset;
	            if (type === 'command') {
	                result = __assign({}, dataset, { type: type, command: command });
	            }
	            else {
	                result = __assign({}, dataset, { type: type });
	            }
	            return result;
	        };
	        /**
	         * Create the class name for the menu item icon.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the item icon.
	         */
	        Renderer.prototype.createIconClass = function (data) {
	            var name = 'p-Menu-itemIcon';
	            var extra = data.item.iconClass;
	            return extra ? name + " " + extra : name;
	        };
	        /**
	         * Create the render content for the label node.
	         *
	         * @param data - The data to use for the label content.
	         *
	         * @returns The content to add to the label node.
	         */
	        Renderer.prototype.formatLabel = function (data) {
	            // Fetch the label text and mnemonic index.
	            var _a = data.item, label = _a.label, mnemonic = _a.mnemonic;
	            // If the index is out of range, do not modify the label.
	            if (mnemonic < 0 || mnemonic >= label.length) {
	                return label;
	            }
	            // Split the label into parts.
	            var prefix = label.slice(0, mnemonic);
	            var suffix = label.slice(mnemonic + 1);
	            var char = label[mnemonic];
	            // Wrap the mnemonic character in a span.
	            var span = virtualdom_1.h.span({ className: 'p-Menu-itemMnemonic' }, char);
	            // Return the content parts.
	            return [prefix, span, suffix];
	        };
	        /**
	         * Create the render content for the shortcut node.
	         *
	         * @param data - The data to use for the shortcut content.
	         *
	         * @returns The content to add to the shortcut node.
	         */
	        Renderer.prototype.formatShortcut = function (data) {
	            var kb = data.item.keyBinding;
	            return kb ? kb.keys.map(Private.formatKeystroke).join(', ') : null;
	        };
	        return Renderer;
	    }());
	    Menu.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    Menu.defaultRenderer = new Renderer();
	})(Menu = exports.Menu || (exports.Menu = {}));
	exports.Menu = Menu;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The ms delay for opening and closing a submenu.
	     */
	    Private.TIMER_DELAY = 300;
	    /**
	     * The horizontal pixel overlap for an open submenu.
	     */
	    Private.SUBMENU_OVERLAP = 3;
	    /**
	     * Create the DOM node for a menu.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = 'p-Menu-content';
	        node.appendChild(content);
	        node.tabIndex = -1;
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Test whether a menu item can be activated.
	     */
	    function canActivate(item) {
	        return item.type !== 'separator' && item.isEnabled && item.isVisible;
	    }
	    Private.canActivate = canActivate;
	    /**
	     * Create a new menu item for an owner menu.
	     */
	    function createItem(owner, options) {
	        return new MenuItem(owner.commands, options);
	    }
	    Private.createItem = createItem;
	    /**
	     * Format a keystroke for display on the local system.
	     */
	    function formatKeystroke(keystroke) {
	        var mods = '';
	        var parts = commands_1.CommandRegistry.parseKeystroke(keystroke);
	        if (domutils_1.Platform.IS_MAC) {
	            if (parts.ctrl) {
	                mods += '\u2303 ';
	            }
	            if (parts.alt) {
	                mods += '\u2325 ';
	            }
	            if (parts.shift) {
	                mods += '\u21E7 ';
	            }
	            if (parts.cmd) {
	                mods += '\u2318 ';
	            }
	        }
	        else {
	            if (parts.ctrl) {
	                mods += 'Ctrl+';
	            }
	            if (parts.alt) {
	                mods += 'Alt+';
	            }
	            if (parts.shift) {
	                mods += 'Shift+';
	            }
	        }
	        return mods + parts.key;
	    }
	    Private.formatKeystroke = formatKeystroke;
	    /**
	     * Hit test a menu hierarchy starting at the given root.
	     */
	    function hitTestMenus(menu, x, y) {
	        for (var temp = menu; temp; temp = temp.childMenu) {
	            if (domutils_1.ElementExt.hitTest(temp.node, x, y)) {
	                return true;
	            }
	        }
	        return false;
	    }
	    Private.hitTestMenus = hitTestMenus;
	    /**
	     * Compute which extra separator items should be collapsed.
	     */
	    function computeCollapsed(items) {
	        // Allocate the return array and fill it with `false`.
	        var result = new Array(items.length);
	        algorithm_1.ArrayExt.fill(result, false);
	        // Collapse the leading separators.
	        var k1 = 0;
	        var n = items.length;
	        for (; k1 < n; ++k1) {
	            var item = items[k1];
	            if (!item.isVisible) {
	                continue;
	            }
	            if (item.type !== 'separator') {
	                break;
	            }
	            result[k1] = true;
	        }
	        // Hide the trailing separators.
	        var k2 = n - 1;
	        for (; k2 >= 0; --k2) {
	            var item = items[k2];
	            if (!item.isVisible) {
	                continue;
	            }
	            if (item.type !== 'separator') {
	                break;
	            }
	            result[k2] = true;
	        }
	        // Hide the remaining consecutive separators.
	        var hide = false;
	        while (++k1 < k2) {
	            var item = items[k1];
	            if (!item.isVisible) {
	                continue;
	            }
	            if (item.type !== 'separator') {
	                hide = false;
	            }
	            else if (hide) {
	                result[k1] = true;
	            }
	            else {
	                hide = true;
	            }
	        }
	        // Return the resulting flags.
	        return result;
	    }
	    Private.computeCollapsed = computeCollapsed;
	    /**
	     * Open a menu as a root menu at the target location.
	     */
	    function openRootMenu(menu, x, y, forceX, forceY) {
	        // Ensure the menu is updated before attaching and measuring.
	        messaging_1.MessageLoop.sendMessage(menu, widget_1.Widget.Msg.UpdateRequest);
	        // Get the current position and size of the main viewport.
	        var px = window.pageXOffset;
	        var py = window.pageYOffset;
	        var cw = document.documentElement.clientWidth;
	        var ch = document.documentElement.clientHeight;
	        // Compute the maximum allowed height for the menu.
	        var maxHeight = ch - (forceY ? y : 0);
	        // Fetch common variables.
	        var node = menu.node;
	        var style = node.style;
	        // Clear the menu geometry and prepare it for measuring.
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	        style.visibility = 'hidden';
	        style.maxHeight = maxHeight + "px";
	        // Attach the menu to the document.
	        widget_1.Widget.attach(menu, document.body);
	        // Measure the size of the menu.
	        var _a = node.getBoundingClientRect(), width = _a.width, height = _a.height;
	        // Adjust the X position of the menu to fit on-screen.
	        if (!forceX && (x + width > px + cw)) {
	            x = px + cw - width;
	        }
	        // Adjust the Y position of the menu to fit on-screen.
	        if (!forceY && (y + height > py + ch)) {
	            if (y > py + ch) {
	                y = py + ch - height;
	            }
	            else {
	                y = y - height;
	            }
	        }
	        // Update the position of the menu to the computed position.
	        style.top = Math.max(0, y) + "px";
	        style.left = Math.max(0, x) + "px";
	        // Finally, make the menu visible on the screen.
	        style.visibility = '';
	    }
	    Private.openRootMenu = openRootMenu;
	    /**
	     * Open a menu as a submenu using an item node for positioning.
	     */
	    function openSubmenu(submenu, itemNode) {
	        // Ensure the menu is updated before opening.
	        messaging_1.MessageLoop.sendMessage(submenu, widget_1.Widget.Msg.UpdateRequest);
	        // Get the current position and size of the main viewport.
	        var px = window.pageXOffset;
	        var py = window.pageYOffset;
	        var cw = document.documentElement.clientWidth;
	        var ch = document.documentElement.clientHeight;
	        // Compute the maximum allowed height for the menu.
	        var maxHeight = ch;
	        // Fetch common variables.
	        var node = submenu.node;
	        var style = node.style;
	        // Clear the menu geometry and prepare it for measuring.
	        style.top = '';
	        style.left = '';
	        style.width = '';
	        style.height = '';
	        style.visibility = 'hidden';
	        style.maxHeight = maxHeight + "px";
	        // Attach the menu to the document.
	        widget_1.Widget.attach(submenu, document.body);
	        // Measure the size of the menu.
	        var _a = node.getBoundingClientRect(), width = _a.width, height = _a.height;
	        // Compute the box sizing for the menu.
	        var box = domutils_1.ElementExt.boxSizing(submenu.node);
	        // Get the bounding rect for the target item node.
	        var itemRect = itemNode.getBoundingClientRect();
	        // Compute the target X position.
	        var x = itemRect.right - Private.SUBMENU_OVERLAP;
	        // Adjust the X position to fit on the screen.
	        if (x + width > px + cw) {
	            x = itemRect.left + Private.SUBMENU_OVERLAP - width;
	        }
	        // Compute the target Y position.
	        var y = itemRect.top - box.borderTop - box.paddingTop;
	        // Adjust the Y position to fit on the screen.
	        if (y + height > py + ch) {
	            y = itemRect.bottom + box.borderBottom + box.paddingBottom - height;
	        }
	        // Update the position of the menu to the computed position.
	        style.top = Math.max(0, y) + "px";
	        style.left = Math.max(0, x) + "px";
	        // Finally, make the menu visible on the screen.
	        style.visibility = '';
	    }
	    Private.openSubmenu = openSubmenu;
	    /**
	     * Find the best matching mnemonic item.
	     *
	     * The search starts at the given index and wraps around.
	     */
	    function findMnemonic(items, key, start) {
	        // Setup the result variables.
	        var index = -1;
	        var auto = -1;
	        var multiple = false;
	        // Normalize the key to upper case.
	        var upperKey = key.toUpperCase();
	        // Search the items from the given start index.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Compute the wrapped index.
	            var k = (i + start) % n;
	            // Lookup the item
	            var item = items[k];
	            // Ignore items which cannot be activated.
	            if (!canActivate(item)) {
	                continue;
	            }
	            // Ignore items with an empty label.
	            var label = item.label;
	            if (label.length === 0) {
	                continue;
	            }
	            // Lookup the mnemonic index for the label.
	            var mn = item.mnemonic;
	            // Handle a valid mnemonic index.
	            if (mn >= 0 && mn < label.length) {
	                if (label[mn].toUpperCase() === upperKey) {
	                    if (index === -1) {
	                        index = k;
	                    }
	                    else {
	                        multiple = true;
	                    }
	                }
	                continue;
	            }
	            // Finally, handle the auto index if possible.
	            if (auto === -1 && label[0].toUpperCase() === upperKey) {
	                auto = k;
	            }
	        }
	        // Return the search results.
	        return { index: index, multiple: multiple, auto: auto };
	    }
	    Private.findMnemonic = findMnemonic;
	    /**
	     * A concrete implementation of `Menu.IItem`.
	     */
	    var MenuItem = (function () {
	        /**
	         * Construct a new menu item.
	         */
	        function MenuItem(commands, options) {
	            this._commands = commands;
	            this.type = options.type || 'command';
	            this.command = options.command || '';
	            this.args = options.args || coreutils_1.JSONExt.emptyObject;
	            this.submenu = options.submenu || null;
	        }
	        Object.defineProperty(MenuItem.prototype, "label", {
	            /**
	             * The display label for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.label(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.label;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "mnemonic", {
	            /**
	             * The mnemonic index for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.mnemonic(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.mnemonic;
	                }
	                return -1;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "icon", {
	            /**
	             * @deprecated Use `iconClass` instead.
	             */
	            get: function () {
	                return this.iconClass;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "iconClass", {
	            /**
	             * The icon class for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.iconClass(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.iconClass;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "iconLabel", {
	            /**
	             * The icon label for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.iconLabel(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.iconLabel;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "caption", {
	            /**
	             * The display caption for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.caption(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.caption;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "className", {
	            /**
	             * The extra class name for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.className(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.className;
	                }
	                return '';
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "dataset", {
	            /**
	             * The dataset for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.dataset(this.command, this.args);
	                }
	                if (this.type === 'submenu' && this.submenu) {
	                    return this.submenu.title.dataset;
	                }
	                return {};
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "isEnabled", {
	            /**
	             * Whether the menu item is enabled.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.isEnabled(this.command, this.args);
	                }
	                if (this.type === 'submenu') {
	                    return this.submenu !== null;
	                }
	                return true;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "isToggled", {
	            /**
	             * Whether the menu item is toggled.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.isToggled(this.command, this.args);
	                }
	                return false;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "isVisible", {
	            /**
	             * Whether the menu item is visible.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    return this._commands.isVisible(this.command, this.args);
	                }
	                if (this.type === 'submenu') {
	                    return this.submenu !== null;
	                }
	                return true;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(MenuItem.prototype, "keyBinding", {
	            /**
	             * The key binding for the menu item.
	             */
	            get: function () {
	                if (this.type === 'command') {
	                    var _a = this, command_1 = _a.command, args_1 = _a.args;
	                    return algorithm_1.ArrayExt.findLastValue(this._commands.keyBindings, function (kb) {
	                        return kb.command === command_1 && coreutils_1.JSONExt.deepEqual(kb.args, args_1);
	                    }) || null;
	                }
	                return null;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        return MenuItem;
	    }());
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/menu.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/docklayout.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/docklayout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var boxengine_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/boxengine.js');
	var layout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/layout.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A layout which provides a flexible docking arrangement.
	 *
	 * #### Notes
	 * The consumer of this layout is repsonsible for handling all signals
	 * from the generated tab bars and managing the visibility of widgets
	 * and tab bars as needed.
	 */
	var DockLayout = (function (_super) {
	    __extends(DockLayout, _super);
	    /**
	     * Construct a new dock layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function DockLayout(options) {
	        var _this = _super.call(this) || this;
	        _this._spacing = 4;
	        _this._dirty = false;
	        _this._root = null;
	        _this._box = null;
	        _this._items = new Map();
	        _this.renderer = options.renderer;
	        if (options.spacing !== undefined) {
	            _this._spacing = Private.clampSpacing(options.spacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     *
	     * #### Notes
	     * This will clear and dispose all widgets in the layout.
	     */
	    DockLayout.prototype.dispose = function () {
	        // Get an iterator over the widgets in the layout.
	        var widgets = this.iter();
	        // Dispose of the layout items.
	        this._items.forEach(function (item) { item.dispose(); });
	        // Clear the layout state before disposing the widgets.
	        this._box = null;
	        this._root = null;
	        this._items.clear();
	        // Dispose of the widgets contained in the old layout root.
	        algorithm_1.each(widgets, function (widget) { widget.dispose(); });
	        // Dispose of the base class.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(DockLayout.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the dock layout.
	         */
	        get: function () {
	            return this._spacing;
	        },
	        /**
	         * Set the inter-element spacing for the dock layout.
	         */
	        set: function (value) {
	            value = Private.clampSpacing(value);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockLayout.prototype, "isEmpty", {
	        /**
	         * Whether the dock layout is empty.
	         */
	        get: function () {
	            return this._root === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over all widgets in the layout.
	     *
	     * @returns A new iterator over the widgets in the layout.
	     *
	     * #### Notes
	     * This iterator includes the generated tab bars.
	     */
	    DockLayout.prototype.iter = function () {
	        return this._root ? this._root.iterAllWidgets() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the user widgets in the layout.
	     *
	     * @returns A new iterator over the user widgets in the layout.
	     *
	     * #### Notes
	     * This iterator does not include the generated tab bars.
	     */
	    DockLayout.prototype.widgets = function () {
	        return this._root ? this._root.iterUserWidgets() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the selected widgets in the layout.
	     *
	     * @returns A new iterator over the selected user widgets.
	     *
	     * #### Notes
	     * This iterator yields the widgets corresponding to the current tab
	     * of each tab bar in the layout.
	     */
	    DockLayout.prototype.selectedWidgets = function () {
	        return this._root ? this._root.iterSelectedWidgets() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the tab bars in the layout.
	     *
	     * @returns A new iterator over the tab bars in the layout.
	     *
	     * #### Notes
	     * This iterator does not include the user widgets.
	     */
	    DockLayout.prototype.tabBars = function () {
	        return this._root ? this._root.iterTabBars() : algorithm_1.empty();
	    };
	    /**
	     * Create an iterator over the handles in the layout.
	     *
	     * @returns A new iterator over the handles in the layout.
	     */
	    DockLayout.prototype.handles = function () {
	        return this._root ? this._root.iterHandles() : algorithm_1.empty();
	    };
	    /**
	     * Move a handle to the given offset position.
	     *
	     * @param handle - The handle to move.
	     *
	     * @param offsetX - The desired offset X position of the handle.
	     *
	     * @param offsetY - The desired offset Y position of the handle.
	     *
	     * #### Notes
	     * If the given handle is not contained in the layout, this is no-op.
	     *
	     * The handle will be moved as close as possible to the desired
	     * position without violating any of the layout constraints.
	     *
	     * Only one of the coordinates is used depending on the orientation
	     * of the handle. This method accepts both coordinates to make it
	     * easy to invoke from a mouse move event without needing to know
	     * the handle orientation.
	     */
	    DockLayout.prototype.moveHandle = function (handle, offsetX, offsetY) {
	        // Bail early if there is no root or if the handle is hidden.
	        if (!this._root || handle.classList.contains('p-mod-hidden')) {
	            return;
	        }
	        // Lookup the split node for the handle.
	        var data = this._root.findSplitNode(handle);
	        if (!data) {
	            return;
	        }
	        // Compute the desired delta movement for the handle.
	        var delta;
	        if (data.node.orientation === 'horizontal') {
	            delta = offsetX - handle.offsetLeft;
	        }
	        else {
	            delta = offsetY - handle.offsetTop;
	        }
	        // Bail if there is no handle movement.
	        if (delta === 0) {
	            return;
	        }
	        // Prevent sibling resizing unless needed.
	        data.node.holdSizes();
	        // Adjust the sizers to reflect the handle movement.
	        boxengine_1.BoxEngine.adjust(data.node.sizers, data.index, delta);
	        // Update the layout of the widgets.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Save the current configuration of the dock layout.
	     *
	     * @returns A new config object for the current layout state.
	     *
	     * #### Notes
	     * The return value can be provided to the `restoreLayout` method
	     * in order to restore the layout to its current configuration.
	     */
	    DockLayout.prototype.saveLayout = function () {
	        // Bail early if there is no root.
	        if (!this._root) {
	            return { main: null };
	        }
	        // Hold the current sizes in the layout tree.
	        this._root.holdAllSizes();
	        // Return the layout config.
	        return { main: this._root.createConfig() };
	    };
	    /**
	     * Restore the layout to a previously saved configuration.
	     *
	     * @param config - The layout configuration to restore.
	     *
	     * #### Notes
	     * Widgets which currently belong to the layout but which are not
	     * contained in the config will be unparented.
	     */
	    DockLayout.prototype.restoreLayout = function (config) {
	        var _this = this;
	        // Create the widget set for validating the config.
	        var widgetSet = new Set();
	        // Normalize the main area config and collect the widgets.
	        var mainConfig;
	        if (config.main) {
	            mainConfig = Private.normalizeAreaConfig(config.main, widgetSet);
	        }
	        else {
	            mainConfig = null;
	        }
	        // Create iterators over the old content.
	        var oldWidgets = this.widgets();
	        var oldTabBars = this.tabBars();
	        var oldHandles = this.handles();
	        // Clear the root before removing the old content.
	        this._root = null;
	        // Unparent the old widgets which are not in the new config.
	        algorithm_1.each(oldWidgets, function (widget) {
	            if (!widgetSet.has(widget)) {
	                widget.parent = null;
	            }
	        });
	        // Dispose of the old tab bars.
	        algorithm_1.each(oldTabBars, function (tabBar) {
	            tabBar.dispose();
	        });
	        // Remove the old handles.
	        algorithm_1.each(oldHandles, function (handle) {
	            if (handle.parentNode) {
	                handle.parentNode.removeChild(handle);
	            }
	        });
	        // Reparent the new widgets to the current parent.
	        widgetSet.forEach(function (widget) {
	            widget.parent = _this.parent;
	        });
	        // Create the root node for the new config.
	        if (mainConfig) {
	            this._root = Private.realizeAreaConfig(mainConfig, {
	                createTabBar: function () { return _this._createTabBar(); },
	                createHandle: function () { return _this._createHandle(); }
	            });
	        }
	        else {
	            this._root = null;
	        }
	        // If there is no parent, there is nothing more to do.
	        if (!this.parent) {
	            return;
	        }
	        // Attach the new widgets to the parent.
	        widgetSet.forEach(function (widget) {
	            _this.attachWidget(widget);
	        });
	        // Post a fit request to the parent.
	        this.parent.fit();
	    };
	    /**
	     * Add a widget to the dock layout.
	     *
	     * @param widget - The widget to add to the dock layout.
	     *
	     * @param options - The additional options for adding the widget.
	     *
	     * #### Notes
	     * The widget will be moved if it is already contained in the layout.
	     *
	     * An error will be thrown if the reference widget is invalid.
	     */
	    DockLayout.prototype.addWidget = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        // Parse the options.
	        var ref = options.ref || null;
	        var mode = options.mode || 'tab-after';
	        // Find the tab node which holds the reference widget.
	        var refNode = null;
	        if (this._root && ref) {
	            refNode = this._root.findTabNode(ref);
	        }
	        // Throw an error if the reference widget is invalid.
	        if (ref && !refNode) {
	            throw new Error('Reference widget is not in the layout.');
	        }
	        // Reparent the widget to the current layout parent.
	        widget.parent = this.parent;
	        // Insert the widget according to the insert mode.
	        switch (mode) {
	            case 'tab-after':
	                this._insertTab(widget, ref, refNode, true);
	                break;
	            case 'tab-before':
	                this._insertTab(widget, ref, refNode, false);
	                break;
	            case 'split-top':
	                this._insertSplit(widget, ref, refNode, 'vertical', false);
	                break;
	            case 'split-left':
	                this._insertSplit(widget, ref, refNode, 'horizontal', false);
	                break;
	            case 'split-right':
	                this._insertSplit(widget, ref, refNode, 'horizontal', true);
	                break;
	            case 'split-bottom':
	                this._insertSplit(widget, ref, refNode, 'vertical', true);
	                break;
	        }
	        // Do nothing else if there is no parent widget.
	        if (!this.parent) {
	            return;
	        }
	        // Ensure the widget is attached to the parent widget.
	        this.attachWidget(widget);
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Remove a widget from the layout.
	     *
	     * @param widget - The widget to remove from the layout.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     */
	    DockLayout.prototype.removeWidget = function (widget) {
	        // Remove the widget from its current layout location.
	        this._removeWidget(widget);
	        // Do nothing else if there is no parent widget.
	        if (!this.parent) {
	            return;
	        }
	        // Detach the widget from the parent widget.
	        this.detachWidget(widget);
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Find the tab area which contains the given client position.
	     *
	     * @param clientX - The client X position of interest.
	     *
	     * @param clientY - The client Y position of interest.
	     *
	     * @returns The geometry of the tab area at the given position, or
	     *   `null` if there is no tab area at the given position.
	     */
	    DockLayout.prototype.hitTestTabAreas = function (clientX, clientY) {
	        // Bail early if hit testing cannot produce valid results.
	        if (!this._root || !this.parent || !this.parent.isVisible) {
	            return null;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Convert from client to local coordinates.
	        var rect = this.parent.node.getBoundingClientRect();
	        var x = clientX - rect.left - this._box.borderLeft;
	        var y = clientY - rect.top - this._box.borderTop;
	        // Find the tab layout node at the local position.
	        var tabNode = this._root.hitTestTabNodes(x, y);
	        // Bail if a tab layout node was not found.
	        if (!tabNode) {
	            return null;
	        }
	        // Extract the data from the tab node.
	        var tabBar = tabNode.tabBar, top = tabNode.top, left = tabNode.left, width = tabNode.width, height = tabNode.height;
	        // Compute the right and bottom edges of the tab area.
	        var borderWidth = this._box.borderLeft + this._box.borderRight;
	        var borderHeight = this._box.borderTop + this._box.borderBottom;
	        var right = rect.width - borderWidth - (left + width);
	        var bottom = rect.height - borderHeight - (top + height);
	        // Return the hit test results.
	        return { tabBar: tabBar, x: x, y: y, top: top, left: left, right: right, bottom: bottom, width: width, height: height };
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    DockLayout.prototype.init = function () {
	        var _this = this;
	        // Perform superclass initialization.
	        _super.prototype.init.call(this);
	        // Attach each widget to the parent.
	        algorithm_1.each(this, function (widget) { _this.attachWidget(widget); });
	        // Attach each handle to the parent.
	        algorithm_1.each(this.handles(), function (handle) { _this.parent.node.appendChild(handle); });
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Attach the widget to the layout parent widget.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a no-op if the widget is already attached.
	     */
	    DockLayout.prototype.attachWidget = function (widget) {
	        // Do nothing if the widget is already attached.
	        if (this.parent.node === widget.node.parentNode) {
	            return;
	        }
	        // Create the layout item for the widget.
	        this._items.set(widget, new layout_1.LayoutItem(widget));
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	    };
	    /**
	     * Detach the widget from the layout parent widget.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a no-op if the widget is not attached.
	     */
	    DockLayout.prototype.detachWidget = function (widget) {
	        // Do nothing if the widget is not attached.
	        if (this.parent.node !== widget.node.parentNode) {
	            return;
	        }
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Delete the layout item for the widget.
	        var item = this._items.get(widget);
	        if (item) {
	            this._items.delete(widget);
	            item.dispose();
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    DockLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    DockLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    DockLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    DockLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    DockLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    DockLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    DockLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Remove the specified widget from the layout structure.
	     *
	     * #### Notes
	     * This is a no-op if the widget is not in the layout tree.
	     *
	     * This does not detach the widget from the parent node.
	     */
	    DockLayout.prototype._removeWidget = function (widget) {
	        // Bail early if there is no layout root.
	        if (!this._root) {
	            return;
	        }
	        // Find the tab node which contains the given widget.
	        var tabNode = this._root.findTabNode(widget);
	        // Bail early if the tab node is not found.
	        if (!tabNode) {
	            return;
	        }
	        // If there are multiple tabs, just remove the widget's tab.
	        if (tabNode.tabBar.titles.length > 1) {
	            tabNode.tabBar.removeTab(widget.title);
	            return;
	        }
	        // Otherwise, the tab node needs to be removed...
	        // Dispose the tab bar.
	        tabNode.tabBar.dispose();
	        // Handle the case where the tab node is the root.
	        if (this._root === tabNode) {
	            this._root = null;
	            return;
	        }
	        // Otherwise, remove the tab node from its parent...
	        // Prevent widget resizing unless needed.
	        this._root.holdAllSizes();
	        // Clear the parent reference on the tab node.
	        var splitNode = tabNode.parent;
	        tabNode.parent = null;
	        // Remove the tab node from its parent split node.
	        var i = algorithm_1.ArrayExt.removeFirstOf(splitNode.children, tabNode);
	        var handle = algorithm_1.ArrayExt.removeAt(splitNode.handles, i);
	        algorithm_1.ArrayExt.removeAt(splitNode.sizers, i);
	        // Remove the handle from its parent DOM node.
	        if (handle.parentNode) {
	            handle.parentNode.removeChild(handle);
	        }
	        // If there are multiple children, just update the handles.
	        if (splitNode.children.length > 1) {
	            splitNode.syncHandles();
	            return;
	        }
	        // Otherwise, the split node also needs to be removed...
	        // Clear the parent reference on the split node.
	        var maybeParent = splitNode.parent;
	        splitNode.parent = null;
	        // Lookup the remaining child node and handle.
	        var childNode = splitNode.children[0];
	        var childHandle = splitNode.handles[0];
	        // Clear the split node data.
	        splitNode.children.length = 0;
	        splitNode.handles.length = 0;
	        splitNode.sizers.length = 0;
	        // Remove the child handle from its parent node.
	        if (childHandle.parentNode) {
	            childHandle.parentNode.removeChild(childHandle);
	        }
	        // Handle the case where the split node is the root.
	        if (this._root === splitNode) {
	            childNode.parent = null;
	            this._root = childNode;
	            return;
	        }
	        // Otherwise, move the child node to the parent node...
	        var parentNode = maybeParent;
	        // Lookup the index of the split node.
	        var j = parentNode.children.indexOf(splitNode);
	        // Handle the case where the child node is a tab node.
	        if (childNode instanceof Private.TabLayoutNode) {
	            childNode.parent = parentNode;
	            parentNode.children[j] = childNode;
	            return;
	        }
	        // Remove the split data from the parent.
	        var splitHandle = algorithm_1.ArrayExt.removeAt(parentNode.handles, j);
	        algorithm_1.ArrayExt.removeAt(parentNode.children, j);
	        algorithm_1.ArrayExt.removeAt(parentNode.sizers, j);
	        // Remove the handle from its parent node.
	        if (splitHandle.parentNode) {
	            splitHandle.parentNode.removeChild(splitHandle);
	        }
	        // The child node and the split parent node will have the same
	        // orientation. Merge the grand-children with the parent node.
	        for (var i_1 = 0, n = childNode.children.length; i_1 < n; ++i_1) {
	            var gChild = childNode.children[i_1];
	            var gHandle = childNode.handles[i_1];
	            var gSizer = childNode.sizers[i_1];
	            algorithm_1.ArrayExt.insert(parentNode.children, j + i_1, gChild);
	            algorithm_1.ArrayExt.insert(parentNode.handles, j + i_1, gHandle);
	            algorithm_1.ArrayExt.insert(parentNode.sizers, j + i_1, gSizer);
	            gChild.parent = parentNode;
	        }
	        // Clear the child node.
	        childNode.children.length = 0;
	        childNode.handles.length = 0;
	        childNode.sizers.length = 0;
	        childNode.parent = null;
	        // Sync the handles on the parent node.
	        parentNode.syncHandles();
	    };
	    /**
	     * Insert a widget next to an existing tab.
	     *
	     * #### Notes
	     * This does not attach the widget to the parent widget.
	     */
	    DockLayout.prototype._insertTab = function (widget, ref, refNode, after) {
	        // Do nothing if the tab is inserted next to itself.
	        if (widget === ref) {
	            return;
	        }
	        // Create the root if it does not exist.
	        if (!this._root) {
	            var tabNode = new Private.TabLayoutNode(this._createTabBar());
	            tabNode.tabBar.addTab(widget.title);
	            this._root = tabNode;
	            return;
	        }
	        // Use the first tab node as the ref node if needed.
	        if (!refNode) {
	            refNode = this._root.findFirstTabNode();
	        }
	        // If the widget is not contained in the ref node, ensure it is
	        // removed from the layout and hidden before being added again.
	        if (refNode.tabBar.titles.indexOf(widget.title) === -1) {
	            this._removeWidget(widget);
	            widget.hide();
	        }
	        // Lookup the target index for inserting the tab.
	        var index;
	        if (ref) {
	            index = refNode.tabBar.titles.indexOf(ref.title);
	        }
	        else {
	            index = refNode.tabBar.currentIndex;
	        }
	        // Insert the widget's tab relative to the target index.
	        refNode.tabBar.insertTab(index + (after ? 1 : 0), widget.title);
	    };
	    /**
	     * Insert a widget as a new split area.
	     *
	     * #### Notes
	     * This does not attach the widget to the parent widget.
	     */
	    DockLayout.prototype._insertSplit = function (widget, ref, refNode, orientation, after) {
	        // Do nothing if there is no effective split.
	        if (widget === ref && refNode && refNode.tabBar.titles.length === 1) {
	            return;
	        }
	        // Ensure the widget is removed from the current layout.
	        this._removeWidget(widget);
	        // Create the tab layout node to hold the widget.
	        var tabNode = new Private.TabLayoutNode(this._createTabBar());
	        tabNode.tabBar.addTab(widget.title);
	        // Set the root if it does not exist.
	        if (!this._root) {
	            this._root = tabNode;
	            return;
	        }
	        // If the ref node parent is null, split the root.
	        if (!refNode || !refNode.parent) {
	            // Ensure the root is split with the correct orientation.
	            var root = this._splitRoot(orientation);
	            // Determine the insert index for the new tab node.
	            var i_2 = after ? root.children.length : 0;
	            // Normalize the split node.
	            root.normalizeSizes();
	            // Create the sizer for new tab node.
	            var sizer = Private.createSizer(refNode ? 1 : Private.GOLDEN_RATIO);
	            // Insert the tab node sized to the golden ratio.
	            algorithm_1.ArrayExt.insert(root.children, i_2, tabNode);
	            algorithm_1.ArrayExt.insert(root.sizers, i_2, sizer);
	            algorithm_1.ArrayExt.insert(root.handles, i_2, this._createHandle());
	            tabNode.parent = root;
	            // Re-normalize the split node to maintain the ratios.
	            root.normalizeSizes();
	            // Finally, synchronize the visibility of the handles.
	            root.syncHandles();
	            return;
	        }
	        // Lookup the split node for the ref widget.
	        var splitNode = refNode.parent;
	        // If the split node already had the correct orientation,
	        // the widget can be inserted into the split node directly.
	        if (splitNode.orientation === orientation) {
	            // Find the index of the ref node.
	            var i_3 = splitNode.children.indexOf(refNode);
	            // Normalize the split node.
	            splitNode.normalizeSizes();
	            // Consume half the space for the insert location.
	            var s = splitNode.sizers[i_3].sizeHint /= 2;
	            // Insert the tab node sized to the other half.
	            var j_1 = i_3 + (after ? 1 : 0);
	            algorithm_1.ArrayExt.insert(splitNode.children, j_1, tabNode);
	            algorithm_1.ArrayExt.insert(splitNode.sizers, j_1, Private.createSizer(s));
	            algorithm_1.ArrayExt.insert(splitNode.handles, j_1, this._createHandle());
	            tabNode.parent = splitNode;
	            // Finally, synchronize the visibility of the handles.
	            splitNode.syncHandles();
	            return;
	        }
	        // Remove the ref node from the split node.
	        var i = algorithm_1.ArrayExt.removeFirstOf(splitNode.children, refNode);
	        // Create a new normalized split node for the children.
	        var childNode = new Private.SplitLayoutNode(orientation);
	        childNode.normalized = true;
	        // Add the ref node sized to half the space.
	        childNode.children.push(refNode);
	        childNode.sizers.push(Private.createSizer(0.5));
	        childNode.handles.push(this._createHandle());
	        refNode.parent = childNode;
	        // Add the tab node sized to the other half.
	        var j = after ? 1 : 0;
	        algorithm_1.ArrayExt.insert(childNode.children, j, tabNode);
	        algorithm_1.ArrayExt.insert(childNode.sizers, j, Private.createSizer(0.5));
	        algorithm_1.ArrayExt.insert(childNode.handles, j, this._createHandle());
	        tabNode.parent = childNode;
	        // Synchronize the visibility of the handles.
	        childNode.syncHandles();
	        // Finally, add the new child node to the original split node.
	        algorithm_1.ArrayExt.insert(splitNode.children, i, childNode);
	        childNode.parent = splitNode;
	    };
	    /**
	     * Ensure the root is a split node with the given orientation.
	     */
	    DockLayout.prototype._splitRoot = function (orientation) {
	        // Bail early if the root already meets the requirements.
	        var oldRoot = this._root;
	        if (oldRoot instanceof Private.SplitLayoutNode) {
	            if (oldRoot.orientation === orientation) {
	                return oldRoot;
	            }
	        }
	        // Create a new root node with the specified orientation.
	        var newRoot = this._root = new Private.SplitLayoutNode(orientation);
	        // Add the old root to the new root.
	        if (oldRoot) {
	            newRoot.children.push(oldRoot);
	            newRoot.sizers.push(Private.createSizer(0));
	            newRoot.handles.push(this._createHandle());
	            oldRoot.parent = newRoot;
	        }
	        // Return the new root as a convenience.
	        return newRoot;
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    DockLayout.prototype._fit = function () {
	        // Set up the computed minimum size.
	        var minW = 0;
	        var minH = 0;
	        // Update the size limits for the layout tree.
	        if (this._root) {
	            var limits = this._root.fit(this._spacing, this._items);
	            minW = limits.minWidth;
	            minH = limits.minHeight;
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    DockLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Bail early if there is no root layout node.
	        if (!this._root) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the actual layout bounds adjusted for border and padding.
	        var x = this._box.paddingTop;
	        var y = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Update the geometry of the layout tree.
	        this._root.update(x, y, width, height, this._spacing, this._items);
	    };
	    /**
	     * Create a new tab bar for use by the dock layout.
	     *
	     * #### Notes
	     * The tab bar will be attached to the parent if it exists.
	     */
	    DockLayout.prototype._createTabBar = function () {
	        // Create the tab bar using the renderer.
	        var tabBar = this.renderer.createTabBar();
	        // Enforce necessary tab bar behavior.
	        tabBar.orientation = 'horizontal';
	        // Reparent and attach the tab bar to the parent if possible.
	        if (this.parent) {
	            tabBar.parent = this.parent;
	            this.attachWidget(tabBar);
	        }
	        // Return the initialized tab bar.
	        return tabBar;
	    };
	    /**
	     * Create a new handle for the dock layout.
	     *
	     * #### Notes
	     * The handle will be attached to the parent if it exists.
	     */
	    DockLayout.prototype._createHandle = function () {
	        // Create the handle using the renderer.
	        var handle = this.renderer.createHandle();
	        // Initialize the handle layout behavior.
	        var style = handle.style;
	        style.position = 'absolute';
	        style.top = '0';
	        style.left = '0';
	        style.width = '0';
	        style.height = '0';
	        // Attach the handle to the parent if it exists.
	        if (this.parent) {
	            this.parent.node.appendChild(handle);
	        }
	        // Return the initialized handle.
	        return handle;
	    };
	    return DockLayout;
	}(layout_1.Layout));
	exports.DockLayout = DockLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A fraction used for sizing root panels; ~= `1 / golden_ratio`.
	     */
	    Private.GOLDEN_RATIO = 0.618;
	    /**
	     * Clamp a spacing value to an integer >= 0.
	     */
	    function clampSpacing(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampSpacing = clampSpacing;
	    /**
	     * Create a box sizer with an initial size hint.
	     */
	    function createSizer(hint) {
	        var sizer = new boxengine_1.BoxSizer();
	        sizer.sizeHint = hint;
	        sizer.size = hint;
	        return sizer;
	    }
	    Private.createSizer = createSizer;
	    /**
	     * Normalize an area config object and collect the visited widgets.
	     */
	    function normalizeAreaConfig(config, widgetSet) {
	        var result;
	        if (config.type === 'tab-area') {
	            result = normalizeTabAreaConfig(config, widgetSet);
	        }
	        else {
	            result = normalizeSplitAreaConfig(config, widgetSet);
	        }
	        return result;
	    }
	    Private.normalizeAreaConfig = normalizeAreaConfig;
	    /**
	     * Convert a normalized area config into a layout tree.
	     */
	    function realizeAreaConfig(config, renderer) {
	        var node;
	        if (config.type === 'tab-area') {
	            node = realizeTabAreaConfig(config, renderer);
	        }
	        else {
	            node = realizeSplitAreaConfig(config, renderer);
	        }
	        return node;
	    }
	    Private.realizeAreaConfig = realizeAreaConfig;
	    /**
	     * A layout node which holds the data for a tabbed area.
	     */
	    var TabLayoutNode = (function () {
	        /**
	         * Construct a new tab layout node.
	         *
	         * @param tabBar - The tab bar to use for the layout node.
	         */
	        function TabLayoutNode(tabBar) {
	            /**
	             * The parent of the layout node.
	             */
	            this.parent = null;
	            this._top = 0;
	            this._left = 0;
	            this._width = 0;
	            this._height = 0;
	            var tabSizer = new boxengine_1.BoxSizer();
	            var widgetSizer = new boxengine_1.BoxSizer();
	            tabSizer.stretch = 0;
	            widgetSizer.stretch = 1;
	            this.tabBar = tabBar;
	            this.sizers = [tabSizer, widgetSizer];
	        }
	        Object.defineProperty(TabLayoutNode.prototype, "top", {
	            /**
	             * The most recent value for the `top` edge of the layout box.
	             */
	            get: function () {
	                return this._top;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(TabLayoutNode.prototype, "left", {
	            /**
	             * The most recent value for the `left` edge of the layout box.
	             */
	            get: function () {
	                return this._left;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(TabLayoutNode.prototype, "width", {
	            /**
	             * The most recent value for the `width` of the layout box.
	             */
	            get: function () {
	                return this._width;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(TabLayoutNode.prototype, "height", {
	            /**
	             * The most recent value for the `height` of the layout box.
	             */
	            get: function () {
	                return this._height;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        /**
	         * Create an iterator for all widgets in the layout tree.
	         */
	        TabLayoutNode.prototype.iterAllWidgets = function () {
	            return algorithm_1.chain(algorithm_1.once(this.tabBar), this.iterUserWidgets());
	        };
	        /**
	         * Create an iterator for the user widgets in the layout tree.
	         */
	        TabLayoutNode.prototype.iterUserWidgets = function () {
	            return algorithm_1.map(this.tabBar.titles, function (title) { return title.owner; });
	        };
	        /**
	         * Create an iterator for the selected widgets in the layout tree.
	         */
	        TabLayoutNode.prototype.iterSelectedWidgets = function () {
	            var title = this.tabBar.currentTitle;
	            return title ? algorithm_1.once(title.owner) : algorithm_1.empty();
	        };
	        /**
	         * Create an iterator for the tab bars in the layout tree.
	         */
	        TabLayoutNode.prototype.iterTabBars = function () {
	            return algorithm_1.once(this.tabBar);
	        };
	        /**
	         * Create an iterator for the handles in the layout tree.
	         */
	        TabLayoutNode.prototype.iterHandles = function () {
	            return algorithm_1.empty();
	        };
	        /**
	         * Find the tab layout node which contains the given widget.
	         */
	        TabLayoutNode.prototype.findTabNode = function (widget) {
	            return this.tabBar.titles.indexOf(widget.title) !== -1 ? this : null;
	        };
	        /**
	         * Find the split layout node which contains the given handle.
	         */
	        TabLayoutNode.prototype.findSplitNode = function (handle) {
	            return null;
	        };
	        /**
	         * Find the first tab layout node in a layout tree.
	         */
	        TabLayoutNode.prototype.findFirstTabNode = function () {
	            return this;
	        };
	        /**
	         * Find the tab layout node which contains the local point.
	         */
	        TabLayoutNode.prototype.hitTestTabNodes = function (x, y) {
	            if (x < this._left || x >= this._left + this._width) {
	                return null;
	            }
	            if (y < this._top || y >= this._top + this._height) {
	                return null;
	            }
	            return this;
	        };
	        /**
	         * Create a configuration object for the layout tree.
	         */
	        TabLayoutNode.prototype.createConfig = function () {
	            var widgets = this.tabBar.titles.map(function (title) { return title.owner; });
	            var currentIndex = this.tabBar.currentIndex;
	            return { type: 'tab-area', widgets: widgets, currentIndex: currentIndex };
	        };
	        /**
	         * Recursively hold all of the sizes in the layout tree.
	         *
	         * This ignores the sizers of tab layout nodes.
	         */
	        TabLayoutNode.prototype.holdAllSizes = function () {
	            return;
	        };
	        /**
	         * Fit the layout tree.
	         */
	        TabLayoutNode.prototype.fit = function (spacing, items) {
	            // Set up the limit variables.
	            var minWidth = 0;
	            var minHeight = 0;
	            var maxWidth = Infinity;
	            var maxHeight = Infinity;
	            // Lookup the tab bar layout item.
	            var tabBarItem = items.get(this.tabBar);
	            // Lookup the widget layout item.
	            var current = this.tabBar.currentTitle;
	            var widgetItem = current ? items.get(current.owner) : undefined;
	            // Lookup the tab bar and widget sizers.
	            var _a = this.sizers, tabBarSizer = _a[0], widgetSizer = _a[1];
	            // Update the tab bar limits.
	            if (tabBarItem) {
	                tabBarItem.fit();
	            }
	            // Update the widget limits.
	            if (widgetItem) {
	                widgetItem.fit();
	            }
	            // Update the results and sizer for the tab bar.
	            if (tabBarItem && !tabBarItem.isHidden) {
	                minWidth = Math.max(minWidth, tabBarItem.minWidth);
	                minHeight += tabBarItem.minHeight;
	                tabBarSizer.minSize = tabBarItem.minHeight;
	                tabBarSizer.maxSize = tabBarItem.maxHeight;
	            }
	            else {
	                tabBarSizer.minSize = 0;
	                tabBarSizer.maxSize = 0;
	            }
	            // Update the results and sizer for the current widget.
	            if (widgetItem && !widgetItem.isHidden) {
	                minWidth = Math.max(minWidth, widgetItem.minWidth);
	                minHeight += widgetItem.minHeight;
	                widgetSizer.minSize = widgetItem.minHeight;
	                widgetSizer.maxSize = Infinity;
	            }
	            else {
	                widgetSizer.minSize = 0;
	                widgetSizer.maxSize = Infinity;
	            }
	            // Return the computed size limits for the layout node.
	            return { minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight };
	        };
	        /**
	         * Update the layout tree.
	         */
	        TabLayoutNode.prototype.update = function (left, top, width, height, spacing, items) {
	            // Update the layout box values.
	            this._top = top;
	            this._left = left;
	            this._width = width;
	            this._height = height;
	            // Lookup the tab bar layout item.
	            var tabBarItem = items.get(this.tabBar);
	            // Lookup the widget layout item.
	            var current = this.tabBar.currentTitle;
	            var widgetItem = current ? items.get(current.owner) : undefined;
	            // Distribute the layout space to the sizers.
	            boxengine_1.BoxEngine.calc(this.sizers, height);
	            // Update the tab bar item using the computed size.
	            if (tabBarItem && !tabBarItem.isHidden) {
	                var size = this.sizers[0].size;
	                tabBarItem.update(left, top, width, size);
	                top += size;
	            }
	            // Layout the widget using the computed size.
	            if (widgetItem && !widgetItem.isHidden) {
	                var size = this.sizers[1].size;
	                widgetItem.update(left, top, width, size);
	            }
	        };
	        return TabLayoutNode;
	    }());
	    Private.TabLayoutNode = TabLayoutNode;
	    /**
	     * A layout node which holds the data for a split area.
	     */
	    var SplitLayoutNode = (function () {
	        /**
	         * Construct a new split layout node.
	         *
	         * @param orientation - The orientation of the node.
	         */
	        function SplitLayoutNode(orientation) {
	            /**
	             * The parent of the layout node.
	             */
	            this.parent = null;
	            /**
	             * Whether the sizers have been normalized.
	             */
	            this.normalized = false;
	            /**
	             * The child nodes for the split node.
	             */
	            this.children = [];
	            /**
	             * The box sizers for the layout children.
	             */
	            this.sizers = [];
	            /**
	             * The handles for the layout children.
	             */
	            this.handles = [];
	            this.orientation = orientation;
	        }
	        /**
	         * Create an iterator for all widgets in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterAllWidgets = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterAllWidgets(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the user widgets in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterUserWidgets = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterUserWidgets(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the selected widgets in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterSelectedWidgets = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterSelectedWidgets(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the tab bars in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterTabBars = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterTabBars(); });
	            return new algorithm_1.ChainIterator(children);
	        };
	        /**
	         * Create an iterator for the handles in the layout tree.
	         */
	        SplitLayoutNode.prototype.iterHandles = function () {
	            var children = algorithm_1.map(this.children, function (child) { return child.iterHandles(); });
	            return algorithm_1.chain(this.handles, new algorithm_1.ChainIterator(children));
	        };
	        /**
	         * Find the tab layout node which contains the given widget.
	         */
	        SplitLayoutNode.prototype.findTabNode = function (widget) {
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var result = this.children[i].findTabNode(widget);
	                if (result) {
	                    return result;
	                }
	            }
	            return null;
	        };
	        /**
	         * Find the split layout node which contains the given handle.
	         */
	        SplitLayoutNode.prototype.findSplitNode = function (handle) {
	            var index = this.handles.indexOf(handle);
	            if (index !== -1) {
	                return { index: index, node: this };
	            }
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var result = this.children[i].findSplitNode(handle);
	                if (result) {
	                    return result;
	                }
	            }
	            return null;
	        };
	        /**
	         * Find the first tab layout node in a layout tree.
	         */
	        SplitLayoutNode.prototype.findFirstTabNode = function () {
	            if (this.children.length === 0) {
	                return null;
	            }
	            return this.children[0].findFirstTabNode();
	        };
	        /**
	         * Find the tab layout node which contains the local point.
	         */
	        SplitLayoutNode.prototype.hitTestTabNodes = function (x, y) {
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var result = this.children[i].hitTestTabNodes(x, y);
	                if (result) {
	                    return result;
	                }
	            }
	            return null;
	        };
	        /**
	         * Create a configuration object for the layout tree.
	         */
	        SplitLayoutNode.prototype.createConfig = function () {
	            var orientation = this.orientation;
	            var sizes = this.createNormalizedSizes();
	            var children = this.children.map(function (child) { return child.createConfig(); });
	            return { type: 'split-area', orientation: orientation, children: children, sizes: sizes };
	        };
	        /**
	         * Sync the visibility and orientation of the handles.
	         */
	        SplitLayoutNode.prototype.syncHandles = function () {
	            var _this = this;
	            algorithm_1.each(this.handles, function (handle, i) {
	                handle.setAttribute('data-orientation', _this.orientation);
	                if (i === _this.handles.length - 1) {
	                    handle.classList.add('p-mod-hidden');
	                }
	                else {
	                    handle.classList.remove('p-mod-hidden');
	                }
	            });
	        };
	        /**
	         * Hold the current sizes of the box sizers.
	         *
	         * This sets the size hint of each sizer to its current size.
	         */
	        SplitLayoutNode.prototype.holdSizes = function () {
	            algorithm_1.each(this.sizers, function (sizer) { sizer.sizeHint = sizer.size; });
	        };
	        /**
	         * Recursively hold all of the sizes in the layout tree.
	         *
	         * This ignores the sizers of tab layout nodes.
	         */
	        SplitLayoutNode.prototype.holdAllSizes = function () {
	            algorithm_1.each(this.children, function (child) { return child.holdAllSizes(); });
	            this.holdSizes();
	        };
	        /**
	         * Normalize the sizes of the split layout node.
	         */
	        SplitLayoutNode.prototype.normalizeSizes = function () {
	            // Bail early if the sizers are empty.
	            var n = this.sizers.length;
	            if (n === 0) {
	                return;
	            }
	            // Hold the current sizes of the sizers.
	            this.holdSizes();
	            // Compute the sum of the sizes.
	            var sum = algorithm_1.reduce(this.sizers, function (v, sizer) { return v + sizer.sizeHint; }, 0);
	            // Normalize the sizes based on the sum.
	            if (sum === 0) {
	                algorithm_1.each(this.sizers, function (sizer) {
	                    sizer.size = sizer.sizeHint = 1 / n;
	                });
	            }
	            else {
	                algorithm_1.each(this.sizers, function (sizer) {
	                    sizer.size = sizer.sizeHint /= sum;
	                });
	            }
	            // Mark the sizes as normalized.
	            this.normalized = true;
	        };
	        /**
	         * Snap the normalized sizes of the split layout node.
	         */
	        SplitLayoutNode.prototype.createNormalizedSizes = function () {
	            // Bail early if the sizers are empty.
	            var n = this.sizers.length;
	            if (n === 0) {
	                return [];
	            }
	            // Grab the current sizes of the sizers.
	            var sizes = this.sizers.map(function (sizer) { return sizer.size; });
	            // Compute the sum of the sizes.
	            var sum = algorithm_1.reduce(sizes, function (v, size) { return v + size; }, 0);
	            // Normalize the sizes based on the sum.
	            if (sum === 0) {
	                algorithm_1.each(sizes, function (size, i) { sizes[i] = 1 / n; });
	            }
	            else {
	                algorithm_1.each(sizes, function (size, i) { sizes[i] = size / sum; });
	            }
	            // Return the normalized sizes.
	            return sizes;
	        };
	        /**
	         * Fit the layout tree.
	         */
	        SplitLayoutNode.prototype.fit = function (spacing, items) {
	            // Compute the required fixed space.
	            var horizontal = this.orientation === 'horizontal';
	            var fixed = Math.max(0, this.children.length - 1) * spacing;
	            // Set up the limit variables.
	            var minWidth = horizontal ? fixed : 0;
	            var minHeight = horizontal ? 0 : fixed;
	            var maxWidth = Infinity;
	            var maxHeight = Infinity;
	            // Fit the children and update the limits.
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var limits = this.children[i].fit(spacing, items);
	                if (horizontal) {
	                    minHeight = Math.max(minHeight, limits.minHeight);
	                    minWidth += limits.minWidth;
	                    this.sizers[i].minSize = limits.minWidth;
	                }
	                else {
	                    minWidth = Math.max(minWidth, limits.minWidth);
	                    minHeight += limits.minHeight;
	                    this.sizers[i].minSize = limits.minHeight;
	                }
	            }
	            // Return the computed limits for the layout node.
	            return { minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight };
	        };
	        /**
	         * Update the layout tree.
	         */
	        SplitLayoutNode.prototype.update = function (left, top, width, height, spacing, items) {
	            // Compute the available layout space.
	            var horizontal = this.orientation === 'horizontal';
	            var fixed = Math.max(0, this.children.length - 1) * spacing;
	            var space = Math.max(0, (horizontal ? width : height) - fixed);
	            // De-normalize the sizes if needed.
	            if (this.normalized) {
	                algorithm_1.each(this.sizers, function (sizer) { sizer.sizeHint *= space; });
	                this.normalized = false;
	            }
	            // Distribute the layout space to the sizers.
	            boxengine_1.BoxEngine.calc(this.sizers, space);
	            // Update the geometry of the child nodes and handles.
	            for (var i = 0, n = this.children.length; i < n; ++i) {
	                var child = this.children[i];
	                var size = this.sizers[i].size;
	                var handleStyle = this.handles[i].style;
	                if (horizontal) {
	                    child.update(left, top, size, height, spacing, items);
	                    left += size;
	                    handleStyle.top = top + "px";
	                    handleStyle.left = left + "px";
	                    handleStyle.width = spacing + "px";
	                    handleStyle.height = height + "px";
	                    left += spacing;
	                }
	                else {
	                    child.update(left, top, width, size, spacing, items);
	                    top += size;
	                    handleStyle.top = top + "px";
	                    handleStyle.left = left + "px";
	                    handleStyle.width = width + "px";
	                    handleStyle.height = spacing + "px";
	                    top += spacing;
	                }
	            }
	        };
	        return SplitLayoutNode;
	    }());
	    Private.SplitLayoutNode = SplitLayoutNode;
	    /**
	     * Normalize a tab area config and collect the visited widgets.
	     */
	    function normalizeTabAreaConfig(config, widgetSet) {
	        // Bail early if there is no content.
	        if (config.widgets.length === 0) {
	            return null;
	        }
	        // Setup the filtered widgets array.
	        var widgets = [];
	        // Filter the config for unique widgets.
	        algorithm_1.each(config.widgets, function (widget) {
	            if (!widgetSet.has(widget)) {
	                widgetSet.add(widget);
	                widgets.push(widget);
	            }
	        });
	        // Bail if there are no effective widgets.
	        if (widgets.length === 0) {
	            return null;
	        }
	        // Normalize the current index.
	        var index = config.currentIndex;
	        if (index !== -1 && (index < 0 || index >= widgets.length)) {
	            index = 0;
	        }
	        // Return a normalized config object.
	        return { type: 'tab-area', widgets: widgets, currentIndex: index };
	    }
	    /**
	     * Normalize a split area config and collect the visited widgets.
	     */
	    function normalizeSplitAreaConfig(config, widgetSet) {
	        // Set up the result variables.
	        var orientation = config.orientation;
	        var children = [];
	        var sizes = [];
	        // Normalize the config children.
	        for (var i = 0, n = config.children.length; i < n; ++i) {
	            // Normalize the child config.
	            var child = normalizeAreaConfig(config.children[i], widgetSet);
	            // Ignore an empty child.
	            if (!child) {
	                continue;
	            }
	            // Add the child or hoist its content as appropriate.
	            if (child.type === 'tab-area' || child.orientation !== orientation) {
	                children.push(child);
	                sizes.push(Math.abs(config.sizes[i] || 0));
	            }
	            else {
	                children.push.apply(children, child.children);
	                sizes.push.apply(sizes, child.sizes);
	            }
	        }
	        // Bail if there are no effective children.
	        if (children.length === 0) {
	            return null;
	        }
	        // If there is only one effective child, return that child.
	        if (children.length === 1) {
	            return children[0];
	        }
	        // Return a normalized config object.
	        return { type: 'split-area', orientation: orientation, children: children, sizes: sizes };
	    }
	    /**
	     * Convert a normalized tab area config into a layout tree.
	     */
	    function realizeTabAreaConfig(config, renderer) {
	        // Create the tab bar for the layout node.
	        var tabBar = renderer.createTabBar();
	        // Hide each widget and add it to the tab bar.
	        algorithm_1.each(config.widgets, function (widget) {
	            widget.hide();
	            tabBar.addTab(widget.title);
	        });
	        // Set the current index of the tab bar.
	        tabBar.currentIndex = config.currentIndex;
	        // Return the new tab layout node.
	        return new TabLayoutNode(tabBar);
	    }
	    /**
	     * Convert a normalized split area config into a layout tree.
	     */
	    function realizeSplitAreaConfig(config, renderer) {
	        // Create the split layout node.
	        var node = new SplitLayoutNode(config.orientation);
	        // Add each child to the layout node.
	        algorithm_1.each(config.children, function (child, i) {
	            // Create the child data for the layout node.
	            var childNode = realizeAreaConfig(child, renderer);
	            var sizer = createSizer(config.sizes[i]);
	            var handle = renderer.createHandle();
	            // Add the child data to the layout node.
	            node.children.push(childNode);
	            node.handles.push(handle);
	            node.sizers.push(sizer);
	            // Update the parent for the child node.
	            childNode.parent = node;
	        });
	        // Synchronize the handle state for the layout node.
	        node.syncHandles();
	        // Normalize the sizes for the layout node.
	        node.normalizeSizes();
	        // Return the new layout node.
	        return node;
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/docklayout.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/dockpanel.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/dockpanel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var dragdrop_1 = __jupyter_require__('@phosphor/dragdrop@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.1.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var docklayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/docklayout.js');
	var tabbar_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/tabbar.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A widget which provides a flexible docking area for widgets.
	 */
	var DockPanel = (function (_super) {
	    __extends(DockPanel, _super);
	    /**
	     * Construct a new dock panel.
	     *
	     * @param options - The options for initializing the panel.
	     */
	    function DockPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._drag = null;
	        _this._pressData = null;
	        _this._layoutModified = new signaling_1.Signal(_this);
	        _this.addClass('p-DockPanel');
	        _this._mode = options.mode || 'multiple-document';
	        _this._renderer = options.renderer || DockPanel.defaultRenderer;
	        // Toggle the CSS mode attribute.
	        _this.dataset['mode'] = _this._mode;
	        // Create the delegate renderer for the layout.
	        var renderer = {
	            createTabBar: function () { return _this._createTabBar(); },
	            createHandle: function () { return _this._createHandle(); }
	        };
	        // Set up the dock layout for the panel.
	        _this.layout = new docklayout_1.DockLayout({ renderer: renderer, spacing: options.spacing });
	        // Set up the overlay drop indicator.
	        _this.overlay = options.overlay || new DockPanel.Overlay();
	        _this.node.appendChild(_this.overlay.node);
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the panel.
	     */
	    DockPanel.prototype.dispose = function () {
	        // Ensure the mouse is released.
	        this._releaseMouse();
	        // Hide the overlay.
	        this.overlay.hide(0);
	        // Cancel a drag if one is in progress.
	        if (this._drag) {
	            this._drag.dispose();
	        }
	        // Dispose of the base class.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(DockPanel.prototype, "layoutModified", {
	        /**
	         * A signal emitted when the layout configuration is modified.
	         *
	         * #### Notes
	         * This signal is emitted whenever the current layout configuration
	         * may have changed.
	         *
	         * This signal is emitted asynchronously in a collapsed fashion, so
	         * that multiple synchronous modifications results in only a single
	         * emit of the signal.
	         */
	        get: function () {
	            return this._layoutModified;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "renderer", {
	        /**
	         * The renderer used by the dock panel.
	         */
	        get: function () {
	            return this.layout.renderer;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "spacing", {
	        /**
	         * Get the spacing between the widgets.
	         */
	        get: function () {
	            return this.layout.spacing;
	        },
	        /**
	         * Set the spacing between the widgets.
	         */
	        set: function (value) {
	            this.layout.spacing = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "mode", {
	        /**
	         * Get the mode for the dock panel.
	         */
	        get: function () {
	            return this._mode;
	        },
	        /**
	         * Set the mode for the dock panel.
	         *
	         * #### Notes
	         * Changing the mode is a destructive operation with respect to the
	         * panel's layout configuration. If layout state must be preserved,
	         * save the current layout config before changing the mode.
	         */
	        set: function (value) {
	            // Bail early if the mode does not change.
	            if (this._mode === value) {
	                return;
	            }
	            // Update the internal mode.
	            this._mode = value;
	            // Toggle the CSS mode attribute.
	            this.dataset['mode'] = value;
	            // Get the layout for the panel.
	            var layout = this.layout;
	            // Configure the layout for the specified mode.
	            switch (value) {
	                case 'multiple-document':
	                    algorithm_1.each(layout.tabBars(), function (tabBar) { tabBar.show(); });
	                    break;
	                case 'single-document':
	                    layout.restoreLayout(Private.createSingleDocumentConfig(this));
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	            // Schedule an emit of the layout modified signal.
	            messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DockPanel.prototype, "isEmpty", {
	        /**
	         * Whether the dock panel is empty.
	         */
	        get: function () {
	            return this.layout.isEmpty;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the user widgets in the panel.
	     *
	     * @returns A new iterator over the user widgets in the panel.
	     *
	     * #### Notes
	     * This iterator does not include the generated tab bars.
	     */
	    DockPanel.prototype.widgets = function () {
	        return this.layout.widgets();
	    };
	    /**
	     * Create an iterator over the selected widgets in the panel.
	     *
	     * @returns A new iterator over the selected user widgets.
	     *
	     * #### Notes
	     * This iterator yields the widgets corresponding to the current tab
	     * of each tab bar in the panel.
	     */
	    DockPanel.prototype.selectedWidgets = function () {
	        return this.layout.selectedWidgets();
	    };
	    /**
	     * Create an iterator over the tab bars in the panel.
	     *
	     * @returns A new iterator over the tab bars in the panel.
	     *
	     * #### Notes
	     * This iterator does not include the user widgets.
	     */
	    DockPanel.prototype.tabBars = function () {
	        return this.layout.tabBars();
	    };
	    /**
	     * Create an iterator over the handles in the panel.
	     *
	     * @returns A new iterator over the handles in the panel.
	     */
	    DockPanel.prototype.handles = function () {
	        return this.layout.handles();
	    };
	    /**
	     * Select a specific widget in the dock panel.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * This will make the widget the current widget in its tab area.
	     */
	    DockPanel.prototype.selectWidget = function (widget) {
	        // Find the tab bar which contains the widget.
	        var tabBar = algorithm_1.find(this.tabBars(), function (bar) {
	            return bar.titles.indexOf(widget.title) !== -1;
	        });
	        // Throw an error if no tab bar is found.
	        if (!tabBar) {
	            throw new Error('Widget is not contained in the dock panel.');
	        }
	        // Ensure the widget is the current widget.
	        tabBar.currentTitle = widget.title;
	    };
	    /**
	     * Activate a specified widget in the dock panel.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * This will select and activate the given widget.
	     */
	    DockPanel.prototype.activateWidget = function (widget) {
	        this.selectWidget(widget);
	        widget.activate();
	    };
	    /**
	     * Save the current layout configuration of the dock panel.
	     *
	     * @returns A new config object for the current layout state.
	     *
	     * #### Notes
	     * The return value can be provided to the `restoreLayout` method
	     * in order to restore the layout to its current configuration.
	     */
	    DockPanel.prototype.saveLayout = function () {
	        return this.layout.saveLayout();
	    };
	    /**
	     * Restore the layout to a previously saved configuration.
	     *
	     * @param config - The layout configuration to restore.
	     *
	     * #### Notes
	     * Widgets which currently belong to the layout but which are not
	     * contained in the config will be unparented.
	     *
	     * The dock panel automatically reverts to `'multiple-document'`
	     * mode when a layout config is restored.
	     */
	    DockPanel.prototype.restoreLayout = function (config) {
	        // Reset the mode.
	        this._mode = 'multiple-document';
	        // Restore the layout.
	        this.layout.restoreLayout(config);
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Add a widget to the dock panel.
	     *
	     * @param widget - The widget to add to the dock panel.
	     *
	     * @param options - The additional options for adding the widget.
	     *
	     * #### Notes
	     * If the panel is in single document mode, the options are ignored
	     * and the widget is always added as tab in the hidden tab bar.
	     */
	    DockPanel.prototype.addWidget = function (widget, options) {
	        if (options === void 0) { options = {}; }
	        // Add the widget to the layout.
	        if (this._mode === 'single-document') {
	            this.layout.addWidget(widget);
	        }
	        else {
	            this.layout.addWidget(widget, options);
	        }
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Process a message sent to the widget.
	     *
	     * @param msg - The message sent to the widget.
	     */
	    DockPanel.prototype.processMessage = function (msg) {
	        if (msg.type === 'layout-modified') {
	            this._layoutModified.emit(undefined);
	        }
	        else {
	            _super.prototype.processMessage.call(this, msg);
	        }
	    };
	    /**
	     * Handle the DOM events for the dock panel.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    DockPanel.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'p-dragenter':
	                this._evtDragEnter(event);
	                break;
	            case 'p-dragleave':
	                this._evtDragLeave(event);
	                break;
	            case 'p-dragover':
	                this._evtDragOver(event);
	                break;
	            case 'p-drop':
	                this._evtDrop(event);
	                break;
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    DockPanel.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('p-dragenter', this);
	        this.node.addEventListener('p-dragleave', this);
	        this.node.addEventListener('p-dragover', this);
	        this.node.addEventListener('p-drop', this);
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    DockPanel.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('p-dragenter', this);
	        this.node.removeEventListener('p-dragleave', this);
	        this.node.removeEventListener('p-dragover', this);
	        this.node.removeEventListener('p-drop', this);
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    DockPanel.prototype.onChildAdded = function (msg) {
	        // Ignore the generated tab bars.
	        if (Private.isGeneratedTabBarProperty.get(msg.child)) {
	            return;
	        }
	        // Add the widget class to the child.
	        msg.child.addClass('p-DockPanel-widget');
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    DockPanel.prototype.onChildRemoved = function (msg) {
	        // Ignore the generated tab bars.
	        if (Private.isGeneratedTabBarProperty.get(msg.child)) {
	            return;
	        }
	        // Remove the widget class from the child.
	        msg.child.removeClass('p-DockPanel-widget');
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Handle the `'p-dragenter'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragEnter = function (event) {
	        // If the factory mime type is present, mark the event as
	        // handled in order to get the rest of the drag events.
	        if (event.mimeData.hasData('application/vnd.phosphor.widget-factory')) {
	            event.preventDefault();
	            event.stopPropagation();
	        }
	    };
	    /**
	     * Handle the `'p-dragleave'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragLeave = function (event) {
	        // Mark the event as handled.
	        event.preventDefault();
	        event.stopPropagation();
	        // Get the node into which the drag is entering.
	        var related = event.relatedTarget;
	        // Hide the overlay if the drag is leaving the dock panel.
	        if (!related || !this.node.contains(related)) {
	            this.overlay.hide(0);
	        }
	    };
	    /**
	     * Handle the `'p-dragover'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDragOver = function (event) {
	        // Mark the event as handled.
	        event.preventDefault();
	        event.stopPropagation();
	        // Show the drop indicator overlay and update the drop
	        // action based on the drop target zone under the mouse.
	        if (this._showOverlay(event.clientX, event.clientY) === 'invalid') {
	            event.dropAction = 'none';
	        }
	        else {
	            event.dropAction = event.proposedAction;
	        }
	    };
	    /**
	     * Handle the `'p-drop'` event for the dock panel.
	     */
	    DockPanel.prototype._evtDrop = function (event) {
	        // Mark the event as handled.
	        event.preventDefault();
	        event.stopPropagation();
	        // Hide the drop indicator overlay.
	        this.overlay.hide(0);
	        // Bail if the proposed action is to do nothing.
	        if (event.proposedAction === 'none') {
	            event.dropAction = 'none';
	            return;
	        }
	        // Find the drop target under the mouse.
	        var clientX = event.clientX, clientY = event.clientY;
	        var _a = Private.findDropTarget(this, clientX, clientY), zone = _a.zone, target = _a.target;
	        // Bail if the drop zone is invalid.
	        if (zone === 'invalid') {
	            event.dropAction = 'none';
	            return;
	        }
	        // Bail if the factory mime type has invalid data.
	        var mimeData = event.mimeData;
	        var factory = mimeData.getData('application/vnd.phosphor.widget-factory');
	        if (typeof factory !== 'function') {
	            event.dropAction = 'none';
	            return;
	        }
	        // Bail if the factory does not produce a widget.
	        var widget = factory();
	        if (!(widget instanceof widget_1.Widget)) {
	            event.dropAction = 'none';
	            return;
	        }
	        // Bail if the widget is an ancestor of the dock panel.
	        if (widget.contains(this)) {
	            event.dropAction = 'none';
	            return;
	        }
	        // Find the reference widget for the drop target.
	        var ref = target ? Private.getDropRef(target.tabBar) : null;
	        // Add the widget according to the indicated drop zone.
	        switch (zone) {
	            case 'root-all':
	                this.addWidget(widget);
	                break;
	            case 'root-top':
	                this.addWidget(widget, { mode: 'split-top' });
	                break;
	            case 'root-left':
	                this.addWidget(widget, { mode: 'split-left' });
	                break;
	            case 'root-right':
	                this.addWidget(widget, { mode: 'split-right' });
	                break;
	            case 'root-bottom':
	                this.addWidget(widget, { mode: 'split-bottom' });
	                break;
	            case 'widget-all':
	                this.addWidget(widget, { mode: 'tab-after', ref: ref });
	                break;
	            case 'widget-top':
	                this.addWidget(widget, { mode: 'split-top', ref: ref });
	                break;
	            case 'widget-left':
	                this.addWidget(widget, { mode: 'split-left', ref: ref });
	                break;
	            case 'widget-right':
	                this.addWidget(widget, { mode: 'split-right', ref: ref });
	                break;
	            case 'widget-bottom':
	                this.addWidget(widget, { mode: 'split-bottom', ref: ref });
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Accept the proposed drop action.
	        event.dropAction = event.proposedAction;
	        // Activate the dropped widget.
	        this.activateWidget(widget);
	    };
	    /**
	     * Handle the `'keydown'` event for the dock panel.
	     */
	    DockPanel.prototype._evtKeyDown = function (event) {
	        // Stop input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            // Finalize the mouse release.
	            this._releaseMouse();
	            // Schedule an emit of the layout modified signal.
	            messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the dock panel.
	     */
	    DockPanel.prototype._evtMouseDown = function (event) {
	        // Do nothing if the left mouse button is not pressed.
	        if (event.button !== 0) {
	            return;
	        }
	        // Find the handle which contains the mouse target, if any.
	        var layout = this.layout;
	        var target = event.target;
	        var handle = algorithm_1.find(layout.handles(), function (handle) { return handle.contains(target); });
	        if (!handle) {
	            return;
	        }
	        // Stop the event when a handle is pressed.
	        event.preventDefault();
	        event.stopPropagation();
	        // Add the extra document listeners.
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('contextmenu', this, true);
	        // Compute the offset deltas for the handle press.
	        var rect = handle.getBoundingClientRect();
	        var deltaX = event.clientX - rect.left;
	        var deltaY = event.clientY - rect.top;
	        // Override the cursor and store the press data.
	        var style = window.getComputedStyle(handle);
	        var override = dragdrop_1.Drag.overrideCursor(style.cursor);
	        this._pressData = { handle: handle, deltaX: deltaX, deltaY: deltaY, override: override };
	    };
	    /**
	     * Handle the `'mousemove'` event for the dock panel.
	     */
	    DockPanel.prototype._evtMouseMove = function (event) {
	        // Bail early if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Stop the event when dragging a handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Compute the desired offset position for the handle.
	        var rect = this.node.getBoundingClientRect();
	        var xPos = event.clientX - rect.left - this._pressData.deltaX;
	        var yPos = event.clientY - rect.top - this._pressData.deltaY;
	        // Set the handle as close to the desired position as possible.
	        var layout = this.layout;
	        layout.moveHandle(this._pressData.handle, xPos, yPos);
	    };
	    /**
	     * Handle the `'mouseup'` event for the dock panel.
	     */
	    DockPanel.prototype._evtMouseUp = function (event) {
	        // Do nothing if the left mouse button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Stop the event when releasing a handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Finalize the mouse release.
	        this._releaseMouse();
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Release the mouse grab for the dock panel.
	     */
	    DockPanel.prototype._releaseMouse = function () {
	        // Bail early if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Clear the override cursor.
	        this._pressData.override.dispose();
	        this._pressData = null;
	        // Remove the extra document listeners.
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('contextmenu', this, true);
	    };
	    /**
	     * Show the overlay indicator at the given client position.
	     *
	     * Returns the drop zone at the specified client position.
	     *
	     * #### Notes
	     * If the position is not over a valid zone, the overlay is hidden.
	     */
	    DockPanel.prototype._showOverlay = function (clientX, clientY) {
	        // Find the dock target for the given client position.
	        var _a = Private.findDropTarget(this, clientX, clientY), zone = _a.zone, target = _a.target;
	        // If the drop zone is invalid, hide the overlay and bail.
	        if (zone === 'invalid') {
	            this.overlay.hide(100);
	            return zone;
	        }
	        // Setup the variables needed to compute the overlay geometry.
	        var top;
	        var left;
	        var right;
	        var bottom;
	        var box = domutils_1.ElementExt.boxSizing(this.node); // TODO cache this?
	        var rect = this.node.getBoundingClientRect();
	        // Compute the overlay geometry based on the dock zone.
	        switch (zone) {
	            case 'root-all':
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                right = box.paddingRight;
	                bottom = box.paddingBottom;
	                break;
	            case 'root-top':
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                right = box.paddingRight;
	                bottom = rect.height * Private.GOLDEN_RATIO;
	                break;
	            case 'root-left':
	                top = box.paddingTop;
	                left = box.paddingLeft;
	                right = rect.width * Private.GOLDEN_RATIO;
	                bottom = box.paddingBottom;
	                break;
	            case 'root-right':
	                top = box.paddingTop;
	                left = rect.width * Private.GOLDEN_RATIO;
	                right = box.paddingRight;
	                bottom = box.paddingBottom;
	                break;
	            case 'root-bottom':
	                top = rect.height * Private.GOLDEN_RATIO;
	                left = box.paddingLeft;
	                right = box.paddingRight;
	                bottom = box.paddingBottom;
	                break;
	            case 'widget-all':
	                top = target.top;
	                left = target.left;
	                right = target.right;
	                bottom = target.bottom;
	                break;
	            case 'widget-top':
	                top = target.top;
	                left = target.left;
	                right = target.right;
	                bottom = target.bottom + target.height / 2;
	                break;
	            case 'widget-left':
	                top = target.top;
	                left = target.left;
	                right = target.right + target.width / 2;
	                bottom = target.bottom;
	                break;
	            case 'widget-right':
	                top = target.top;
	                left = target.left + target.width / 2;
	                right = target.right;
	                bottom = target.bottom;
	                break;
	            case 'widget-bottom':
	                top = target.top + target.height / 2;
	                left = target.left;
	                right = target.right;
	                bottom = target.bottom;
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Show the overlay with the computed geometry.
	        this.overlay.show({ top: top, left: left, right: right, bottom: bottom });
	        // Finally, return the computed drop zone.
	        return zone;
	    };
	    /**
	     * Create a new tab bar for use by the panel.
	     */
	    DockPanel.prototype._createTabBar = function () {
	        // Create the tab bar.
	        var tabBar = this._renderer.createTabBar();
	        // Set the generated tab bar property for the tab bar.
	        Private.isGeneratedTabBarProperty.set(tabBar, true);
	        // Hide the tab bar when in single document mode.
	        if (this._mode === 'single-document') {
	            tabBar.hide();
	        }
	        // Enforce necessary tab bar behavior.
	        // TODO do we really want to enforce *all* of these?
	        tabBar.tabsMovable = true;
	        tabBar.allowDeselect = false;
	        tabBar.removeBehavior = 'select-previous-tab';
	        tabBar.insertBehavior = 'select-tab-if-needed';
	        // Connect the signal handlers for the tab bar.
	        tabBar.tabMoved.connect(this._onTabMoved, this);
	        tabBar.currentChanged.connect(this._onCurrentChanged, this);
	        tabBar.tabCloseRequested.connect(this._onTabCloseRequested, this);
	        tabBar.tabDetachRequested.connect(this._onTabDetachRequested, this);
	        tabBar.tabActivateRequested.connect(this._onTabActivateRequested, this);
	        // Return the initialized tab bar.
	        return tabBar;
	    };
	    /**
	     * Create a new handle for use by the panel.
	     */
	    DockPanel.prototype._createHandle = function () {
	        return this._renderer.createHandle();
	    };
	    /**
	     * Handle the `tabMoved` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabMoved = function () {
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Handle the `currentChanged` signal from a tab bar.
	     */
	    DockPanel.prototype._onCurrentChanged = function (sender, args) {
	        // Extract the previous and current title from the args.
	        var previousTitle = args.previousTitle, currentTitle = args.currentTitle;
	        // Hide the previous widget.
	        if (previousTitle) {
	            previousTitle.owner.hide();
	        }
	        // Show the current widget.
	        if (currentTitle) {
	            currentTitle.owner.show();
	        }
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	        // Schedule an emit of the layout modified signal.
	        messaging_1.MessageLoop.postMessage(this, Private.LayoutModified);
	    };
	    /**
	     * Handle the `tabActivateRequested` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabActivateRequested = function (sender, args) {
	        args.title.owner.activate();
	    };
	    /**
	     * Handle the `tabCloseRequested` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabCloseRequested = function (sender, args) {
	        args.title.owner.close();
	    };
	    /**
	     * Handle the `tabDetachRequested` signal from a tab bar.
	     */
	    DockPanel.prototype._onTabDetachRequested = function (sender, args) {
	        var _this = this;
	        // Do nothing if a drag is already in progress.
	        if (this._drag) {
	            return;
	        }
	        // Release the tab bar's hold on the mouse.
	        sender.releaseMouse();
	        // Extract the data from the args.
	        var title = args.title, tab = args.tab, clientX = args.clientX, clientY = args.clientY;
	        // Setup the mime data for the drag operation.
	        var mimeData = new coreutils_1.MimeData();
	        var factory = function () { return title.owner; };
	        mimeData.setData('application/vnd.phosphor.widget-factory', factory);
	        // Create the drag image for the drag operation.
	        var dragImage = tab.cloneNode(true);
	        // Create the drag object to manage the drag-drop operation.
	        this._drag = new dragdrop_1.Drag({
	            mimeData: mimeData, dragImage: dragImage,
	            proposedAction: 'move',
	            supportedActions: 'move',
	        });
	        // Hide the tab node in the original tab.
	        tab.classList.add('p-mod-hidden');
	        // Create the cleanup callback.
	        var cleanup = (function () {
	            _this._drag = null;
	            tab.classList.remove('p-mod-hidden');
	        });
	        // Start the drag operation and cleanup when done.
	        this._drag.start(clientX, clientY).then(cleanup);
	    };
	    return DockPanel;
	}(widget_1.Widget));
	exports.DockPanel = DockPanel;
	/**
	 * The namespace for the `DockPanel` class statics.
	 */
	(function (DockPanel) {
	    /**
	     * A concrete implementation of `IOverlay`.
	     *
	     * This is the default overlay implementation for a dock panel.
	     */
	    var Overlay = (function () {
	        /**
	         * Construct a new overlay.
	         */
	        function Overlay() {
	            this._timer = -1;
	            this._hidden = true;
	            this.node = document.createElement('div');
	            this.node.classList.add('p-DockPanel-overlay');
	            this.node.classList.add('p-mod-hidden');
	            this.node.style.position = 'absolute';
	        }
	        /**
	         * Show the overlay using the given overlay geometry.
	         *
	         * @param geo - The desired geometry for the overlay.
	         */
	        Overlay.prototype.show = function (geo) {
	            // Update the position of the overlay.
	            var style = this.node.style;
	            style.top = geo.top + "px";
	            style.left = geo.left + "px";
	            style.right = geo.right + "px";
	            style.bottom = geo.bottom + "px";
	            // Clear any pending hide timer.
	            clearTimeout(this._timer);
	            this._timer = -1;
	            // If the overlay is already visible, we're done.
	            if (!this._hidden) {
	                return;
	            }
	            // Clear the hidden flag.
	            this._hidden = false;
	            // Finally, show the overlay.
	            this.node.classList.remove('p-mod-hidden');
	        };
	        /**
	         * Hide the overlay node.
	         *
	         * @param delay - The delay (in ms) before hiding the overlay.
	         *   A delay value <= 0 will hide the overlay immediately.
	         */
	        Overlay.prototype.hide = function (delay) {
	            var _this = this;
	            // Do nothing if the overlay is already hidden.
	            if (this._hidden) {
	                return;
	            }
	            // Hide immediately if the delay is <= 0.
	            if (delay <= 0) {
	                clearTimeout(this._timer);
	                this._timer = -1;
	                this._hidden = true;
	                this.node.classList.add('p-mod-hidden');
	                return;
	            }
	            // Do nothing if a hide is already pending.
	            if (this._timer !== -1) {
	                return;
	            }
	            // Otherwise setup the hide timer.
	            this._timer = setTimeout(function () {
	                _this._timer = -1;
	                _this._hidden = true;
	                _this.node.classList.add('p-mod-hidden');
	            }, delay);
	        };
	        return Overlay;
	    }());
	    DockPanel.Overlay = Overlay;
	    /**
	     * The default implementation of `IRenderer`.
	     */
	    var Renderer = (function () {
	        function Renderer() {
	        }
	        /**
	         * Create a new tab bar for use with a dock panel.
	         *
	         * @returns A new tab bar for a dock panel.
	         */
	        Renderer.prototype.createTabBar = function () {
	            var bar = new tabbar_1.TabBar();
	            bar.addClass('p-DockPanel-tabBar');
	            return bar;
	        };
	        /**
	         * Create a new handle node for use with a dock panel.
	         *
	         * @returns A new handle node for a dock panel.
	         */
	        Renderer.prototype.createHandle = function () {
	            var handle = document.createElement('div');
	            handle.className = 'p-DockPanel-handle';
	            return handle;
	        };
	        return Renderer;
	    }());
	    DockPanel.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    DockPanel.defaultRenderer = new Renderer();
	})(DockPanel = exports.DockPanel || (exports.DockPanel = {}));
	exports.DockPanel = DockPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A fraction used for sizing root panels; ~= `1 / golden_ratio`.
	     */
	    Private.GOLDEN_RATIO = 0.618;
	    /**
	     * The size of the edge dock zone for the root panel, in pixels.
	     */
	    Private.EDGE_SIZE = 40;
	    /**
	     * A singleton `'layout-modified'` conflatable message.
	     */
	    Private.LayoutModified = new messaging_1.ConflatableMessage('layout-modified');
	    /**
	     * An attached property used to track generated tab bars.
	     */
	    Private.isGeneratedTabBarProperty = new properties_1.AttachedProperty({
	        name: 'isGeneratedTabBar',
	        create: function () { return false; }
	    });
	    /**
	     * Create a single document config for the widgets in a dock panel.
	     */
	    function createSingleDocumentConfig(panel) {
	        // Return an empty config if the panel is empty.
	        if (panel.isEmpty) {
	            return { main: null };
	        }
	        // Get a flat array of the widgets in the panel.
	        var widgets = algorithm_1.toArray(panel.widgets());
	        // Get the first selected widget in the panel.
	        var selected = panel.selectedWidgets().next();
	        // Compute the current index for the new config.
	        var currentIndex = selected ? widgets.indexOf(selected) : -1;
	        // Return the single document config.
	        return { main: { type: 'tab-area', widgets: widgets, currentIndex: currentIndex } };
	    }
	    Private.createSingleDocumentConfig = createSingleDocumentConfig;
	    /**
	     * Find the drop target at the given client position.
	     */
	    function findDropTarget(panel, clientX, clientY) {
	        // Bail if the mouse is not over the dock panel.
	        if (!domutils_1.ElementExt.hitTest(panel.node, clientX, clientY)) {
	            return { zone: 'invalid', target: null };
	        }
	        // Look up the layout for the panel.
	        var layout = panel.layout;
	        // If the layout is empty, indicate the entire root drop zone.
	        if (layout.isEmpty) {
	            return { zone: 'root-all', target: null };
	        }
	        // Test the edge zones when in multiple document mode.
	        if (panel.mode === 'multiple-document') {
	            // Get the client rect for the dock panel.
	            var panelRect = panel.node.getBoundingClientRect();
	            // Compute the distance to each edge of the panel.
	            var pl = clientX - panelRect.left + 1;
	            var pt = clientY - panelRect.top + 1;
	            var pr = panelRect.right - clientX;
	            var pb = panelRect.bottom - clientY;
	            // Find the minimum distance to an edge.
	            var pd = Math.min(pl, pt, pr, pb);
	            // Return a root zone if the mouse is within an edge.
	            if (pd <= Private.EDGE_SIZE) {
	                var zone_1;
	                switch (pd) {
	                    case pl:
	                        zone_1 = 'root-left';
	                        break;
	                    case pt:
	                        zone_1 = 'root-top';
	                        break;
	                    case pr:
	                        zone_1 = 'root-right';
	                        break;
	                    case pb:
	                        zone_1 = 'root-bottom';
	                        break;
	                    default:
	                        throw 'unreachable';
	                }
	                return { zone: zone_1, target: null };
	            }
	        }
	        // Hit test the dock layout at the given client position.
	        var target = layout.hitTestTabAreas(clientX, clientY);
	        // Bail if no target area was found.
	        if (!target) {
	            return { zone: 'invalid', target: null };
	        }
	        // Return the whole tab area when in single document mode.
	        if (panel.mode === 'single-document') {
	            return { zone: 'widget-all', target: target };
	        }
	        // Compute the distance to each edge of the tab area.
	        var al = target.x - target.left + 1;
	        var at = target.y - target.top + 1;
	        var ar = target.left + target.width - target.x;
	        var ab = target.top + target.height - target.y;
	        // Get the X and Y edge sizes for the area.
	        var rx = Math.round(target.width / 3);
	        var ry = Math.round(target.height / 3);
	        // If the mouse is not within an edge, indicate the entire area.
	        if (al > rx && ar > rx && at > ry && ab > ry) {
	            return { zone: 'widget-all', target: target };
	        }
	        // Scale the distances by the slenderness ratio.
	        al /= rx;
	        at /= ry;
	        ar /= rx;
	        ab /= ry;
	        // Find the minimum distance to the area edge.
	        var ad = Math.min(al, at, ar, ab);
	        // Find the widget zone for the area edge.
	        var zone;
	        switch (ad) {
	            case al:
	                zone = 'widget-left';
	                break;
	            case at:
	                zone = 'widget-top';
	                break;
	            case ar:
	                zone = 'widget-right';
	                break;
	            case ab:
	                zone = 'widget-bottom';
	                break;
	            default:
	                throw 'unreachable';
	        }
	        // Return the final drop target.
	        return { zone: zone, target: target };
	    }
	    Private.findDropTarget = findDropTarget;
	    /**
	     * Get the drop reference widget for a tab bar.
	     */
	    function getDropRef(tabBar) {
	        if (tabBar.titles.length === 0) {
	            return null;
	        }
	        if (tabBar.currentTitle) {
	            return tabBar.currentTitle.owner;
	        }
	        return tabBar.titles[tabBar.titles.length - 1].owner;
	    }
	    Private.getDropRef = getDropRef;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/dockpanel.js **/


/** START DEFINE BLOCK for @phosphor/dragdrop@1.1.1/lib/index.js **/
jupyter.define('@phosphor/dragdrop@1.1.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.1.1/lib/index.js');
	/**
	 * An object which manages a drag-drop operation.
	 *
	 * A drag object dispatches four different events to drop targets:
	 *
	 * - `'p-dragenter'` - Dispatched when the mouse enters the target
	 *   element. This event must be canceled in order to receive any
	 *   of the other events.
	 *
	 * - `'p-dragover'` - Dispatched when the mouse moves over the drop
	 *   target. It must cancel the event and set the `dropAction` to one
	 *   of the supported actions in order to receive drop events.
	 *
	 * - `'p-dragleave'` - Dispatched when the mouse leaves the target
	 *   element. This includes moving the mouse into child elements.
	 *
	 * - `'p-drop'`- Dispatched when the mouse is released over the target
	 *   element when the target indicates an appropriate drop action. If
	 *   the event is canceled, the indicated drop action is returned to
	 *   the initiator through the resolved promise.
	 *
	 * A drag operation can be terminated at any time by pressing `Escape`
	 * or by disposing the drag object.
	 *
	 * A drag object has the ability to automatically scroll a scrollable
	 * element when the mouse is hovered near one of its edges. To enable
	 * this, add the `data-p-dragscroll` attribute to any element which
	 * the drag object should consider for scrolling.
	 *
	 * #### Notes
	 * This class is designed to be used when dragging and dropping custom
	 * data *within* a single application. It is *not* a replacement for
	 * the native drag-drop API. Instead, it provides an API which allows
	 * drag operations to be initiated programmatically and enables the
	 * transfer of arbitrary non-string objects; features which are not
	 * possible with the native drag-drop API.
	 */
	var Drag = (function () {
	    /**
	     * Construct a new drag object.
	     *
	     * @param options - The options for initializing the drag.
	     */
	    function Drag(options) {
	        var _this = this;
	        /**
	         * The scroll loop handler function.
	         */
	        this._onScrollFrame = function () {
	            // Bail early if there is no scroll target.
	            if (!_this._scrollTarget) {
	                return;
	            }
	            // Unpack the scroll target.
	            var _a = _this._scrollTarget, element = _a.element, edge = _a.edge, distance = _a.distance;
	            // Calculate the scroll delta using nonlinear acceleration.
	            var d = Private.SCROLL_EDGE_SIZE - distance;
	            var f = Math.pow(d / Private.SCROLL_EDGE_SIZE, 2);
	            var s = Math.max(1, Math.round(f * Private.SCROLL_EDGE_SIZE));
	            // Scroll the element in the specified direction.
	            switch (edge) {
	                case 'top':
	                    element.scrollTop -= s;
	                    break;
	                case 'left':
	                    element.scrollLeft -= s;
	                    break;
	                case 'right':
	                    element.scrollLeft += s;
	                    break;
	                case 'bottom':
	                    element.scrollTop += s;
	                    break;
	            }
	            // Request the next cycle of the scroll loop.
	            requestAnimationFrame(_this._onScrollFrame);
	        };
	        this._disposed = false;
	        this._dropAction = 'none';
	        this._override = null;
	        this._currentTarget = null;
	        this._currentElement = null;
	        this._promise = null;
	        this._scrollTarget = null;
	        this._resolve = null;
	        this.mimeData = options.mimeData;
	        this.dragImage = options.dragImage || null;
	        this.proposedAction = options.proposedAction || 'copy';
	        this.supportedActions = options.supportedActions || 'all';
	        this.source = options.source || null;
	    }
	    /**
	     * Dispose of the resources held by the drag object.
	     *
	     * #### Notes
	     * This will cancel the drag operation if it is active.
	     */
	    Drag.prototype.dispose = function () {
	        // Do nothing if the drag object is already disposed.
	        if (this._disposed) {
	            return;
	        }
	        this._disposed = true;
	        // If there is a current target, dispatch a drag leave event.
	        if (this._currentTarget) {
	            var event_1 = Private.createMouseEvent('mouseup', -1, -1);
	            Private.dispatchDragLeave(this, this._currentTarget, null, event_1);
	        }
	        // Finalize the drag object with `'none'`.
	        this._finalize('none');
	    };
	    Object.defineProperty(Drag.prototype, "isDisposed", {
	        /**
	         * Test whether the drag object is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Start the drag operation at the specified client position.
	     *
	     * @param clientX - The client X position for the drag start.
	     *
	     * @param clientY - The client Y position for the drag start.
	     *
	     * @returns A promise which resolves to the result of the drag.
	     *
	     * #### Notes
	     * If the drag has already been started, the promise created by the
	     * first call to `start` is returned.
	     *
	     * If the drag operation has ended, or if the drag object has been
	     * disposed, the returned promise will resolve to `'none'`.
	     *
	     * The drag object will be automatically disposed when drag operation
	     * completes. This means `Drag` objects are for single-use only.
	     *
	     * This method assumes the left mouse button is already held down.
	     */
	    Drag.prototype.start = function (clientX, clientY) {
	        var _this = this;
	        // If the drag object is already disposed, resolve to `None`.
	        if (this._disposed) {
	            return Promise.resolve('none');
	        }
	        // If the drag has already been started, return the promise.
	        if (this._promise) {
	            return this._promise;
	        }
	        // Install the document listeners for the drag object.
	        this._addListeners();
	        // Attach the drag image at the specified client position.
	        this._attachDragImage(clientX, clientY);
	        // Create the promise which will be resolved on completion.
	        this._promise = new Promise(function (resolve, reject) {
	            _this._resolve = resolve;
	        });
	        // Trigger a fake move event to kick off the drag operation.
	        var event = Private.createMouseEvent('mousemove', clientX, clientY);
	        document.dispatchEvent(event);
	        // Return the pending promise for the drag operation.
	        return this._promise;
	    };
	    /**
	     * Handle the DOM events for the drag operation.
	     *
	     * @param event - The DOM event sent to the drag object.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the document. It should not be
	     * called directly by user code.
	     */
	    Drag.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            default:
	                // Stop all other events during drag-drop.
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * Handle the `'mousemove'` event for the drag object.
	     */
	    Drag.prototype._evtMouseMove = function (event) {
	        // Stop all input events during drag-drop.
	        event.preventDefault();
	        event.stopPropagation();
	        // Update the current target node and dispatch enter/leave events.
	        this._updateCurrentTarget(event);
	        // Update the drag scroll element.
	        this._updateDragScroll(event);
	        // Move the drag image to the specified client position. This is
	        // performed *after* dispatching to prevent unnecessary reflows.
	        this._moveDragImage(event.clientX, event.clientY);
	    };
	    /**
	     * Handle the `'mouseup'` event for the drag object.
	     */
	    Drag.prototype._evtMouseUp = function (event) {
	        // Stop all input events during drag-drop.
	        event.preventDefault();
	        event.stopPropagation();
	        // Do nothing if the left button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Update the current target node and dispatch enter/leave events.
	        // This prevents a subtle issue where the DOM mutates under the
	        // cursor after the last move event but before the drop event.
	        this._updateCurrentTarget(event);
	        // If there is no current target, finalize with `'none'`.
	        if (!this._currentTarget) {
	            this._finalize('none');
	            return;
	        }
	        // If the last drop action was `'none'`, dispatch a leave event
	        // to the current target and finalize the drag with `'none'`.
	        if (this._dropAction === 'none') {
	            Private.dispatchDragLeave(this, this._currentTarget, null, event);
	            this._finalize('none');
	            return;
	        }
	        // Dispatch the drop event at the current target and finalize
	        // with the resulting drop action.
	        var action = Private.dispatchDrop(this, this._currentTarget, event);
	        this._finalize(action);
	    };
	    /**
	     * Handle the `'keydown'` event for the drag object.
	     */
	    Drag.prototype._evtKeyDown = function (event) {
	        // Stop all input events during drag-drop.
	        event.preventDefault();
	        event.stopPropagation();
	        // Cancel the drag if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            this.dispose();
	        }
	    };
	    /**
	     * Add the document event listeners for the drag object.
	     */
	    Drag.prototype._addListeners = function () {
	        document.addEventListener('mousedown', this, true);
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('mouseenter', this, true);
	        document.addEventListener('mouseleave', this, true);
	        document.addEventListener('mouseover', this, true);
	        document.addEventListener('mouseout', this, true);
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('keyup', this, true);
	        document.addEventListener('keypress', this, true);
	        document.addEventListener('contextmenu', this, true);
	    };
	    /**
	     * Remove the document event listeners for the drag object.
	     */
	    Drag.prototype._removeListeners = function () {
	        document.removeEventListener('mousedown', this, true);
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('mouseenter', this, true);
	        document.removeEventListener('mouseleave', this, true);
	        document.removeEventListener('mouseover', this, true);
	        document.removeEventListener('mouseout', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('keyup', this, true);
	        document.removeEventListener('keypress', this, true);
	        document.removeEventListener('contextmenu', this, true);
	    };
	    /**
	     * Update the drag scroll element under the mouse.
	     */
	    Drag.prototype._updateDragScroll = function (event) {
	        // Find the scroll target under the mouse.
	        var target = Private.findScrollTarget(event);
	        // Bail if there is nothing to scroll.
	        if (!this._scrollTarget && !target) {
	            return;
	        }
	        // Start the scroll loop if needed.
	        if (!this._scrollTarget) {
	            setTimeout(this._onScrollFrame, 500);
	        }
	        // Update the scroll target.
	        this._scrollTarget = target;
	    };
	    /**
	     * Update the current target node using the given mouse event.
	     */
	    Drag.prototype._updateCurrentTarget = function (event) {
	        // Fetch common local state.
	        var prevTarget = this._currentTarget;
	        var currTarget = this._currentTarget;
	        var prevElem = this._currentElement;
	        // Find the current indicated element at the given position.
	        var currElem = document.elementFromPoint(event.clientX, event.clientY);
	        // Update the current element reference.
	        this._currentElement = currElem;
	        // If the indicated element changes from the previous iteration,
	        // and is different from the current target, dispatch the exit
	        // event to the target.
	        if (currElem !== prevElem && currElem !== currTarget) {
	            Private.dispatchDragExit(this, currTarget, currElem, event);
	        }
	        // If the indicated element changes from the previous iteration,
	        // and is different from the current target, dispatch the enter
	        // event and compute the new target element.
	        if (currElem !== prevElem && currElem !== currTarget) {
	            currTarget = Private.dispatchDragEnter(this, currElem, currTarget, event);
	        }
	        // If the current target element has changed, update the current
	        // target reference and dispatch the leave event to the old target.
	        if (currTarget !== prevTarget) {
	            this._currentTarget = currTarget;
	            Private.dispatchDragLeave(this, prevTarget, currTarget, event);
	        }
	        // Dispatch the drag over event and update the drop action.
	        var action = Private.dispatchDragOver(this, currTarget, event);
	        this._setDropAction(action);
	    };
	    /**
	     * Attach the drag image element at the specified location.
	     *
	     * This is a no-op if there is no drag image element.
	     */
	    Drag.prototype._attachDragImage = function (clientX, clientY) {
	        if (!this.dragImage) {
	            return;
	        }
	        this.dragImage.classList.add('p-mod-drag-image');
	        var style = this.dragImage.style;
	        style.pointerEvents = 'none';
	        style.position = 'fixed';
	        style.top = clientY + "px";
	        style.left = clientX + "px";
	        document.body.appendChild(this.dragImage);
	    };
	    /**
	     * Move the drag image element to the specified location.
	     *
	     * This is a no-op if there is no drag image element.
	     */
	    Drag.prototype._moveDragImage = function (clientX, clientY) {
	        if (!this.dragImage) {
	            return;
	        }
	        var style = this.dragImage.style;
	        style.top = clientY + "px";
	        style.left = clientX + "px";
	    };
	    /**
	     * Detach the drag image element from the DOM.
	     *
	     * This is a no-op if there is no drag image element.
	     */
	    Drag.prototype._detachDragImage = function () {
	        if (!this.dragImage) {
	            return;
	        }
	        var parent = this.dragImage.parentNode;
	        if (!parent) {
	            return;
	        }
	        parent.removeChild(this.dragImage);
	    };
	    /**
	     * Set the internal drop action state and update the drag cursor.
	     */
	    Drag.prototype._setDropAction = function (action) {
	        action = Private.validateAction(action, this.supportedActions);
	        if (this._override && this._dropAction === action) {
	            return;
	        }
	        switch (action) {
	            case 'none':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('no-drop');
	                break;
	            case 'copy':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('copy');
	                break;
	            case 'link':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('alias');
	                break;
	            case 'move':
	                this._dropAction = action;
	                this._override = Drag.overrideCursor('move');
	                break;
	        }
	    };
	    /**
	     * Finalize the drag operation and resolve the drag promise.
	     */
	    Drag.prototype._finalize = function (action) {
	        // Store the resolve function as a temp variable.
	        var resolve = this._resolve;
	        // Remove the document event listeners.
	        this._removeListeners();
	        // Detach the drag image.
	        this._detachDragImage();
	        // Dispose of the cursor override.
	        if (this._override) {
	            this._override.dispose();
	            this._override = null;
	        }
	        // Clear the mime data.
	        this.mimeData.clear();
	        // Clear the rest of the internal drag state.
	        this._disposed = true;
	        this._dropAction = 'none';
	        this._currentTarget = null;
	        this._currentElement = null;
	        this._scrollTarget = null;
	        this._promise = null;
	        this._resolve = null;
	        // Finally, resolve the promise to the given drop action.
	        if (resolve) {
	            resolve(action);
	        }
	    };
	    return Drag;
	}());
	exports.Drag = Drag;
	/**
	 * The namespace for the `Drag` class statics.
	 */
	(function (Drag) {
	    /**
	     * Override the cursor icon for the entire document.
	     *
	     * @param cursor - The string representing the cursor style.
	     *
	     * @returns A disposable which will clear the override when disposed.
	     *
	     * #### Notes
	     * The most recent call to `overrideCursor` takes precedence.
	     * Disposing an old override has no effect on the current override.
	     *
	     * This utility function is used by the `Drag` class to override the
	     * mouse cursor during a drag-drop operation, but it can also be used
	     * by other classes to fix the cursor icon during normal mouse drags.
	     *
	     * #### Example
	     * ```typescript
	     * import { Drag } from '@phosphor/dragdrop';
	     *
	     * // Force the cursor to be 'wait' for the entire document.
	     * let override = Drag.overrideCursor('wait');
	     *
	     * // Clear the override by disposing the return value.
	     * override.dispose();
	     * ```
	     */
	    function overrideCursor(cursor) {
	        var id = ++overrideCursorID;
	        document.body.style.cursor = cursor;
	        document.body.classList.add('p-mod-override-cursor');
	        return new disposable_1.DisposableDelegate(function () {
	            if (id === overrideCursorID) {
	                document.body.style.cursor = '';
	                document.body.classList.remove('p-mod-override-cursor');
	            }
	        });
	    }
	    Drag.overrideCursor = overrideCursor;
	    /**
	     * The internal id for the active cursor override.
	     */
	    var overrideCursorID = 0;
	})(Drag = exports.Drag || (exports.Drag = {}));
	exports.Drag = Drag;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The size of a drag scroll edge, in pixels.
	     */
	    Private.SCROLL_EDGE_SIZE = 20;
	    /**
	     * Validate the given action is one of the supported actions.
	     *
	     * Returns the given action or `'none'` if the action is unsupported.
	     */
	    function validateAction(action, supported) {
	        return (actionTable[action] & supportedTable[supported]) ? action : 'none';
	    }
	    Private.validateAction = validateAction;
	    /**
	     * Create a left mouse event at the given position.
	     *
	     * @param type - The event type for the mouse event.
	     *
	     * @param clientX - The client X position.
	     *
	     * @param clientY - The client Y position.
	     *
	     * @returns A newly created and initialized mouse event.
	     */
	    function createMouseEvent(type, clientX, clientY) {
	        var event = document.createEvent('MouseEvent');
	        event.initMouseEvent(type, true, true, window, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null);
	        return event;
	    }
	    Private.createMouseEvent = createMouseEvent;
	    /**
	     * Find the drag scroll target under the mouse, if any.
	     */
	    function findScrollTarget(event) {
	        // Look up the client mouse position.
	        var x = event.clientX;
	        var y = event.clientY;
	        // Get the element under the mouse.
	        var element = document.elementFromPoint(x, y);
	        // Search for a scrollable target based on the mouse position.
	        // The null assert in third clause of for-loop is required due to:
	        // https://github.com/Microsoft/TypeScript/issues/14143
	        for (; element; element = element.parentElement) {
	            // Ignore elements which are not marked as scrollable.
	            if (!element.hasAttribute('data-p-dragscroll')) {
	                continue;
	            }
	            // Set up the coordinate offsets for the element.
	            var offsetX = 0;
	            var offsetY = 0;
	            if (element === document.body) {
	                offsetX = window.pageXOffset;
	                offsetY = window.pageYOffset;
	            }
	            // Get the element bounds in viewport coordinates.
	            var r = element.getBoundingClientRect();
	            var top_1 = r.top + offsetY;
	            var left = r.left + offsetX;
	            var right = left + r.width;
	            var bottom = top_1 + r.height;
	            // Skip the element if it's not under the mouse.
	            if (x < left || x >= right || y < top_1 || y >= bottom) {
	                continue;
	            }
	            // Compute the distance to each edge.
	            var dl = x - left + 1;
	            var dt = y - top_1 + 1;
	            var dr = right - x;
	            var db = bottom - y;
	            // Find the smallest of the edge distances.
	            var distance = Math.min(dl, dt, dr, db);
	            // Skip the element if the mouse is not within a scroll edge.
	            if (distance > Private.SCROLL_EDGE_SIZE) {
	                continue;
	            }
	            // Set up the edge result variable.
	            var edge = void 0;
	            // Find the edge for the computed distance.
	            switch (distance) {
	                case db:
	                    edge = 'bottom';
	                    break;
	                case dt:
	                    edge = 'top';
	                    break;
	                case dr:
	                    edge = 'right';
	                    break;
	                case dl:
	                    edge = 'left';
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	            // Compute how much the element can scroll in width and height.
	            var dsw = element.scrollWidth - element.clientWidth;
	            var dsh = element.scrollHeight - element.clientHeight;
	            // Determine if the element should be scrolled for the edge.
	            var shouldScroll = void 0;
	            switch (edge) {
	                case 'top':
	                    shouldScroll = dsh > 0 && element.scrollTop > 0;
	                    break;
	                case 'left':
	                    shouldScroll = dsw > 0 && element.scrollLeft > 0;
	                    break;
	                case 'right':
	                    shouldScroll = dsw > 0 && element.scrollLeft < dsw;
	                    break;
	                case 'bottom':
	                    shouldScroll = dsh > 0 && element.scrollTop < dsh;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	            // Skip the element if it should not be scrolled.
	            if (!shouldScroll) {
	                continue;
	            }
	            // Return the drag scroll target.
	            return { element: element, edge: edge, distance: distance };
	        }
	        // No drag scroll target was found.
	        return null;
	    }
	    Private.findScrollTarget = findScrollTarget;
	    /**
	     * Dispatch a drag enter event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param currElem - The currently indicated element, or `null`. This
	     *   is the "immediate user selection" from the whatwg spec.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * @returns The element to use as the current drag target. This is the
	     *   "current target element" from the whatwg spec, and may be `null`.
	     *
	     * #### Notes
	     * This largely implements the drag enter portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragEnter(drag, currElem, currTarget, event) {
	        // If the current element is null, return null as the new target.
	        if (!currElem) {
	            return null;
	        }
	        // Dispatch a drag enter event to the current element.
	        var dragEvent = createDragEvent('p-dragenter', drag, event, currTarget);
	        var canceled = !currElem.dispatchEvent(dragEvent);
	        // If the event was canceled, use the current element as the new target.
	        if (canceled) {
	            return currElem;
	        }
	        // If the current element is the document body, keep the original target.
	        if (currElem === document.body) {
	            return currTarget;
	        }
	        // Dispatch a drag enter event on the document body.
	        dragEvent = createDragEvent('p-dragenter', drag, event, currTarget);
	        document.body.dispatchEvent(dragEvent);
	        // Ignore the event cancellation, and use the body as the new target.
	        return document.body;
	    }
	    Private.dispatchDragEnter = dispatchDragEnter;
	    /**
	     * Dispatch a drag exit event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param prevTarget - The previous target element, or `null`. This
	     *   is the previous "current target element" from the whatwg spec.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * #### Notes
	     * This largely implements the drag exit portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragExit(drag, prevTarget, currTarget, event) {
	        // If the previous target is null, do nothing.
	        if (!prevTarget) {
	            return;
	        }
	        // Dispatch the drag exit event to the previous target.
	        var dragEvent = createDragEvent('p-dragexit', drag, event, currTarget);
	        prevTarget.dispatchEvent(dragEvent);
	    }
	    Private.dispatchDragExit = dispatchDragExit;
	    /**
	     * Dispatch a drag leave event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param prevTarget - The previous target element, or `null`. This
	     *   is the previous "current target element" from the whatwg spec.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * #### Notes
	     * This largely implements the drag leave portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragLeave(drag, prevTarget, currTarget, event) {
	        // If the previous target is null, do nothing.
	        if (!prevTarget) {
	            return;
	        }
	        // Dispatch the drag leave event to the previous target.
	        var dragEvent = createDragEvent('p-dragleave', drag, event, currTarget);
	        prevTarget.dispatchEvent(dragEvent);
	    }
	    Private.dispatchDragLeave = dispatchDragLeave;
	    /**
	     * Dispatch a drag over event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * @returns The `DropAction` result of the drag over event.
	     *
	     * #### Notes
	     * This largely implements the drag over portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDragOver(drag, currTarget, event) {
	        // If there is no current target, the drop action is none.
	        if (!currTarget) {
	            return 'none';
	        }
	        // Dispatch the drag over event to the current target.
	        var dragEvent = createDragEvent('p-dragover', drag, event, null);
	        var canceled = !currTarget.dispatchEvent(dragEvent);
	        // If the event was canceled, return the drop action result.
	        if (canceled) {
	            return dragEvent.dropAction;
	        }
	        // Otherwise, the effective drop action is none.
	        return 'none';
	    }
	    Private.dispatchDragOver = dispatchDragOver;
	    /**
	     * Dispatch a drop event to the indicated element.
	     *
	     * @param drag - The drag object associated with the action.
	     *
	     * @param currTarget - The current drag target element, or `null`. This
	     *   is the "current target element" from the whatwg spec.
	     *
	     * @param event - The mouse event related to the action.
	     *
	     * @returns The `DropAction` result of the drop event.
	     *
	     * #### Notes
	     * This largely implements the drag over portion of the whatwg spec:
	     * https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model
	     */
	    function dispatchDrop(drag, currTarget, event) {
	        // If there is no current target, the drop action is none.
	        if (!currTarget) {
	            return 'none';
	        }
	        // Dispatch the drop event to the current target.
	        var dragEvent = createDragEvent('p-drop', drag, event, null);
	        var canceled = !currTarget.dispatchEvent(dragEvent);
	        // If the event was canceled, return the drop action result.
	        if (canceled) {
	            return dragEvent.dropAction;
	        }
	        // Otherwise, the effective drop action is none.
	        return 'none';
	    }
	    Private.dispatchDrop = dispatchDrop;
	    /**
	     * A lookup table from drop action to bit value.
	     */
	    var actionTable = {
	        'none': 0x0,
	        'copy': 0x1,
	        'link': 0x2,
	        'move': 0x4
	    };
	    /**
	     * A lookup table from supported action to drop action bit mask.
	     */
	    var supportedTable = {
	        'none': actionTable['none'],
	        'copy': actionTable['copy'],
	        'link': actionTable['link'],
	        'move': actionTable['move'],
	        'copy-link': actionTable['copy'] | actionTable['link'],
	        'copy-move': actionTable['copy'] | actionTable['move'],
	        'link-move': actionTable['link'] | actionTable['move'],
	        'all': actionTable['copy'] | actionTable['link'] | actionTable['move']
	    };
	    /**
	     * Create a new initialized `IDragEvent` from the given data.
	     *
	     * @param type - The event type for the drag event.
	     *
	     * @param drag - The drag object to use for seeding the drag data.
	     *
	     * @param event - The mouse event to use for seeding the mouse data.
	     *
	     * @param related - The related target for the event, or `null`.
	     *
	     * @returns A new object which implements `IDragEvent`.
	     */
	    function createDragEvent(type, drag, event, related) {
	        // Create a new mouse event to use as the drag event. Currently,
	        // JS engines do now allow user-defined Event subclasses.
	        var dragEvent = document.createEvent('MouseEvent');
	        // Initialize the mouse event data.
	        dragEvent.initMouseEvent(type, true, true, window, 0, event.screenX, event.screenY, event.clientX, event.clientY, event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.button, related);
	        // Forcefully add the custom drag event properties.
	        dragEvent.dropAction = 'none';
	        dragEvent.mimeData = drag.mimeData;
	        dragEvent.proposedAction = drag.proposedAction;
	        dragEvent.supportedActions = drag.supportedActions;
	        dragEvent.source = drag.source;
	        // Return the fully initialized drag event.
	        return dragEvent;
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/dragdrop@1.1.1/lib/index.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/tabbar.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/tabbar.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var dragdrop_1 = __jupyter_require__('@phosphor/dragdrop@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var virtualdom_1 = __jupyter_require__('@phosphor/virtualdom@^1.1.1/lib/index.js');
	var title_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/title.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A widget which displays titles as a single row or column of tabs.
	 *
	 * #### Notes
	 * If CSS transforms are used to rotate nodes for vertically oriented
	 * text, then tab dragging will not work correctly. The `tabsMovable`
	 * property should be set to `false` when rotating nodes from CSS.
	 */
	var TabBar = (function (_super) {
	    __extends(TabBar, _super);
	    /**
	     * Construct a new tab bar.
	     *
	     * @param options - The options for initializing the tab bar.
	     */
	    function TabBar(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._currentIndex = -1;
	        _this._titles = [];
	        _this._previousTitle = null;
	        _this._dragData = null;
	        _this._tabMoved = new signaling_1.Signal(_this);
	        _this._currentChanged = new signaling_1.Signal(_this);
	        _this._tabCloseRequested = new signaling_1.Signal(_this);
	        _this._tabDetachRequested = new signaling_1.Signal(_this);
	        _this._tabActivateRequested = new signaling_1.Signal(_this);
	        _this.addClass('p-TabBar');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.tabsMovable = options.tabsMovable || false;
	        _this.allowDeselect = options.allowDeselect || false;
	        _this.insertBehavior = options.insertBehavior || 'select-tab-if-needed';
	        _this.removeBehavior = options.removeBehavior || 'select-tab-after';
	        _this.renderer = options.renderer || TabBar.defaultRenderer;
	        _this._orientation = options.orientation || 'horizontal';
	        _this.dataset['orientation'] = _this._orientation;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    TabBar.prototype.dispose = function () {
	        this._releaseMouse();
	        this._titles.length = 0;
	        this._previousTitle = null;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(TabBar.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current tab is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected tab is changed
	         * either through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current
	         * tab changes due to tabs being inserted, removed, or moved. It is
	         * only emitted when the actual current tab node is changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabMoved", {
	        /**
	         * A signal emitted when a tab is moved by the user.
	         *
	         * #### Notes
	         * This signal is emitted when a tab is moved by user interaction.
	         *
	         * This signal is not emitted when a tab is moved programmatically.
	         */
	        get: function () {
	            return this._tabMoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabActivateRequested", {
	        /**
	         * A signal emitted when a tab is clicked by the user.
	         *
	         * #### Notes
	         * If the clicked tab is not the current tab, the clicked tab will be
	         * made current and the `currentChanged` signal will be emitted first.
	         *
	         * This signal is emitted even if the clicked tab is the current tab.
	         */
	        get: function () {
	            return this._tabActivateRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabCloseRequested", {
	        /**
	         * A signal emitted when a tab close icon is clicked.
	         *
	         * #### Notes
	         * This signal is not emitted unless the tab title is `closable`.
	         */
	        get: function () {
	            return this._tabCloseRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "tabDetachRequested", {
	        /**
	         * A signal emitted when a tab is dragged beyond the detach threshold.
	         *
	         * #### Notes
	         * This signal is emitted when the user drags a tab with the mouse,
	         * and mouse is dragged beyond the detach threshold.
	         *
	         * The consumer of the signal should call `releaseMouse` and remove
	         * the tab in order to complete the detach.
	         *
	         * This signal is only emitted once per drag cycle.
	         */
	        get: function () {
	            return this._tabDetachRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "currentTitle", {
	        /**
	         * Get the currently selected title.
	         *
	         * #### Notes
	         * This will be `null` if no tab is selected.
	         */
	        get: function () {
	            return this._titles[this._currentIndex] || null;
	        },
	        /**
	         * Set the currently selected title.
	         *
	         * #### Notes
	         * If the title does not exist, the title will be set to `null`.
	         */
	        set: function (value) {
	            this.currentIndex = value ? this._titles.indexOf(value) : -1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "currentIndex", {
	        /**
	         * Get the index of the currently selected tab.
	         *
	         * #### Notes
	         * This will be `-1` if no tab is selected.
	         */
	        get: function () {
	            return this._currentIndex;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * #### Notes
	         * If the value is out of range, the index will be set to `-1`.
	         */
	        set: function (value) {
	            // Adjust for an out of range index.
	            if (value < 0 || value >= this._titles.length) {
	                value = -1;
	            }
	            // Bail early if the index will not change.
	            if (this._currentIndex === value) {
	                return;
	            }
	            // Look up the previous index and title.
	            var pi = this._currentIndex;
	            var pt = this._titles[pi] || null;
	            // Look up the current index and title.
	            var ci = value;
	            var ct = this._titles[ci] || null;
	            // Update the current index and previous title.
	            this._currentIndex = ci;
	            this._previousTitle = pt;
	            // Schedule an update of the tabs.
	            this.update();
	            // Emit the current changed signal.
	            this._currentChanged.emit({
	                previousIndex: pi, previousTitle: pt,
	                currentIndex: ci, currentTitle: ct
	            });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "orientation", {
	        /**
	         * Get the orientation of the tab bar.
	         *
	         * #### Notes
	         * This controls whether the tabs are arranged in a row or column.
	         */
	        get: function () {
	            return this._orientation;
	        },
	        /**
	         * Set the orientation of the tab bar.
	         *
	         * #### Notes
	         * This controls whether the tabs are arranged in a row or column.
	         */
	        set: function (value) {
	            // Do nothing if the orientation does not change.
	            if (this._orientation === value) {
	                return;
	            }
	            // Release the mouse before making any changes.
	            this._releaseMouse();
	            // Toggle the orientation values.
	            this._orientation = value;
	            this.dataset['orientation'] = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "titles", {
	        /**
	         * A read-only array of the titles in the tab bar.
	         */
	        get: function () {
	            return this._titles;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabBar.prototype, "contentNode", {
	        /**
	         * The tab bar content node.
	         *
	         * #### Notes
	         * This is the node which holds the tab nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-TabBar-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a tab to the end of the tab bar.
	     *
	     * @param value - The title which holds the data for the tab,
	     *   or an options object to convert to a title.
	     *
	     * @returns The title object added to the tab bar.
	     *
	     * #### Notes
	     * If the title is already added to the tab bar, it will be moved.
	     */
	    TabBar.prototype.addTab = function (value) {
	        return this.insertTab(this._titles.length, value);
	    };
	    /**
	     * Insert a tab into the tab bar at the specified index.
	     *
	     * @param index - The index at which to insert the tab.
	     *
	     * @param value - The title which holds the data for the tab,
	     *   or an options object to convert to a title.
	     *
	     * @returns The title object added to the tab bar.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the tabs.
	     *
	     * If the title is already added to the tab bar, it will be moved.
	     */
	    TabBar.prototype.insertTab = function (index, value) {
	        // Release the mouse before making any changes.
	        this._releaseMouse();
	        // Coerce the value to a title.
	        var title = Private.asTitle(value);
	        // Look up the index of the title.
	        var i = this._titles.indexOf(title);
	        // Clamp the insert index to the array bounds.
	        var j = Math.max(0, Math.min(index, this._titles.length));
	        // If the title is not in the array, insert it.
	        if (i === -1) {
	            // Insert the title into the array.
	            algorithm_1.ArrayExt.insert(this._titles, j, title);
	            // Connect to the title changed signal.
	            title.changed.connect(this._onTitleChanged, this);
	            // Schedule an update of the tabs.
	            this.update();
	            // Adjust the current index for the insert.
	            this._adjustCurrentForInsert(j, title);
	            // Return the title added to the tab bar.
	            return title;
	        }
	        // Otherwise, the title exists in the array and should be moved.
	        // Adjust the index if the location is at the end of the array.
	        if (j === this._titles.length) {
	            j--;
	        }
	        // Bail if there is no effective move.
	        if (i === j) {
	            return title;
	        }
	        // Move the title to the new location.
	        algorithm_1.ArrayExt.move(this._titles, i, j);
	        // Schedule an update of the tabs.
	        this.update();
	        // Adjust the current index for the move.
	        this._adjustCurrentForMove(i, j);
	        // Return the title added to the tab bar.
	        return title;
	    };
	    /**
	     * Remove a tab from the tab bar.
	     *
	     * @param title - The title for the tab to remove.
	     *
	     * #### Notes
	     * This is a no-op if the title is not in the tab bar.
	     */
	    TabBar.prototype.removeTab = function (title) {
	        this.removeTabAt(this._titles.indexOf(title));
	    };
	    /**
	     * Remove the tab at a given index from the tab bar.
	     *
	     * @param index - The index of the tab to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    TabBar.prototype.removeTabAt = function (index) {
	        // Release the mouse before making any changes.
	        this._releaseMouse();
	        // Remove the title from the array.
	        var title = algorithm_1.ArrayExt.removeAt(this._titles, index);
	        // Bail if the index is out of range.
	        if (!title) {
	            return;
	        }
	        // Disconnect from the title changed signal.
	        title.changed.disconnect(this._onTitleChanged, this);
	        // Clear the previous title if it's being removed.
	        if (title === this._previousTitle) {
	            this._previousTitle = null;
	        }
	        // Schedule an update of the tabs.
	        this.update();
	        // Adjust the current index for the remove.
	        this._adjustCurrentForRemove(index, title);
	    };
	    /**
	     * Remove all tabs from the tab bar.
	     */
	    TabBar.prototype.clearTabs = function () {
	        // Bail if there is nothing to remove.
	        if (this._titles.length === 0) {
	            return;
	        }
	        // Release the mouse before making any changes.
	        this._releaseMouse();
	        // Disconnect from the title changed signals.
	        for (var _i = 0, _a = this._titles; _i < _a.length; _i++) {
	            var title = _a[_i];
	            title.changed.disconnect(this._onTitleChanged, this);
	        }
	        // Get the current index and title.
	        var pi = this.currentIndex;
	        var pt = this.currentTitle;
	        // Reset the current index and previous title.
	        this._currentIndex = -1;
	        this._previousTitle = null;
	        // Clear the title array.
	        this._titles.length = 0;
	        // Schedule an update of the tabs.
	        this.update();
	        // If no tab was selected, there's nothing else to do.
	        if (pi === -1) {
	            return;
	        }
	        // Emit the current changed signal.
	        this._currentChanged.emit({
	            previousIndex: pi, previousTitle: pt,
	            currentIndex: -1, currentTitle: null
	        });
	    };
	    /**
	     * Release the mouse and restore the non-dragged tab positions.
	     *
	     * #### Notes
	     * This will cause the tab bar to stop handling mouse events and to
	     * restore the tabs to their non-dragged positions.
	     */
	    TabBar.prototype.releaseMouse = function () {
	        this._releaseMouse();
	    };
	    /**
	     * Handle the DOM events for the tab bar.
	     *
	     * @param event - The DOM event sent to the tab bar.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the tab bar's DOM node.
	     *
	     * This should not be called directly by user code.
	     */
	    TabBar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    TabBar.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    TabBar.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    TabBar.prototype.onUpdateRequest = function (msg) {
	        var titles = this._titles;
	        var renderer = this.renderer;
	        var currentTitle = this.currentTitle;
	        var content = new Array(titles.length);
	        for (var i = 0, n = titles.length; i < n; ++i) {
	            var title = titles[i];
	            var current = title === currentTitle;
	            var zIndex = current ? n : n - i - 1;
	            content[i] = renderer.renderTab({ title: title, current: current, zIndex: zIndex });
	        }
	        virtualdom_1.VirtualDOM.render(content, this.contentNode);
	    };
	    /**
	     * Handle the `'keydown'` event for the tab bar.
	     */
	    TabBar.prototype._evtKeyDown = function (event) {
	        // Stop all input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            this._releaseMouse();
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the tab bar.
	     */
	    TabBar.prototype._evtMouseDown = function (event) {
	        // Do nothing if it's not a left or middle mouse press.
	        if (event.button !== 0 && event.button !== 1) {
	            return;
	        }
	        // Do nothing if a drag is in progress.
	        if (this._dragData) {
	            return;
	        }
	        // Lookup the tab nodes.
	        var tabs = this.contentNode.children;
	        // Find the index of the pressed tab.
	        var index = algorithm_1.ArrayExt.findFirstIndex(tabs, function (tab) {
	            return domutils_1.ElementExt.hitTest(tab, event.clientX, event.clientY);
	        });
	        // Do nothing if the press is not on a tab.
	        if (index === -1) {
	            return;
	        }
	        // Pressing on a tab stops the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Initialize the non-measured parts of the drag data.
	        this._dragData = {
	            tab: tabs[index],
	            index: index,
	            pressX: event.clientX,
	            pressY: event.clientY,
	            tabPos: -1,
	            tabSize: -1,
	            tabPressPos: -1,
	            targetIndex: -1,
	            tabLayout: null,
	            contentRect: null,
	            override: null,
	            dragActive: false,
	            dragAborted: false,
	            detachRequested: false
	        };
	        // Add the document mouse up listener.
	        document.addEventListener('mouseup', this, true);
	        // Do nothing else if the middle button is clicked.
	        if (event.button === 1) {
	            return;
	        }
	        // Do nothing else if the close icon is clicked.
	        var icon = tabs[index].querySelector(this.renderer.closeIconSelector);
	        if (icon && icon.contains(event.target)) {
	            return;
	        }
	        // Add the extra listeners if the tabs are movable.
	        if (this.tabsMovable) {
	            document.addEventListener('mousemove', this, true);
	            document.addEventListener('keydown', this, true);
	            document.addEventListener('contextmenu', this, true);
	        }
	        // Update the current index as appropriate.
	        if (this.allowDeselect && this.currentIndex === index) {
	            this.currentIndex = -1;
	        }
	        else {
	            this.currentIndex = index;
	        }
	        // Do nothing else if there is no current tab.
	        if (this.currentIndex === -1) {
	            return;
	        }
	        // Emit the tab activate request signal.
	        this._tabActivateRequested.emit({
	            index: this.currentIndex, title: this.currentTitle
	        });
	    };
	    /**
	     * Handle the `'mousemove'` event for the tab bar.
	     */
	    TabBar.prototype._evtMouseMove = function (event) {
	        // Do nothing if no drag is in progress.
	        var data = this._dragData;
	        if (!data) {
	            return;
	        }
	        // Suppress the event during a drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Lookup the tab nodes.
	        var tabs = this.contentNode.children;
	        // Bail early if the drag threshold has not been met.
	        if (!data.dragActive && !Private.dragExceeded(data, event)) {
	            return;
	        }
	        // Activate the drag if necessary.
	        if (!data.dragActive) {
	            // Fill in the rest of the drag data measurements.
	            var tabRect = data.tab.getBoundingClientRect();
	            if (this._orientation === 'horizontal') {
	                data.tabPos = data.tab.offsetLeft;
	                data.tabSize = tabRect.width;
	                data.tabPressPos = data.pressX - tabRect.left;
	            }
	            else {
	                data.tabPos = data.tab.offsetTop;
	                data.tabSize = tabRect.height;
	                data.tabPressPos = data.pressY - tabRect.top;
	            }
	            data.tabLayout = Private.snapTabLayout(tabs, this._orientation);
	            data.contentRect = this.contentNode.getBoundingClientRect();
	            data.override = dragdrop_1.Drag.overrideCursor('default');
	            // Add the dragging style classes.
	            data.tab.classList.add('p-mod-dragging');
	            this.addClass('p-mod-dragging');
	            // Mark the drag as active.
	            data.dragActive = true;
	        }
	        // Emit the detach requested signal if the threshold is exceeded.
	        if (!data.detachRequested && Private.detachExceeded(data, event)) {
	            // Only emit the signal once per drag cycle.
	            data.detachRequested = true;
	            // Setup the arguments for the signal.
	            var index = data.index;
	            var clientX = event.clientX;
	            var clientY = event.clientY;
	            var tab = tabs[index];
	            var title = this._titles[index];
	            // Emit the tab detach requested signal.
	            this._tabDetachRequested.emit({ index: index, title: title, tab: tab, clientX: clientX, clientY: clientY });
	            // Bail if the signal handler aborted the drag.
	            if (data.dragAborted) {
	                return;
	            }
	        }
	        // Update the positions of the tabs.
	        Private.layoutTabs(tabs, data, event, this._orientation);
	    };
	    /**
	     * Handle the `'mouseup'` event for the document.
	     */
	    TabBar.prototype._evtMouseUp = function (event) {
	        var _this = this;
	        // Do nothing if it's not a left or middle mouse release.
	        if (event.button !== 0 && event.button !== 1) {
	            return;
	        }
	        // Do nothing if no drag is in progress.
	        var data = this._dragData;
	        if (!data) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Remove the extra mouse event listeners.
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	        // Handle a release when the drag is not active.
	        if (!data.dragActive) {
	            // Clear the drag data.
	            this._dragData = null;
	            // Lookup the tab nodes.
	            var tabs = this.contentNode.children;
	            // Find the index of the released tab.
	            var index = algorithm_1.ArrayExt.findFirstIndex(tabs, function (tab) {
	                return domutils_1.ElementExt.hitTest(tab, event.clientX, event.clientY);
	            });
	            // Do nothing if the release is not on the original pressed tab.
	            if (index !== data.index) {
	                return;
	            }
	            // Ignore the release if the title is not closable.
	            var title = this._titles[index];
	            if (!title.closable) {
	                return;
	            }
	            // Emit the close requested signal if the middle button is released.
	            if (event.button === 1) {
	                this._tabCloseRequested.emit({ index: index, title: title });
	                return;
	            }
	            // Emit the close requested signal if the close icon was released.
	            var icon = tabs[index].querySelector(this.renderer.closeIconSelector);
	            if (icon && icon.contains(event.target)) {
	                this._tabCloseRequested.emit({ index: index, title: title });
	                return;
	            }
	            // Otherwise, there is nothing left to do.
	            return;
	        }
	        // Do nothing if the left button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Position the tab at its final resting position.
	        Private.finalizeTabPosition(data, this._orientation);
	        // Remove the dragging class from the tab so it can be transitioned.
	        data.tab.classList.remove('p-mod-dragging');
	        // Parse the transition duration for releasing the tab.
	        var duration = Private.parseTransitionDuration(data.tab);
	        // Complete the release on a timer to allow the tab to transition.
	        setTimeout(function () {
	            // Do nothing if the drag has been aborted.
	            if (data.dragAborted) {
	                return;
	            }
	            // Clear the drag data reference.
	            _this._dragData = null;
	            // Reset the positions of the tabs.
	            Private.resetTabPositions(_this.contentNode.children, _this._orientation);
	            // Clear the cursor grab.
	            data.override.dispose();
	            // Remove the remaining dragging style.
	            _this.removeClass('p-mod-dragging');
	            // If the tab was not moved, there is nothing else to do.
	            var i = data.index;
	            var j = data.targetIndex;
	            if (j === -1 || i === j) {
	                return;
	            }
	            // Move the title to the new locations.
	            algorithm_1.ArrayExt.move(_this._titles, i, j);
	            // Adjust the current index for the move.
	            _this._adjustCurrentForMove(i, j);
	            // Emit the tab moved signal.
	            _this._tabMoved.emit({
	                fromIndex: i, toIndex: j, title: _this._titles[j]
	            });
	            // Update the tabs immediately to prevent flicker.
	            messaging_1.MessageLoop.sendMessage(_this, widget_1.Widget.Msg.UpdateRequest);
	        }, duration);
	    };
	    /**
	     * Release the mouse and restore the non-dragged tab positions.
	     */
	    TabBar.prototype._releaseMouse = function () {
	        // Do nothing if no drag is in progress.
	        var data = this._dragData;
	        if (!data) {
	            return;
	        }
	        // Clear the drag data reference.
	        this._dragData = null;
	        // Remove the extra mouse listeners.
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	        // Indicate the drag has been aborted. This allows the mouse
	        // event handlers to return early when the drag is canceled.
	        data.dragAborted = true;
	        // If the drag is not active, there's nothing more to do.
	        if (!data.dragActive) {
	            return;
	        }
	        // Reset the tabs to their non-dragged positions.
	        Private.resetTabPositions(this.contentNode.children, this._orientation);
	        // Clear the cursor override.
	        data.override.dispose();
	        // Clear the dragging style classes.
	        data.tab.classList.remove('p-mod-dragging');
	        this.removeClass('p-mod-dragging');
	    };
	    /**
	     * Adjust the current index for a tab insert operation.
	     *
	     * This method accounts for the tab bar's insertion behavior when
	     * adjusting the current index and emitting the changed signal.
	     */
	    TabBar.prototype._adjustCurrentForInsert = function (i, title) {
	        // Lookup commonly used variables.
	        var ct = this.currentTitle;
	        var ci = this._currentIndex;
	        var bh = this.insertBehavior;
	        // Handle the behavior where the new tab is always selected,
	        // or the behavior where the new tab is selected if needed.
	        if (bh === 'select-tab' || (bh === 'select-tab-if-needed' && ci === -1)) {
	            this._currentIndex = i;
	            this._previousTitle = ct;
	            this._currentChanged.emit({
	                previousIndex: ci, previousTitle: ct,
	                currentIndex: i, currentTitle: title
	            });
	            return;
	        }
	        // Otherwise, silently adjust the current index if needed.
	        if (ci >= i) {
	            this._currentIndex++;
	        }
	    };
	    /**
	     * Adjust the current index for a tab move operation.
	     *
	     * This method will not cause the actual current tab to change.
	     * It silently adjusts the index to account for the given move.
	     */
	    TabBar.prototype._adjustCurrentForMove = function (i, j) {
	        if (this._currentIndex === i) {
	            this._currentIndex = j;
	        }
	        else if (this._currentIndex < i && this._currentIndex >= j) {
	            this._currentIndex++;
	        }
	        else if (this._currentIndex > i && this._currentIndex <= j) {
	            this._currentIndex--;
	        }
	    };
	    /**
	     * Adjust the current index for a tab remove operation.
	     *
	     * This method accounts for the tab bar's remove behavior when
	     * adjusting the current index and emitting the changed signal.
	     */
	    TabBar.prototype._adjustCurrentForRemove = function (i, title) {
	        // Lookup commonly used variables.
	        var ci = this._currentIndex;
	        var bh = this.removeBehavior;
	        // Silently adjust the index if the current tab is not removed.
	        if (ci !== i) {
	            if (ci > i) {
	                this._currentIndex--;
	            }
	            return;
	        }
	        // No tab gets selected if the tab bar is empty.
	        if (this._titles.length === 0) {
	            this._currentIndex = -1;
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: -1, currentTitle: null
	            });
	            return;
	        }
	        // Handle behavior where the next sibling tab is selected.
	        if (bh === 'select-tab-after') {
	            this._currentIndex = Math.min(i, this._titles.length - 1);
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: this._currentIndex, currentTitle: this.currentTitle
	            });
	            return;
	        }
	        // Handle behavior where the previous sibling tab is selected.
	        if (bh === 'select-tab-before') {
	            this._currentIndex = Math.max(0, i - 1);
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: this._currentIndex, currentTitle: this.currentTitle
	            });
	            return;
	        }
	        // Handle behavior where the previous history tab is selected.
	        if (bh === 'select-previous-tab') {
	            if (this._previousTitle) {
	                this._currentIndex = this._titles.indexOf(this._previousTitle);
	                this._previousTitle = null;
	            }
	            else {
	                this._currentIndex = Math.min(i, this._titles.length - 1);
	            }
	            this._currentChanged.emit({
	                previousIndex: i, previousTitle: title,
	                currentIndex: this._currentIndex, currentTitle: this.currentTitle
	            });
	            return;
	        }
	        // Otherwise, no tab gets selected.
	        this._currentIndex = -1;
	        this._currentChanged.emit({
	            previousIndex: i, previousTitle: title,
	            currentIndex: -1, currentTitle: null
	        });
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    TabBar.prototype._onTitleChanged = function (sender) {
	        this.update();
	    };
	    return TabBar;
	}(widget_1.Widget));
	exports.TabBar = TabBar;
	/**
	 * The namespace for the `TabBar` class statics.
	 */
	(function (TabBar) {
	    /**
	     * The default implementation of `IRenderer`.
	     *
	     * #### Notes
	     * Subclasses are free to reimplement rendering methods as needed.
	     */
	    var Renderer = (function () {
	        /**
	         * Construct a new renderer.
	         */
	        function Renderer() {
	            /**
	             * A selector which matches the close icon node in a tab.
	             */
	            this.closeIconSelector = '.p-TabBar-tabCloseIcon';
	            this._tabID = 0;
	            this._tabKeys = new WeakMap();
	        }
	        /**
	         * Render the virtual element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab.
	         */
	        Renderer.prototype.renderTab = function (data) {
	            var title = data.title.caption;
	            var key = this.createTabKey(data);
	            var style = this.createTabStyle(data);
	            var className = this.createTabClass(data);
	            var dataset = this.createTabDataset(data);
	            return (virtualdom_1.h.li({ key: key, className: className, title: title, style: style, dataset: dataset }, this.renderIcon(data), this.renderLabel(data), this.renderCloseIcon(data)));
	        };
	        /**
	         * Render the icon element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab icon.
	         */
	        Renderer.prototype.renderIcon = function (data) {
	            var className = this.createIconClass(data);
	            return virtualdom_1.h.div({ className: className }, data.title.iconLabel);
	        };
	        /**
	         * Render the label element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab label.
	         */
	        Renderer.prototype.renderLabel = function (data) {
	            return virtualdom_1.h.div({ className: 'p-TabBar-tabLabel' }, data.title.label);
	        };
	        /**
	         * Render the close icon element for a tab.
	         *
	         * @param data - The data to use for rendering the tab.
	         *
	         * @returns A virtual element representing the tab close icon.
	         */
	        Renderer.prototype.renderCloseIcon = function (data) {
	            return virtualdom_1.h.div({ className: 'p-TabBar-tabCloseIcon' });
	        };
	        /**
	         * Create a unique render key for the tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The unique render key for the tab.
	         *
	         * #### Notes
	         * This method caches the key against the tab title the first time
	         * the key is generated. This enables efficient rendering of moved
	         * tabs and avoids subtle hover style artifacts.
	         */
	        Renderer.prototype.createTabKey = function (data) {
	            var key = this._tabKeys.get(data.title);
	            if (key === undefined) {
	                key = "tab-key-" + this._tabID++;
	                this._tabKeys.set(data.title, key);
	            }
	            return key;
	        };
	        /**
	         * Create the inline style object for a tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The inline style data for the tab.
	         */
	        Renderer.prototype.createTabStyle = function (data) {
	            return { zIndex: "" + data.zIndex };
	        };
	        /**
	         * Create the class name for the tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The full class name for the tab.
	         */
	        Renderer.prototype.createTabClass = function (data) {
	            var name = 'p-TabBar-tab';
	            if (data.title.className) {
	                name += " " + data.title.className;
	            }
	            if (data.title.closable) {
	                name += ' p-mod-closable';
	            }
	            if (data.current) {
	                name += ' p-mod-current';
	            }
	            return name;
	        };
	        /**
	         * Create the dataset for a tab.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The dataset for the tab.
	         */
	        Renderer.prototype.createTabDataset = function (data) {
	            return data.title.dataset;
	        };
	        /**
	         * Create the class name for the tab icon.
	         *
	         * @param data - The data to use for the tab.
	         *
	         * @returns The full class name for the tab icon.
	         */
	        Renderer.prototype.createIconClass = function (data) {
	            var name = 'p-TabBar-tabIcon';
	            var extra = data.title.iconClass;
	            return extra ? name + " " + extra : name;
	        };
	        return Renderer;
	    }());
	    TabBar.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    TabBar.defaultRenderer = new Renderer();
	})(TabBar = exports.TabBar || (exports.TabBar = {}));
	exports.TabBar = TabBar;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The start drag distance threshold.
	     */
	    Private.DRAG_THRESHOLD = 5;
	    /**
	     * The detach distance threshold.
	     */
	    Private.DETACH_THRESHOLD = 20;
	    /**
	     * Create the DOM node for a tab bar.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = 'p-TabBar-content';
	        node.appendChild(content);
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Coerce a title or options into a real title.
	     */
	    function asTitle(value) {
	        return value instanceof title_1.Title ? value : new title_1.Title(value);
	    }
	    Private.asTitle = asTitle;
	    /**
	     * Parse the transition duration for a tab node.
	     */
	    function parseTransitionDuration(tab) {
	        var style = window.getComputedStyle(tab);
	        return 1000 * (parseFloat(style.transitionDuration) || 0);
	    }
	    Private.parseTransitionDuration = parseTransitionDuration;
	    /**
	     * Get a snapshot of the current tab layout values.
	     */
	    function snapTabLayout(tabs, orientation) {
	        var layout = new Array(tabs.length);
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            var node = tabs[i];
	            var style = window.getComputedStyle(node);
	            if (orientation === 'horizontal') {
	                layout[i] = {
	                    pos: node.offsetLeft,
	                    size: node.offsetWidth,
	                    margin: parseFloat(style.marginLeft) || 0
	                };
	            }
	            else {
	                layout[i] = {
	                    pos: node.offsetTop,
	                    size: node.offsetHeight,
	                    margin: parseFloat(style.marginTop) || 0
	                };
	            }
	        }
	        return layout;
	    }
	    Private.snapTabLayout = snapTabLayout;
	    /**
	     * Test if the event exceeds the drag threshold.
	     */
	    function dragExceeded(data, event) {
	        var dx = Math.abs(event.clientX - data.pressX);
	        var dy = Math.abs(event.clientY - data.pressY);
	        return dx >= Private.DRAG_THRESHOLD || dy >= Private.DRAG_THRESHOLD;
	    }
	    Private.dragExceeded = dragExceeded;
	    /**
	     * Test if the event exceeds the drag detach threshold.
	     */
	    function detachExceeded(data, event) {
	        var rect = data.contentRect;
	        return ((event.clientX < rect.left - Private.DETACH_THRESHOLD) ||
	            (event.clientX >= rect.right + Private.DETACH_THRESHOLD) ||
	            (event.clientY < rect.top - Private.DETACH_THRESHOLD) ||
	            (event.clientY >= rect.bottom + Private.DETACH_THRESHOLD));
	    }
	    Private.detachExceeded = detachExceeded;
	    /**
	     * Update the relative tab positions and computed target index.
	     */
	    function layoutTabs(tabs, data, event, orientation) {
	        // Compute the orientation-sensitive values.
	        var pressPos;
	        var localPos;
	        var clientPos;
	        var clientSize;
	        if (orientation === 'horizontal') {
	            pressPos = data.pressX;
	            localPos = event.clientX - data.contentRect.left;
	            clientPos = event.clientX;
	            clientSize = data.contentRect.width;
	        }
	        else {
	            pressPos = data.pressY;
	            localPos = event.clientY - data.contentRect.top;
	            clientPos = event.clientY;
	            clientSize = data.contentRect.height;
	        }
	        // Compute the target data.
	        var targetIndex = data.index;
	        var targetPos = localPos - data.tabPressPos;
	        var targetEnd = targetPos + data.tabSize;
	        // Update the relative tab positions.
	        for (var i = 0, n = tabs.length; i < n; ++i) {
	            var pxPos = void 0;
	            var layout = data.tabLayout[i];
	            var threshold = layout.pos + (layout.size >> 1);
	            if (i < data.index && targetPos < threshold) {
	                pxPos = data.tabSize + data.tabLayout[i + 1].margin + "px";
	                targetIndex = Math.min(targetIndex, i);
	            }
	            else if (i > data.index && targetEnd > threshold) {
	                pxPos = -data.tabSize - layout.margin + "px";
	                targetIndex = Math.max(targetIndex, i);
	            }
	            else if (i === data.index) {
	                var ideal = clientPos - pressPos;
	                var limit = clientSize - (data.tabPos + data.tabSize);
	                pxPos = Math.max(-data.tabPos, Math.min(ideal, limit)) + "px";
	            }
	            else {
	                pxPos = '';
	            }
	            if (orientation === 'horizontal') {
	                tabs[i].style.left = pxPos;
	            }
	            else {
	                tabs[i].style.top = pxPos;
	            }
	        }
	        // Update the computed target index.
	        data.targetIndex = targetIndex;
	    }
	    Private.layoutTabs = layoutTabs;
	    /**
	     * Position the drag tab at its final resting relative position.
	     */
	    function finalizeTabPosition(data, orientation) {
	        // Compute the orientation-sensitive client size.
	        var clientSize;
	        if (orientation === 'horizontal') {
	            clientSize = data.contentRect.width;
	        }
	        else {
	            clientSize = data.contentRect.height;
	        }
	        // Compute the ideal final tab position.
	        var ideal;
	        if (data.targetIndex === data.index) {
	            ideal = 0;
	        }
	        else if (data.targetIndex > data.index) {
	            var tgt = data.tabLayout[data.targetIndex];
	            ideal = tgt.pos + tgt.size - data.tabSize - data.tabPos;
	        }
	        else {
	            var tgt = data.tabLayout[data.targetIndex];
	            ideal = tgt.pos - data.tabPos;
	        }
	        // Compute the tab position limit.
	        var limit = clientSize - (data.tabPos + data.tabSize);
	        var final = Math.max(-data.tabPos, Math.min(ideal, limit));
	        // Set the final orientation-sensitive position.
	        if (orientation === 'horizontal') {
	            data.tab.style.left = final + "px";
	        }
	        else {
	            data.tab.style.top = final + "px";
	        }
	    }
	    Private.finalizeTabPosition = finalizeTabPosition;
	    /**
	     * Reset the relative positions of the given tabs.
	     */
	    function resetTabPositions(tabs, orientation) {
	        algorithm_1.each(tabs, function (tab) {
	            if (orientation === 'horizontal') {
	                tab.style.left = '';
	            }
	            else {
	                tab.style.top = '';
	            }
	        });
	    }
	    Private.resetTabPositions = resetTabPositions;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/tabbar.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/focustracker.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/focustracker.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	/**
	 * A class which tracks focus among a set of widgets.
	 *
	 * This class is useful when code needs to keep track of the most
	 * recently focused widget(s) among a set of related widgets.
	 */
	var FocusTracker = (function () {
	    /**
	     * Construct a new focus tracker.
	     */
	    function FocusTracker() {
	        this._counter = 0;
	        this._widgets = [];
	        this._activeWidget = null;
	        this._currentWidget = null;
	        this._numbers = new Map();
	        this._nodes = new Map();
	        this._activeChanged = new signaling_1.Signal(this);
	        this._currentChanged = new signaling_1.Signal(this);
	    }
	    /**
	     * Dispose of the resources held by the tracker.
	     */
	    FocusTracker.prototype.dispose = function () {
	        var _this = this;
	        // Do nothing if the tracker is already disposed.
	        if (this._counter < 0) {
	            return;
	        }
	        // Mark the tracker as disposed.
	        this._counter = -1;
	        // Clear the connections for the tracker.
	        signaling_1.Signal.clearData(this);
	        // Remove all event listeners.
	        algorithm_1.each(this._widgets, function (w) {
	            w.node.removeEventListener('focus', _this, true);
	            w.node.removeEventListener('blur', _this, true);
	        });
	        // Clear the internal data structures.
	        this._activeWidget = null;
	        this._currentWidget = null;
	        this._nodes.clear();
	        this._numbers.clear();
	        this._widgets.length = 0;
	    };
	    Object.defineProperty(FocusTracker.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current widget has changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "activeChanged", {
	        /**
	         * A signal emitted when the active widget has changed.
	         */
	        get: function () {
	            return this._activeChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "isDisposed", {
	        /**
	         * A flag indicating whether the tracker is disposed.
	         */
	        get: function () {
	            return this._counter < 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "currentWidget", {
	        /**
	         * The current widget in the tracker.
	         *
	         * #### Notes
	         * The current widget is the widget among the tracked widgets which
	         * has the *descendant node* which has most recently been focused.
	         *
	         * The current widget will not be updated if the node loses focus. It
	         * will only be updated when a different tracked widget gains focus.
	         *
	         * If the current widget is removed from the tracker, the previous
	         * current widget will be restored.
	         *
	         * This behavior is intended to follow a user's conceptual model of
	         * a semantically "current" widget, where the "last thing of type X"
	         * to be interacted with is the "current instance of X", regardless
	         * of whether that instance still has focus.
	         */
	        get: function () {
	            return this._currentWidget;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "activeWidget", {
	        /**
	         * The active widget in the tracker.
	         *
	         * #### Notes
	         * The active widget is the widget among the tracked widgets which
	         * has the *descendant node* which is currently focused.
	         */
	        get: function () {
	            return this._activeWidget;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(FocusTracker.prototype, "widgets", {
	        /**
	         * A read only array of the widgets being tracked.
	         */
	        get: function () {
	            return this._widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the focus number for a particular widget in the tracker.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The focus number for the given widget, or `-1` if the
	     *   widget has not had focus since being added to the tracker, or
	     *   is not contained by the tracker.
	     *
	     * #### Notes
	     * The focus number indicates the relative order in which the widgets
	     * have gained focus. A widget with a larger number has gained focus
	     * more recently than a widget with a smaller number.
	     *
	     * The `currentWidget` will always have the largest focus number.
	     *
	     * All widgets start with a focus number of `-1`, which indicates that
	     * the widget has not been focused since being added to the tracker.
	     */
	    FocusTracker.prototype.focusNumber = function (widget) {
	        var n = this._numbers.get(widget);
	        return n === undefined ? -1 : n;
	    };
	    /**
	     * Test whether the focus tracker contains a given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns `true` if the widget is tracked, `false` otherwise.
	     */
	    FocusTracker.prototype.has = function (widget) {
	        return this._numbers.has(widget);
	    };
	    /**
	     * Add a widget to the focus tracker.
	     *
	     * @param widget - The widget of interest.
	     *
	     * #### Notes
	     * A widget will be automatically removed from the tracker if it
	     * is disposed after being added.
	     *
	     * If the widget is already tracked, this is a no-op.
	     */
	    FocusTracker.prototype.add = function (widget) {
	        // Do nothing if the widget is already tracked.
	        if (this._numbers.has(widget)) {
	            return;
	        }
	        // Test whether the widget has focus.
	        var focused = widget.node.contains(document.activeElement);
	        // Set up the initial focus number.
	        var n = focused ? this._counter++ : -1;
	        // Add the widget to the internal data structures.
	        this._widgets.push(widget);
	        this._numbers.set(widget, n);
	        this._nodes.set(widget.node, widget);
	        // Set up the event listeners. The capturing phase must be used
	        // since the 'focus' and 'blur' events don't bubble and Firefox
	        // doesn't support the 'focusin' or 'focusout' events.
	        widget.node.addEventListener('focus', this, true);
	        widget.node.addEventListener('blur', this, true);
	        // Connect the disposed signal handler.
	        widget.disposed.connect(this._onWidgetDisposed, this);
	        // Set the current and active widgets if needed.
	        if (focused) {
	            this._setWidgets(widget, widget);
	        }
	    };
	    /**
	     * Remove a widget from the focus tracker.
	     *
	     * #### Notes
	     * If the widget is the `currentWidget`, the previous current widget
	     * will become the new `currentWidget`.
	     *
	     * A widget will be automatically removed from the tracker if it
	     * is disposed after being added.
	     *
	     * If the widget is not tracked, this is a no-op.
	     */
	    FocusTracker.prototype.remove = function (widget) {
	        var _this = this;
	        // Bail early if the widget is not tracked.
	        if (!this._numbers.has(widget)) {
	            return;
	        }
	        // Disconnect the disposed signal handler.
	        widget.disposed.disconnect(this._onWidgetDisposed, this);
	        // Remove the event listeners.
	        widget.node.removeEventListener('focus', this, true);
	        widget.node.removeEventListener('blur', this, true);
	        // Remove the widget from the internal data structures.
	        algorithm_1.ArrayExt.removeFirstOf(this._widgets, widget);
	        this._nodes.delete(widget.node);
	        this._numbers.delete(widget);
	        // Bail early if the widget is not the current widget.
	        if (this._currentWidget !== widget) {
	            return;
	        }
	        // Filter the widgets for those which have had focus.
	        var valid = algorithm_1.filter(this._widgets, function (w) { return _this._numbers.get(w) !== -1; });
	        // Get the valid widget with the max focus number.
	        var previous = algorithm_1.max(valid, function (first, second) {
	            var a = _this._numbers.get(first);
	            var b = _this._numbers.get(second);
	            return a - b;
	        }) || null;
	        // Set the current and active widgets.
	        this._setWidgets(previous, null);
	    };
	    /**
	     * Handle the DOM events for the focus tracker.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the tracked nodes. It should
	     * not be called directly by user code.
	     */
	    FocusTracker.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'focus':
	                this._evtFocus(event);
	                break;
	            case 'blur':
	                this._evtBlur(event);
	                break;
	        }
	    };
	    /**
	     * Set the current and active widgets for the tracker.
	     */
	    FocusTracker.prototype._setWidgets = function (current, active) {
	        // Swap the current widget.
	        var oldCurrent = this._currentWidget;
	        this._currentWidget = current;
	        // Swap the active widget.
	        var oldActive = this._activeWidget;
	        this._activeWidget = active;
	        // Emit the `currentChanged` signal if needed.
	        if (oldCurrent !== current) {
	            this._currentChanged.emit({ oldValue: oldCurrent, newValue: current });
	        }
	        // Emit the `activeChanged` signal if needed.
	        if (oldActive !== active) {
	            this._activeChanged.emit({ oldValue: oldActive, newValue: active });
	        }
	    };
	    /**
	     * Handle the `'focus'` event for a tracked widget.
	     */
	    FocusTracker.prototype._evtFocus = function (event) {
	        // Find the widget which gained focus, which is known to exist.
	        var widget = this._nodes.get(event.currentTarget);
	        // Update the focus number if necessary.
	        if (widget !== this._currentWidget) {
	            this._numbers.set(widget, this._counter++);
	        }
	        // Set the current and active widgets.
	        this._setWidgets(widget, widget);
	    };
	    /**
	     * Handle the `'blur'` event for a tracked widget.
	     */
	    FocusTracker.prototype._evtBlur = function (event) {
	        // Find the widget which lost focus, which is known to exist.
	        var widget = this._nodes.get(event.currentTarget);
	        // Get the node which being focused after this blur.
	        var focusTarget = event.relatedTarget;
	        // If no other node is being focused, clear the active widget.
	        if (!focusTarget) {
	            this._setWidgets(this._currentWidget, null);
	            return;
	        }
	        // Bail if the focus widget is not changing.
	        if (widget.node.contains(focusTarget)) {
	            return;
	        }
	        // If no tracked widget is being focused, clear the active widget.
	        if (!algorithm_1.find(this._widgets, function (w) { return w.node.contains(focusTarget); })) {
	            this._setWidgets(this._currentWidget, null);
	            return;
	        }
	    };
	    /**
	     * Handle the `disposed` signal for a tracked widget.
	     */
	    FocusTracker.prototype._onWidgetDisposed = function (sender) {
	        this.remove(sender);
	    };
	    return FocusTracker;
	}());
	exports.FocusTracker = FocusTracker;
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/focustracker.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/gridlayout.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/gridlayout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.1.1/lib/index.js');
	var boxengine_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/boxengine.js');
	var layout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/layout.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A layout which arranges its widgets in a grid.
	 */
	var GridLayout = (function (_super) {
	    __extends(GridLayout, _super);
	    /**
	     * Construct a new grid layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function GridLayout(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, options) || this;
	        _this._dirty = false;
	        _this._rowSpacing = 4;
	        _this._columnSpacing = 4;
	        _this._items = [];
	        _this._rowStarts = [];
	        _this._columnStarts = [];
	        _this._rowSizers = [new boxengine_1.BoxSizer()];
	        _this._columnSizers = [new boxengine_1.BoxSizer()];
	        _this._box = null;
	        if (options.rowCount !== undefined) {
	            Private.reallocSizers(_this._rowSizers, options.rowCount);
	        }
	        if (options.columnCount !== undefined) {
	            Private.reallocSizers(_this._columnSizers, options.columnCount);
	        }
	        if (options.rowSpacing !== undefined) {
	            _this._rowSpacing = Private.clampValue(options.rowSpacing);
	        }
	        if (options.columnSpacing !== undefined) {
	            _this._columnSpacing = Private.clampValue(options.columnSpacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    GridLayout.prototype.dispose = function () {
	        // Dispose of the widgets and layout items.
	        algorithm_1.each(this._items, function (item) {
	            var widget = item.widget;
	            item.dispose();
	            widget.dispose();
	        });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        this._rowStarts.length = 0;
	        this._rowSizers.length = 0;
	        this._columnStarts.length = 0;
	        this._columnSizers.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(GridLayout.prototype, "rowCount", {
	        /**
	         * Get the number of rows in the layout.
	         */
	        get: function () {
	            return this._rowSizers.length;
	        },
	        /**
	         * Set the number of rows in the layout.
	         *
	         * #### Notes
	         * The minimum row count is `1`.
	         */
	        set: function (value) {
	            // Do nothing if the row count does not change.
	            if (value === this.rowCount) {
	                return;
	            }
	            // Reallocate the row sizers.
	            Private.reallocSizers(this._rowSizers, value);
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(GridLayout.prototype, "columnCount", {
	        /**
	         * Get the number of columns in the layout.
	         */
	        get: function () {
	            return this._columnSizers.length;
	        },
	        /**
	         * Set the number of columns in the layout.
	         *
	         * #### Notes
	         * The minimum column count is `1`.
	         */
	        set: function (value) {
	            // Do nothing if the column count does not change.
	            if (value === this.columnCount) {
	                return;
	            }
	            // Reallocate the column sizers.
	            Private.reallocSizers(this._columnSizers, value);
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(GridLayout.prototype, "rowSpacing", {
	        /**
	         * Get the row spacing for the layout.
	         */
	        get: function () {
	            return this._rowSpacing;
	        },
	        /**
	         * Set the row spacing for the layout.
	         */
	        set: function (value) {
	            // Clamp the spacing to the allowed range.
	            value = Private.clampValue(value);
	            // Bail if the spacing does not change
	            if (this._rowSpacing === value) {
	                return;
	            }
	            // Update the internal spacing.
	            this._rowSpacing = value;
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(GridLayout.prototype, "columnSpacing", {
	        /**
	         * Get the column spacing for the layout.
	         */
	        get: function () {
	            return this._columnSpacing;
	        },
	        /**
	         * Set the col spacing for the layout.
	         */
	        set: function (value) {
	            // Clamp the spacing to the allowed range.
	            value = Private.clampValue(value);
	            // Bail if the spacing does not change
	            if (this._columnSpacing === value) {
	                return;
	            }
	            // Update the internal spacing.
	            this._columnSpacing = value;
	            // Schedule a fit of the parent.
	            if (this.parent) {
	                this.parent.fit();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the stretch factor for a specific row.
	     *
	     * @param index - The row index of interest.
	     *
	     * @returns The stretch factor for the row.
	     *
	     * #### Notes
	     * This returns `-1` if the index is out of range.
	     */
	    GridLayout.prototype.rowStretch = function (index) {
	        var sizer = this._rowSizers[index];
	        return sizer ? sizer.stretch : -1;
	    };
	    /**
	     * Set the stretch factor for a specific row.
	     *
	     * @param index - The row index of interest.
	     *
	     * @param value - The stretch factor for the row.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    GridLayout.prototype.setRowStretch = function (index, value) {
	        // Look up the row sizer.
	        var sizer = this._rowSizers[index];
	        // Bail if the index is out of range.
	        if (!sizer) {
	            return;
	        }
	        // Clamp the value to the allowed range.
	        value = Private.clampValue(value);
	        // Bail if the stretch does not change.
	        if (sizer.stretch === value) {
	            return;
	        }
	        // Update the sizer stretch.
	        sizer.stretch = value;
	        // Schedule an update of the parent.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Get the stretch factor for a specific column.
	     *
	     * @param index - The column index of interest.
	     *
	     * @returns The stretch factor for the column.
	     *
	     * #### Notes
	     * This returns `-1` if the index is out of range.
	     */
	    GridLayout.prototype.columnStretch = function (index) {
	        var sizer = this._columnSizers[index];
	        return sizer ? sizer.stretch : -1;
	    };
	    /**
	     * Set the stretch factor for a specific column.
	     *
	     * @param index - The column index of interest.
	     *
	     * @param value - The stretch factor for the column.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    GridLayout.prototype.setColumnStretch = function (index, value) {
	        // Look up the column sizer.
	        var sizer = this._columnSizers[index];
	        // Bail if the index is out of range.
	        if (!sizer) {
	            return;
	        }
	        // Clamp the value to the allowed range.
	        value = Private.clampValue(value);
	        // Bail if the stretch does not change.
	        if (sizer.stretch === value) {
	            return;
	        }
	        // Update the sizer stretch.
	        sizer.stretch = value;
	        // Schedule an update of the parent.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Create an iterator over the widgets in the layout.
	     *
	     * @returns A new iterator over the widgets in the layout.
	     */
	    GridLayout.prototype.iter = function () {
	        return algorithm_1.map(this._items, function (item) { return item.widget; });
	    };
	    /**
	     * Add a widget to the grid layout.
	     *
	     * @param widget - The widget to add to the layout.
	     *
	     * #### Notes
	     * If the widget is already contained in the layout, this is no-op.
	     */
	    GridLayout.prototype.addWidget = function (widget) {
	        // Look up the index for the widget.
	        var i = algorithm_1.ArrayExt.findFirstIndex(this._items, function (it) { return it.widget === widget; });
	        // Bail if the widget is already in the layout.
	        if (i !== -1) {
	            return;
	        }
	        // Add the widget to the layout.
	        this._items.push(new layout_1.LayoutItem(widget));
	        // Attach the widget to the parent.
	        if (this.parent) {
	            this.attachWidget(widget);
	        }
	    };
	    /**
	     * Remove a widget from the grid layout.
	     *
	     * @param widget - The widget to remove from the layout.
	     *
	     * #### Notes
	     * A widget is automatically removed from the layout when its `parent`
	     * is set to `null`. This method should only be invoked directly when
	     * removing a widget from a layout which has yet to be installed on a
	     * parent widget.
	     *
	     * This method does *not* modify the widget's `parent`.
	     */
	    GridLayout.prototype.removeWidget = function (widget) {
	        // Look up the index for the widget.
	        var i = algorithm_1.ArrayExt.findFirstIndex(this._items, function (it) { return it.widget === widget; });
	        // Bail if the widget is not in the layout.
	        if (i !== -1) {
	            return;
	        }
	        // Remove the widget from the layout.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, i);
	        // Detach the widget from the parent.
	        if (this.parent) {
	            this.detachWidget(widget);
	        }
	        // Dispose the layout item.
	        item.dispose();
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    GridLayout.prototype.init = function () {
	        var _this = this;
	        _super.prototype.init.call(this);
	        algorithm_1.each(this, function (widget) { _this.attachWidget(widget); });
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param widget - The widget to attach to the parent.
	     */
	    GridLayout.prototype.attachWidget = function (widget) {
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param widget - The widget to detach from the parent.
	     */
	    GridLayout.prototype.detachWidget = function (widget) {
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    GridLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    GridLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    GridLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    GridLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    GridLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    GridLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    GridLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    GridLayout.prototype._fit = function () {
	        // Reset the min sizes of the sizers.
	        for (var i = 0, n = this.rowCount; i < n; ++i) {
	            this._rowSizers[i].minSize = 0;
	        }
	        for (var i = 0, n = this.columnCount; i < n; ++i) {
	            this._columnSizers[i].minSize = 0;
	        }
	        // Filter for the visible layout items.
	        var items = this._items.filter(function (it) { return !it.isHidden; });
	        // Fit the layout items.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            items[i].fit();
	        }
	        // Get the max row and column index.
	        var maxRow = this.rowCount - 1;
	        var maxCol = this.columnCount - 1;
	        // Sort the items by row span.
	        items.sort(Private.rowSpanCmp);
	        // Update the min sizes of the row sizers.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = items[i];
	            // Get the row bounds for the item.
	            var config = GridLayout.getCellConfig(item.widget);
	            var r1 = Math.min(config.row, maxRow);
	            var r2 = Math.min(config.row + config.rowSpan - 1, maxRow);
	            // Distribute the minimum height to the sizers as needed.
	            Private.distributeMin(this._rowSizers, r1, r2, item.minHeight);
	        }
	        // Sort the items by column span.
	        items.sort(Private.columnSpanCmp);
	        // Update the min sizes of the column sizers.
	        for (var i = 0, n = items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = items[i];
	            // Get the column bounds for the item.
	            var config = GridLayout.getCellConfig(item.widget);
	            var c1 = Math.min(config.column, maxCol);
	            var c2 = Math.min(config.column + config.columnSpan - 1, maxCol);
	            // Distribute the minimum width to the sizers as needed.
	            Private.distributeMin(this._columnSizers, c1, c2, item.minWidth);
	        }
	        // If no size constraint is needed, just update the parent.
	        if (this.fitPolicy === 'set-no-constraint') {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	            return;
	        }
	        // Set up the computed min size.
	        var minH = maxRow * this._rowSpacing;
	        var minW = maxCol * this._columnSpacing;
	        // Add the sizer minimums to the computed min size.
	        for (var i = 0, n = this.rowCount; i < n; ++i) {
	            minH += this._rowSizers[i].minSize;
	        }
	        for (var i = 0, n = this.columnCount; i < n; ++i) {
	            minW += this._columnSizers[i].minSize;
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    GridLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the layout area adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Get the max row and column index.
	        var maxRow = this.rowCount - 1;
	        var maxCol = this.columnCount - 1;
	        // Compute the total fixed row and column space.
	        var fixedRowSpace = maxRow * this._rowSpacing;
	        var fixedColSpace = maxCol * this._columnSpacing;
	        // Distribute the available space to the box sizers.
	        boxengine_1.BoxEngine.calc(this._rowSizers, Math.max(0, height - fixedRowSpace));
	        boxengine_1.BoxEngine.calc(this._columnSizers, Math.max(0, width - fixedColSpace));
	        // Update the row start positions.
	        for (var i = 0, pos = top, n = this.rowCount; i < n; ++i) {
	            this._rowStarts[i] = pos;
	            pos += this._rowSizers[i].size + this._rowSpacing;
	        }
	        // Update the column start positions.
	        for (var i = 0, pos = left, n = this.columnCount; i < n; ++i) {
	            this._columnStarts[i] = pos;
	            pos += this._columnSizers[i].size + this._columnSpacing;
	        }
	        // Update the geometry of the layout items.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Fetch the cell bounds for the widget.
	            var config = GridLayout.getCellConfig(item.widget);
	            var r1 = Math.min(config.row, maxRow);
	            var c1 = Math.min(config.column, maxCol);
	            var r2 = Math.min(config.row + config.rowSpan - 1, maxRow);
	            var c2 = Math.min(config.column + config.columnSpan - 1, maxCol);
	            // Compute the cell geometry.
	            var x = this._columnStarts[c1];
	            var y = this._rowStarts[r1];
	            var w = this._columnStarts[c2] + this._columnSizers[c2].size - x;
	            var h = this._rowStarts[r2] + this._rowSizers[r2].size - y;
	            // Update the geometry of the layout item.
	            item.update(x, y, w, h);
	        }
	    };
	    return GridLayout;
	}(layout_1.Layout));
	exports.GridLayout = GridLayout;
	/**
	 * The namespace for the `GridLayout` class statics.
	 */
	(function (GridLayout) {
	    /**
	     * Get the cell config for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The cell config for the widget.
	     */
	    function getCellConfig(widget) {
	        return Private.cellConfigProperty.get(widget);
	    }
	    GridLayout.getCellConfig = getCellConfig;
	    /**
	     * Set the cell config for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the cell config.
	     */
	    function setCellConfig(widget, value) {
	        Private.cellConfigProperty.set(widget, Private.normalizeConfig(value));
	    }
	    GridLayout.setCellConfig = setCellConfig;
	})(GridLayout = exports.GridLayout || (exports.GridLayout = {}));
	exports.GridLayout = GridLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The property descriptor for the widget cell config.
	     */
	    Private.cellConfigProperty = new properties_1.AttachedProperty({
	        name: 'cellConfig',
	        create: function () { return ({ row: 0, column: 0, rowSpan: 1, columnSpan: 1 }); },
	        changed: onChildCellConfigChanged
	    });
	    /**
	     * Normalize a partial cell config object.
	     */
	    function normalizeConfig(config) {
	        var row = Math.max(0, Math.floor(config.row || 0));
	        var column = Math.max(0, Math.floor(config.column || 0));
	        var rowSpan = Math.max(1, Math.floor(config.rowSpan || 0));
	        var columnSpan = Math.max(1, Math.floor(config.columnSpan || 0));
	        return { row: row, column: column, rowSpan: rowSpan, columnSpan: columnSpan };
	    }
	    Private.normalizeConfig = normalizeConfig;
	    /**
	     * Clamp a value to an integer >= 0.
	     */
	    function clampValue(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampValue = clampValue;
	    /**
	     * A sort comparison function for row spans.
	     */
	    function rowSpanCmp(a, b) {
	        var c1 = Private.cellConfigProperty.get(a.widget);
	        var c2 = Private.cellConfigProperty.get(b.widget);
	        return c1.rowSpan - c2.rowSpan;
	    }
	    Private.rowSpanCmp = rowSpanCmp;
	    /**
	     * A sort comparison function for column spans.
	     */
	    function columnSpanCmp(a, b) {
	        var c1 = Private.cellConfigProperty.get(a.widget);
	        var c2 = Private.cellConfigProperty.get(b.widget);
	        return c1.columnSpan - c2.columnSpan;
	    }
	    Private.columnSpanCmp = columnSpanCmp;
	    /**
	     * Reallocate the box sizers for the given grid dimensions.
	     */
	    function reallocSizers(sizers, count) {
	        // Coerce the count to the valid range.
	        count = Math.max(1, Math.floor(count));
	        // Add the missing sizers.
	        while (sizers.length < count) {
	            sizers.push(new boxengine_1.BoxSizer());
	        }
	        // Remove the extra sizers.
	        if (sizers.length < count) {
	            sizers.length = count;
	        }
	    }
	    Private.reallocSizers = reallocSizers;
	    /**
	     * Distribute a min size constraint across a range of sizers.
	     */
	    function distributeMin(sizers, i1, i2, minSize) {
	        // Sanity check the indices.
	        if (i2 < i1) {
	            return;
	        }
	        // Handle the simple case of no cell span.
	        if (i1 === i2) {
	            var sizer = sizers[i1];
	            sizer.minSize = Math.max(sizer.minSize, minSize);
	            return;
	        }
	        // Compute the total current min size of the span.
	        var totalMin = 0;
	        for (var i = i1; i <= i2; ++i) {
	            totalMin += sizers[i].minSize;
	        }
	        // Do nothing if the total is greater than the required.
	        if (totalMin >= minSize) {
	            return;
	        }
	        // Compute the portion of the space to allocate to each sizer.
	        var portion = (minSize - totalMin) / (i2 - i1 + 1);
	        // Add the portion to each sizer.
	        for (var i = i1; i <= i2; ++i) {
	            sizers[i].minSize += portion;
	        }
	    }
	    Private.distributeMin = distributeMin;
	    /**
	     * The change handler for the child cell config property.
	     */
	    function onChildCellConfigChanged(child) {
	        if (child.parent && child.parent.layout instanceof GridLayout) {
	            child.parent.fit();
	        }
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/gridlayout.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/menubar.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/menubar.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var keyboard_1 = __jupyter_require__('@phosphor/keyboard@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var virtualdom_1 = __jupyter_require__('@phosphor/virtualdom@^1.1.1/lib/index.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A widget which displays menus as a canonical menu bar.
	 */
	var MenuBar = (function (_super) {
	    __extends(MenuBar, _super);
	    /**
	     * Construct a new menu bar.
	     *
	     * @param options - The options for initializing the menu bar.
	     */
	    function MenuBar(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this._activeIndex = -1;
	        _this._menus = [];
	        _this._childMenu = null;
	        _this.addClass('p-MenuBar');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        _this.renderer = options.renderer || MenuBar.defaultRenderer;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    MenuBar.prototype.dispose = function () {
	        this._closeChildMenu();
	        this._menus.length = 0;
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(MenuBar.prototype, "childMenu", {
	        /**
	         * The child menu of the menu bar.
	         *
	         * #### Notes
	         * This will be `null` if the menu bar does not have an open menu.
	         */
	        get: function () {
	            return this._childMenu;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "contentNode", {
	        /**
	         * Get the menu bar content node.
	         *
	         * #### Notes
	         * This is the node which holds the menu title nodes.
	         *
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-MenuBar-content')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "activeMenu", {
	        /**
	         * Get the currently active menu.
	         */
	        get: function () {
	            return this._menus[this._activeIndex] || null;
	        },
	        /**
	         * Set the currently active menu.
	         *
	         * #### Notes
	         * If the menu does not exist, the menu will be set to `null`.
	         */
	        set: function (value) {
	            this.activeIndex = value ? this._menus.indexOf(value) : -1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "activeIndex", {
	        /**
	         * Get the index of the currently active menu.
	         *
	         * #### Notes
	         * This will be `-1` if no menu is active.
	         */
	        get: function () {
	            return this._activeIndex;
	        },
	        /**
	         * Set the index of the currently active menu.
	         *
	         * #### Notes
	         * If the menu cannot be activated, the index will be set to `-1`.
	         */
	        set: function (value) {
	            // Adjust the value for an out of range index.
	            if (value < 0 || value >= this._menus.length) {
	                value = -1;
	            }
	            // Bail early if the index will not change.
	            if (this._activeIndex === value) {
	                return;
	            }
	            // Update the active index.
	            this._activeIndex = value;
	            // Schedule an update of the items.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(MenuBar.prototype, "menus", {
	        /**
	         * A read-only array of the menus in the menu bar.
	         */
	        get: function () {
	            return this._menus;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Open the active menu and activate its first menu item.
	     *
	     * #### Notes
	     * If there is no active menu, this is a no-op.
	     */
	    MenuBar.prototype.openActiveMenu = function () {
	        // Bail early if there is no active item.
	        if (this._activeIndex === -1) {
	            return;
	        }
	        // Open the child menu.
	        this._openChildMenu();
	        // Activate the first item in the child menu.
	        if (this._childMenu) {
	            this._childMenu.activeIndex = -1;
	            this._childMenu.activateNextItem();
	        }
	    };
	    /**
	     * Add a menu to the end of the menu bar.
	     *
	     * @param menu - The menu to add to the menu bar.
	     *
	     * #### Notes
	     * If the menu is already added to the menu bar, it will be moved.
	     */
	    MenuBar.prototype.addMenu = function (menu) {
	        this.insertMenu(this._menus.length, menu);
	    };
	    /**
	     * Insert a menu into the menu bar at the specified index.
	     *
	     * @param index - The index at which to insert the menu.
	     *
	     * @param menu - The menu to insert into the menu bar.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the menus.
	     *
	     * If the menu is already added to the menu bar, it will be moved.
	     */
	    MenuBar.prototype.insertMenu = function (index, menu) {
	        // Close the child menu before making changes.
	        this._closeChildMenu();
	        // Look up the index of the menu.
	        var i = this._menus.indexOf(menu);
	        // Clamp the insert index to the array bounds.
	        var j = Math.max(0, Math.min(index, this._menus.length));
	        // If the menu is not in the array, insert it.
	        if (i === -1) {
	            // Insert the menu into the array.
	            algorithm_1.ArrayExt.insert(this._menus, j, menu);
	            // Add the styling class to the menu.
	            menu.addClass('p-MenuBar-menu');
	            // Connect to the menu signals.
	            menu.aboutToClose.connect(this._onMenuAboutToClose, this);
	            menu.menuRequested.connect(this._onMenuMenuRequested, this);
	            menu.title.changed.connect(this._onTitleChanged, this);
	            // Schedule an update of the items.
	            this.update();
	            // There is nothing more to do.
	            return;
	        }
	        // Otherwise, the menu exists in the array and should be moved.
	        // Adjust the index if the location is at the end of the array.
	        if (j === this._menus.length) {
	            j--;
	        }
	        // Bail if there is no effective move.
	        if (i === j) {
	            return;
	        }
	        // Move the menu to the new locations.
	        algorithm_1.ArrayExt.move(this._menus, i, j);
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Remove a menu from the menu bar.
	     *
	     * @param menu - The menu to remove from the menu bar.
	     *
	     * #### Notes
	     * This is a no-op if the menu is not in the menu bar.
	     */
	    MenuBar.prototype.removeMenu = function (menu) {
	        this.removeMenuAt(this._menus.indexOf(menu));
	    };
	    /**
	     * Remove the menu at a given index from the menu bar.
	     *
	     * @param index - The index of the menu to remove.
	     *
	     * #### Notes
	     * This is a no-op if the index is out of range.
	     */
	    MenuBar.prototype.removeMenuAt = function (index) {
	        // Close the child menu before making changes.
	        this._closeChildMenu();
	        // Remove the menu from the array.
	        var menu = algorithm_1.ArrayExt.removeAt(this._menus, index);
	        // Bail if the index is out of range.
	        if (!menu) {
	            return;
	        }
	        // Disconnect from the menu signals.
	        menu.aboutToClose.disconnect(this._onMenuAboutToClose, this);
	        menu.menuRequested.disconnect(this._onMenuMenuRequested, this);
	        menu.title.changed.disconnect(this._onTitleChanged, this);
	        // Remove the styling class from the menu.
	        menu.removeClass('p-MenuBar-menu');
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Remove all menus from the menu bar.
	     */
	    MenuBar.prototype.clearMenus = function () {
	        // Bail if there is nothing to remove.
	        if (this._menus.length === 0) {
	            return;
	        }
	        // Close the child menu before making changes.
	        this._closeChildMenu();
	        // Disconnect from the menu signals and remove the styling class.
	        for (var _i = 0, _a = this._menus; _i < _a.length; _i++) {
	            var menu = _a[_i];
	            menu.aboutToClose.disconnect(this._onMenuAboutToClose, this);
	            menu.menuRequested.disconnect(this._onMenuMenuRequested, this);
	            menu.title.changed.disconnect(this._onTitleChanged, this);
	            menu.removeClass('p-MenuBar-menu');
	        }
	        // Clear the menus array.
	        this._menus.length = 0;
	        // Schedule an update of the items.
	        this.update();
	    };
	    /**
	     * Handle the DOM events for the menu bar.
	     *
	     * @param event - The DOM event sent to the menu bar.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the menu bar's DOM nodes. It
	     * should not be called directly by user code.
	     */
	    MenuBar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseleave':
	                this._evtMouseLeave(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    MenuBar.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('keydown', this);
	        this.node.addEventListener('mousedown', this);
	        this.node.addEventListener('mousemove', this);
	        this.node.addEventListener('mouseleave', this);
	        this.node.addEventListener('contextmenu', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    MenuBar.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('keydown', this);
	        this.node.removeEventListener('mousedown', this);
	        this.node.removeEventListener('mousemove', this);
	        this.node.removeEventListener('mouseleave', this);
	        this.node.removeEventListener('contextmenu', this);
	        this._closeChildMenu();
	    };
	    /**
	     * A message handler invoked on an `'activate-request'` message.
	     */
	    MenuBar.prototype.onActivateRequest = function (msg) {
	        if (this.isAttached) {
	            this.node.focus();
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    MenuBar.prototype.onUpdateRequest = function (msg) {
	        var menus = this._menus;
	        var renderer = this.renderer;
	        var activeIndex = this._activeIndex;
	        var content = new Array(menus.length);
	        for (var i = 0, n = menus.length; i < n; ++i) {
	            var title = menus[i].title;
	            var active = i === activeIndex;
	            content[i] = renderer.renderItem({ title: title, active: active });
	        }
	        virtualdom_1.VirtualDOM.render(content, this.contentNode);
	    };
	    /**
	     * Handle the `'keydown'` event for the menu bar.
	     */
	    MenuBar.prototype._evtKeyDown = function (event) {
	        // A menu bar handles all keydown events.
	        event.preventDefault();
	        event.stopPropagation();
	        // Fetch the key code for the event.
	        var kc = event.keyCode;
	        // Enter, Up Arrow, Down Arrow
	        if (kc === 13 || kc === 38 || kc === 40) {
	            this.openActiveMenu();
	            return;
	        }
	        // Escape
	        if (kc === 27) {
	            this._closeChildMenu();
	            this.activeIndex = -1;
	            this.node.blur();
	            return;
	        }
	        // Left Arrow
	        if (kc === 37) {
	            var i = this._activeIndex;
	            var n = this._menus.length;
	            this.activeIndex = i === 0 ? n - 1 : i - 1;
	            return;
	        }
	        // Right Arrow
	        if (kc === 39) {
	            var i = this._activeIndex;
	            var n = this._menus.length;
	            this.activeIndex = i === n - 1 ? 0 : i + 1;
	            return;
	        }
	        // Get the pressed key character.
	        var key = keyboard_1.getKeyboardLayout().keyForKeydownEvent(event);
	        // Bail if the key is not valid.
	        if (!key) {
	            return;
	        }
	        // Search for the next best matching mnemonic item.
	        var start = this._activeIndex + 1;
	        var result = Private.findMnemonic(this._menus, key, start);
	        // Handle the requested mnemonic based on the search results.
	        // If exactly one mnemonic is matched, that menu is opened.
	        // Otherwise, the next mnemonic is activated if available,
	        // followed by the auto mnemonic if available.
	        if (result.index !== -1 && !result.multiple) {
	            this.activeIndex = result.index;
	            this.openActiveMenu();
	        }
	        else if (result.index !== -1) {
	            this.activeIndex = result.index;
	        }
	        else if (result.auto !== -1) {
	            this.activeIndex = result.auto;
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseDown = function (event) {
	        // Bail if the mouse press was not on the menu bar. This can occur
	        // when the document listener is installed for an active menu bar.
	        if (!domutils_1.ElementExt.hitTest(this.node, event.clientX, event.clientY)) {
	            return;
	        }
	        // Stop the propagation of the event. Immediate propagation is
	        // also stopped so that an open menu does not handle the event.
	        event.preventDefault();
	        event.stopPropagation();
	        event.stopImmediatePropagation();
	        // Check if the mouse is over one of the menu items.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return domutils_1.ElementExt.hitTest(node, event.clientX, event.clientY);
	        });
	        // If the press was not on an item, close the child menu.
	        if (index === -1) {
	            this._closeChildMenu();
	            return;
	        }
	        // If the press was not the left mouse button, do nothing further.
	        if (event.button !== 0) {
	            return;
	        }
	        // Otherwise, toggle the open state of the child menu.
	        if (this._childMenu) {
	            this._closeChildMenu();
	            this.activeIndex = index;
	        }
	        else {
	            this.activeIndex = index;
	            this._openChildMenu();
	        }
	    };
	    /**
	     * Handle the `'mousemove'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseMove = function (event) {
	        // Check if the mouse is over one of the menu items.
	        var index = algorithm_1.ArrayExt.findFirstIndex(this.contentNode.children, function (node) {
	            return domutils_1.ElementExt.hitTest(node, event.clientX, event.clientY);
	        });
	        // Bail early if the active index will not change.
	        if (index === this._activeIndex) {
	            return;
	        }
	        // Bail early if a child menu is open and the mouse is not over
	        // an item. This allows the child menu to be kept open when the
	        // mouse is over the empty part of the menu bar.
	        if (index === -1 && this._childMenu) {
	            return;
	        }
	        // Update the active index to the hovered item.
	        this.activeIndex = index;
	        // Open the new menu if a menu is already open.
	        if (this._childMenu) {
	            this._openChildMenu();
	        }
	    };
	    /**
	     * Handle the `'mouseleave'` event for the menu bar.
	     */
	    MenuBar.prototype._evtMouseLeave = function (event) {
	        // Reset the active index if there is no open menu.
	        if (!this._childMenu) {
	            this.activeIndex = -1;
	        }
	    };
	    /**
	     * Open the child menu at the active index immediately.
	     *
	     * If a different child menu is already open, it will be closed,
	     * even if there is no active menu.
	     */
	    MenuBar.prototype._openChildMenu = function () {
	        // If there is no active menu, close the current menu.
	        var newMenu = this.activeMenu;
	        if (!newMenu) {
	            this._closeChildMenu();
	            return;
	        }
	        // Bail if there is no effective menu change.
	        var oldMenu = this._childMenu;
	        if (oldMenu === newMenu) {
	            return;
	        }
	        // Swap the internal menu reference.
	        this._childMenu = newMenu;
	        // Close the current menu, or setup for the new menu.
	        if (oldMenu) {
	            oldMenu.close();
	        }
	        else {
	            this.addClass('p-mod-active');
	            document.addEventListener('mousedown', this, true);
	        }
	        // Ensure the menu bar is updated and look up the item node.
	        messaging_1.MessageLoop.sendMessage(this, widget_1.Widget.Msg.UpdateRequest);
	        var itemNode = this.contentNode.children[this._activeIndex];
	        // Get the positioning data for the new menu.
	        var _a = itemNode.getBoundingClientRect(), left = _a.left, bottom = _a.bottom;
	        // Open the new menu at the computed location.
	        newMenu.open(left, bottom, { forceX: true, forceY: true });
	    };
	    /**
	     * Close the child menu immediately.
	     *
	     * This is a no-op if a child menu is not open.
	     */
	    MenuBar.prototype._closeChildMenu = function () {
	        // Bail if no child menu is open.
	        if (!this._childMenu) {
	            return;
	        }
	        // Remove the active class from the menu bar.
	        this.removeClass('p-mod-active');
	        // Remove the document listeners.
	        document.removeEventListener('mousedown', this, true);
	        // Clear the internal menu reference.
	        var menu = this._childMenu;
	        this._childMenu = null;
	        // Close the menu.
	        menu.close();
	        // Reset the active index.
	        this.activeIndex = -1;
	    };
	    /**
	     * Handle the `aboutToClose` signal of a menu.
	     */
	    MenuBar.prototype._onMenuAboutToClose = function (sender) {
	        // Bail if the sender is not the child menu.
	        if (sender !== this._childMenu) {
	            return;
	        }
	        // Remove the active class from the menu bar.
	        this.removeClass('p-mod-active');
	        // Remove the document listeners.
	        document.removeEventListener('mousedown', this, true);
	        // Clear the internal menu reference.
	        this._childMenu = null;
	        // Reset the active index.
	        this.activeIndex = -1;
	    };
	    /**
	     * Handle the `menuRequested` signal of a child menu.
	     */
	    MenuBar.prototype._onMenuMenuRequested = function (sender, args) {
	        // Bail if the sender is not the child menu.
	        if (sender !== this._childMenu) {
	            return;
	        }
	        // Look up the active index and menu count.
	        var i = this._activeIndex;
	        var n = this._menus.length;
	        // Active the next requested index.
	        switch (args) {
	            case 'next':
	                this.activeIndex = i === n - 1 ? 0 : i + 1;
	                break;
	            case 'previous':
	                this.activeIndex = i === 0 ? n - 1 : i - 1;
	                break;
	        }
	        // Open the active menu.
	        this.openActiveMenu();
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    MenuBar.prototype._onTitleChanged = function () {
	        this.update();
	    };
	    return MenuBar;
	}(widget_1.Widget));
	exports.MenuBar = MenuBar;
	/**
	 * The namespace for the `MenuBar` class statics.
	 */
	(function (MenuBar) {
	    /**
	     * The default implementation of `IRenderer`.
	     *
	     * #### Notes
	     * Subclasses are free to reimplement rendering methods as needed.
	     */
	    var Renderer = (function () {
	        /**
	         * Construct a new renderer.
	         */
	        function Renderer() {
	        }
	        /**
	         * Render the virtual element for a menu bar item.
	         *
	         * @param data - The data to use for rendering the item.
	         *
	         * @returns A virtual element representing the item.
	         */
	        Renderer.prototype.renderItem = function (data) {
	            var className = this.createItemClass(data);
	            var dataset = this.createItemDataset(data);
	            return (virtualdom_1.h.li({ className: className, dataset: dataset }, this.renderIcon(data), this.renderLabel(data)));
	        };
	        /**
	         * Render the icon element for a menu bar item.
	         *
	         * @param data - The data to use for rendering the icon.
	         *
	         * @returns A virtual element representing the item icon.
	         */
	        Renderer.prototype.renderIcon = function (data) {
	            var className = this.createIconClass(data);
	            return virtualdom_1.h.div({ className: className }, data.title.iconLabel);
	        };
	        /**
	         * Render the label element for a menu item.
	         *
	         * @param data - The data to use for rendering the label.
	         *
	         * @returns A virtual element representing the item label.
	         */
	        Renderer.prototype.renderLabel = function (data) {
	            var content = this.formatLabel(data);
	            return virtualdom_1.h.div({ className: 'p-MenuBar-itemLabel' }, content);
	        };
	        /**
	         * Create the class name for the menu bar item.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the menu item.
	         */
	        Renderer.prototype.createItemClass = function (data) {
	            var name = 'p-MenuBar-item';
	            if (data.title.className) {
	                name += " " + data.title.className;
	            }
	            if (data.active) {
	                name += ' p-mod-active';
	            }
	            return name;
	        };
	        /**
	         * Create the dataset for a menu bar item.
	         *
	         * @param data - The data to use for the item.
	         *
	         * @returns The dataset for the menu bar item.
	         */
	        Renderer.prototype.createItemDataset = function (data) {
	            return data.title.dataset;
	        };
	        /**
	         * Create the class name for the menu bar item icon.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the item icon.
	         */
	        Renderer.prototype.createIconClass = function (data) {
	            var name = 'p-MenuBar-itemIcon';
	            var extra = data.title.iconClass;
	            return extra ? name + " " + extra : name;
	        };
	        /**
	         * Create the render content for the label node.
	         *
	         * @param data - The data to use for the label content.
	         *
	         * @returns The content to add to the label node.
	         */
	        Renderer.prototype.formatLabel = function (data) {
	            // Fetch the label text and mnemonic index.
	            var _a = data.title, label = _a.label, mnemonic = _a.mnemonic;
	            // If the index is out of range, do not modify the label.
	            if (mnemonic < 0 || mnemonic >= label.length) {
	                return label;
	            }
	            // Split the label into parts.
	            var prefix = label.slice(0, mnemonic);
	            var suffix = label.slice(mnemonic + 1);
	            var char = label[mnemonic];
	            // Wrap the mnemonic character in a span.
	            var span = virtualdom_1.h.span({ className: 'p-MenuBar-itemMnemonic' }, char);
	            // Return the content parts.
	            return [prefix, span, suffix];
	        };
	        return Renderer;
	    }());
	    MenuBar.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    MenuBar.defaultRenderer = new Renderer();
	})(MenuBar = exports.MenuBar || (exports.MenuBar = {}));
	exports.MenuBar = MenuBar;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the DOM node for a menu bar.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var content = document.createElement('ul');
	        content.className = 'p-MenuBar-content';
	        node.appendChild(content);
	        node.tabIndex = -1;
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Find the best matching mnemonic item.
	     *
	     * The search starts at the given index and wraps around.
	     */
	    function findMnemonic(menus, key, start) {
	        // Setup the result variables.
	        var index = -1;
	        var auto = -1;
	        var multiple = false;
	        // Normalize the key to upper case.
	        var upperKey = key.toUpperCase();
	        // Search the items from the given start index.
	        for (var i = 0, n = menus.length; i < n; ++i) {
	            // Compute the wrapped index.
	            var k = (i + start) % n;
	            // Look up the menu title.
	            var title = menus[k].title;
	            // Ignore titles with an empty label.
	            if (title.label.length === 0) {
	                continue;
	            }
	            // Look up the mnemonic index for the label.
	            var mn = title.mnemonic;
	            // Handle a valid mnemonic index.
	            if (mn >= 0 && mn < title.label.length) {
	                if (title.label[mn].toUpperCase() === upperKey) {
	                    if (index === -1) {
	                        index = k;
	                    }
	                    else {
	                        multiple = true;
	                    }
	                }
	                continue;
	            }
	            // Finally, handle the auto index if possible.
	            if (auto === -1 && title.label[0].toUpperCase() === upperKey) {
	                auto = k;
	            }
	        }
	        // Return the search results.
	        return { index: index, multiple: multiple, auto: auto };
	    }
	    Private.findMnemonic = findMnemonic;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/menubar.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/scrollbar.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/scrollbar.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var dragdrop_1 = __jupyter_require__('@phosphor/dragdrop@^1.1.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A widget which implements a canonical scroll bar.
	 */
	var ScrollBar = (function (_super) {
	    __extends(ScrollBar, _super);
	    /**
	     * Construct a new scroll bar.
	     *
	     * @param options - The options for initializing the scroll bar.
	     */
	    function ScrollBar(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        /**
	         * A timeout callback for repeating the mouse press.
	         */
	        _this._onRepeat = function () {
	            // Clear the repeat timer id.
	            _this._repeatTimer = -1;
	            // Bail if the mouse has been released.
	            if (!_this._pressData) {
	                return;
	            }
	            // Look up the part that was pressed.
	            var part = _this._pressData.part;
	            // Bail if the thumb was pressed.
	            if (part === 'thumb') {
	                return;
	            }
	            // Schedule the timer for another repeat.
	            _this._repeatTimer = setTimeout(_this._onRepeat, 20);
	            // Get the current mouse position.
	            var mouseX = _this._pressData.mouseX;
	            var mouseY = _this._pressData.mouseY;
	            // Handle a decrement button repeat.
	            if (part === 'decrement') {
	                // Bail if the mouse is not over the button.
	                if (!domutils_1.ElementExt.hitTest(_this.decrementNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Emit the step requested signal.
	                _this._stepRequested.emit('decrement');
	                // Finished.
	                return;
	            }
	            // Handle an increment button repeat.
	            if (part === 'increment') {
	                // Bail if the mouse is not over the button.
	                if (!domutils_1.ElementExt.hitTest(_this.incrementNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Emit the step requested signal.
	                _this._stepRequested.emit('increment');
	                // Finished.
	                return;
	            }
	            // Handle a track repeat.
	            if (part === 'track') {
	                // Bail if the mouse is not over the track.
	                if (!domutils_1.ElementExt.hitTest(_this.trackNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Fetch the thumb node.
	                var thumbNode = _this.thumbNode;
	                // Bail if the mouse is over the thumb.
	                if (domutils_1.ElementExt.hitTest(thumbNode, mouseX, mouseY)) {
	                    return;
	                }
	                // Fetch the client rect for the thumb.
	                var thumbRect = thumbNode.getBoundingClientRect();
	                // Determine the direction for the page request.
	                var dir = void 0;
	                if (_this._orientation === 'horizontal') {
	                    dir = mouseX < thumbRect.left ? 'decrement' : 'increment';
	                }
	                else {
	                    dir = mouseY < thumbRect.top ? 'decrement' : 'increment';
	                }
	                // Emit the page requested signal.
	                _this._pageRequested.emit(dir);
	                // Finished.
	                return;
	            }
	        };
	        _this._value = 0;
	        _this._page = 10;
	        _this._maximum = 100;
	        _this._repeatTimer = -1;
	        _this._pressData = null;
	        _this._thumbMoved = new signaling_1.Signal(_this);
	        _this._stepRequested = new signaling_1.Signal(_this);
	        _this._pageRequested = new signaling_1.Signal(_this);
	        _this.addClass('p-ScrollBar');
	        _this.setFlag(widget_1.Widget.Flag.DisallowLayout);
	        // Set the orientation.
	        _this._orientation = options.orientation || 'vertical';
	        _this.dataset['orientation'] = _this._orientation;
	        // Parse the rest of the options.
	        if (options.maximum !== undefined) {
	            _this._maximum = Math.max(0, options.maximum);
	        }
	        if (options.page !== undefined) {
	            _this._page = Math.max(0, options.page);
	        }
	        if (options.value !== undefined) {
	            _this._value = Math.max(0, Math.min(options.value, _this._maximum));
	        }
	        return _this;
	    }
	    Object.defineProperty(ScrollBar.prototype, "thumbMoved", {
	        /**
	         * A signal emitted when the user moves the scroll thumb.
	         *
	         * #### Notes
	         * The payload is the current value of the scroll bar.
	         */
	        get: function () {
	            return this._thumbMoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "stepRequested", {
	        /**
	         * A signal emitted when the user clicks a step button.
	         *
	         * #### Notes
	         * The payload is whether a decrease or increase is requested.
	         */
	        get: function () {
	            return this._stepRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "pageRequested", {
	        /**
	         * A signal emitted when the user clicks the scroll track.
	         *
	         * #### Notes
	         * The payload is whether a decrease or increase is requested.
	         */
	        get: function () {
	            return this._pageRequested;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "orientation", {
	        /**
	         * Get the orientation of the scroll bar.
	         */
	        get: function () {
	            return this._orientation;
	        },
	        /**
	         * Set the orientation of the scroll bar.
	         */
	        set: function (value) {
	            // Do nothing if the orientation does not change.
	            if (this._orientation === value) {
	                return;
	            }
	            // Release the mouse before making changes.
	            this._releaseMouse();
	            // Update the internal orientation.
	            this._orientation = value;
	            this.dataset['orientation'] = value;
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "value", {
	        /**
	         * Get the current value of the scroll bar.
	         */
	        get: function () {
	            return this._value;
	        },
	        /**
	         * Set the current value of the scroll bar.
	         *
	         * #### Notes
	         * The value will be clamped to the range `[0, maximum]`.
	         */
	        set: function (value) {
	            // Clamp the value to the allowable range.
	            value = Math.max(0, Math.min(value, this._maximum));
	            // Do nothing if the value does not change.
	            if (this._value === value) {
	                return;
	            }
	            // Update the internal value.
	            this._value = value;
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "page", {
	        /**
	         * Get the page size of the scroll bar.
	         *
	         * #### Notes
	         * The page size is the amount of visible content in the scrolled
	         * region, expressed in data units. It determines the size of the
	         * scroll bar thumb.
	         */
	        get: function () {
	            return this._page;
	        },
	        /**
	         * Set the page size of the scroll bar.
	         *
	         * #### Notes
	         * The page size will be clamped to the range `[0, Infinity]`.
	         */
	        set: function (value) {
	            // Clamp the page size to the allowable range.
	            value = Math.max(0, value);
	            // Do nothing if the value does not change.
	            if (this._page === value) {
	                return;
	            }
	            // Update the internal page size.
	            this._page = value;
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "maximum", {
	        /**
	         * Get the maximum value of the scroll bar.
	         */
	        get: function () {
	            return this._maximum;
	        },
	        /**
	         * Set the maximum value of the scroll bar.
	         *
	         * #### Notes
	         * The max size will be clamped to the range `[0, Infinity]`.
	         */
	        set: function (value) {
	            // Clamp the value to the allowable range.
	            value = Math.max(0, value);
	            // Do nothing if the value does not change.
	            if (this._maximum === value) {
	                return;
	            }
	            // Update the internal values.
	            this._maximum = value;
	            // Clamp the current value to the new range.
	            this._value = Math.min(this._value, value);
	            // Schedule an update the scroll bar.
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "decrementNode", {
	        /**
	         * The scroll bar decrement button node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-button')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "incrementNode", {
	        /**
	         * The scroll bar increment button node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-button')[1];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "trackNode", {
	        /**
	         * The scroll bar track node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-track')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ScrollBar.prototype, "thumbNode", {
	        /**
	         * The scroll bar thumb node.
	         *
	         * #### Notes
	         * Modifying this node directly can lead to undefined behavior.
	         */
	        get: function () {
	            return this.node.getElementsByClassName('p-ScrollBar-thumb')[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Handle the DOM events for the scroll bar.
	     *
	     * @param event - The DOM event sent to the scroll bar.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the scroll bar's DOM node.
	     *
	     * This should not be called directly by user code.
	     */
	    ScrollBar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A method invoked on a 'before-attach' message.
	     */
	    ScrollBar.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	        this.update();
	    };
	    /**
	     * A method invoked on an 'after-detach' message.
	     */
	    ScrollBar.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A method invoked on an 'update-request' message.
	     */
	    ScrollBar.prototype.onUpdateRequest = function (msg) {
	        // Convert the value and page into percentages.
	        var value = this._value * 100 / this._maximum;
	        var page = this._page * 100 / (this._page + this._maximum);
	        // Clamp the value and page to the relevant range.
	        value = Math.max(0, Math.min(value, 100));
	        page = Math.max(0, Math.min(page, 100));
	        // Fetch the thumb style.
	        var thumbStyle = this.thumbNode.style;
	        // Update the thumb style for the current orientation.
	        if (this._orientation === 'horizontal') {
	            thumbStyle.top = '';
	            thumbStyle.height = '';
	            thumbStyle.left = value + "%";
	            thumbStyle.width = page + "%";
	            thumbStyle.transform = "translate(" + -value + "%, 0%)";
	        }
	        else {
	            thumbStyle.left = '';
	            thumbStyle.width = '';
	            thumbStyle.top = value + "%";
	            thumbStyle.height = page + "%";
	            thumbStyle.transform = "translate(0%, " + -value + "%)";
	        }
	    };
	    /**
	     * Handle the `'keydown'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtKeyDown = function (event) {
	        // Stop all input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Ignore anything except the `Escape` key.
	        if (event.keyCode !== 27) {
	            return;
	        }
	        // Fetch the previous scroll value.
	        var value = this._pressData ? this._pressData.value : -1;
	        // Release the mouse.
	        this._releaseMouse();
	        // Restore the old scroll value if possible.
	        if (value !== -1) {
	            this._moveThumb(value);
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtMouseDown = function (event) {
	        // Do nothing if it's not a left mouse press.
	        if (event.button !== 0) {
	            return;
	        }
	        // Do nothing if the mouse is already captured.
	        if (this._pressData) {
	            return;
	        }
	        // Find the pressed scroll bar part.
	        var part = Private.findPart(this, event.target);
	        // Do nothing if the part is not of interest.
	        if (!part) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Override the mouse cursor.
	        var override = dragdrop_1.Drag.overrideCursor('default');
	        // Set up the press data.
	        this._pressData = {
	            part: part, override: override,
	            delta: -1, value: -1,
	            mouseX: event.clientX,
	            mouseY: event.clientY
	        };
	        // Add the extra event listeners.
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('contextmenu', this, true);
	        // Handle a thumb press.
	        if (part === 'thumb') {
	            // Fetch the thumb node.
	            var thumbNode = this.thumbNode;
	            // Fetch the client rect for the thumb.
	            var thumbRect = thumbNode.getBoundingClientRect();
	            // Update the press data delta for the current orientation.
	            if (this._orientation === 'horizontal') {
	                this._pressData.delta = event.clientX - thumbRect.left;
	            }
	            else {
	                this._pressData.delta = event.clientY - thumbRect.top;
	            }
	            // Add the active class to the thumb node.
	            thumbNode.classList.add('p-mod-active');
	            // Store the current value in the press data.
	            this._pressData.value = this._value;
	            // Finished.
	            return;
	        }
	        // Handle a track press.
	        if (part === 'track') {
	            // Fetch the client rect for the thumb.
	            var thumbRect = this.thumbNode.getBoundingClientRect();
	            // Determine the direction for the page request.
	            var dir = void 0;
	            if (this._orientation === 'horizontal') {
	                dir = event.clientX < thumbRect.left ? 'decrement' : 'increment';
	            }
	            else {
	                dir = event.clientY < thumbRect.top ? 'decrement' : 'increment';
	            }
	            // Start the repeat timer.
	            this._repeatTimer = setTimeout(this._onRepeat, 350);
	            // Emit the page requested signal.
	            this._pageRequested.emit(dir);
	            // Finished.
	            return;
	        }
	        // Handle a decrement button press.
	        if (part === 'decrement') {
	            // Add the active class to the decrement node.
	            this.decrementNode.classList.add('p-mod-active');
	            // Start the repeat timer.
	            this._repeatTimer = setTimeout(this._onRepeat, 350);
	            // Emit the step requested signal.
	            this._stepRequested.emit('decrement');
	            // Finished.
	            return;
	        }
	        // Handle an increment button press.
	        if (part === 'increment') {
	            // Add the active class to the increment node.
	            this.incrementNode.classList.add('p-mod-active');
	            // Start the repeat timer.
	            this._repeatTimer = setTimeout(this._onRepeat, 350);
	            // Emit the step requested signal.
	            this._stepRequested.emit('increment');
	            // Finished.
	            return;
	        }
	    };
	    /**
	     * Handle the `'mousemove'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtMouseMove = function (event) {
	        // Do nothing if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Update the mouse position.
	        this._pressData.mouseX = event.clientX;
	        this._pressData.mouseY = event.clientY;
	        // Bail if the thumb is not being dragged.
	        if (this._pressData.part !== 'thumb') {
	            return;
	        }
	        // Get the client rect for the thumb and track.
	        var thumbRect = this.thumbNode.getBoundingClientRect();
	        var trackRect = this.trackNode.getBoundingClientRect();
	        // Fetch the scroll geometry based on the orientation.
	        var trackPos;
	        var trackSpan;
	        if (this._orientation === 'horizontal') {
	            trackPos = event.clientX - trackRect.left - this._pressData.delta;
	            trackSpan = trackRect.width - thumbRect.width;
	        }
	        else {
	            trackPos = event.clientY - trackRect.top - this._pressData.delta;
	            trackSpan = trackRect.height - thumbRect.height;
	        }
	        // Compute the desired value from the scroll geometry.
	        var value = trackSpan === 0 ? 0 : trackPos * this._maximum / trackSpan;
	        // Move the thumb to the computed value.
	        this._moveThumb(value);
	    };
	    /**
	     * Handle the `'mouseup'` event for the scroll bar.
	     */
	    ScrollBar.prototype._evtMouseUp = function (event) {
	        // Do nothing if it's not a left mouse release.
	        if (event.button !== 0) {
	            return;
	        }
	        // Stop the event propagation.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse.
	        this._releaseMouse();
	    };
	    /**
	     * Release the mouse and restore the node states.
	     */
	    ScrollBar.prototype._releaseMouse = function () {
	        // Bail if there is no press data.
	        if (!this._pressData) {
	            return;
	        }
	        // Clear the repeat timer.
	        clearTimeout(this._repeatTimer);
	        this._repeatTimer = -1;
	        // Clear the press data.
	        this._pressData.override.dispose();
	        this._pressData = null;
	        // Remove the extra event listeners.
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	        // Remove the active classes from the nodes.
	        this.thumbNode.classList.remove('p-mod-active');
	        this.decrementNode.classList.remove('p-mod-active');
	        this.incrementNode.classList.remove('p-mod-active');
	    };
	    /**
	     * Move the thumb to the specified position.
	     */
	    ScrollBar.prototype._moveThumb = function (value) {
	        // Clamp the value to the allowed range.
	        value = Math.max(0, Math.min(value, this._maximum));
	        // Bail if the value does not change.
	        if (this._value === value) {
	            return;
	        }
	        // Update the internal value.
	        this._value = value;
	        // Schedule an update of the scroll bar.
	        this.update();
	        // Emit the thumb moved signal.
	        this._thumbMoved.emit(value);
	    };
	    return ScrollBar;
	}(widget_1.Widget));
	exports.ScrollBar = ScrollBar;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the DOM node for a scroll bar.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var decrement = document.createElement('div');
	        var increment = document.createElement('div');
	        var track = document.createElement('div');
	        var thumb = document.createElement('div');
	        decrement.className = 'p-ScrollBar-button';
	        increment.className = 'p-ScrollBar-button';
	        decrement.dataset['action'] = 'decrement';
	        increment.dataset['action'] = 'increment';
	        track.className = 'p-ScrollBar-track';
	        thumb.className = 'p-ScrollBar-thumb';
	        track.appendChild(thumb);
	        node.appendChild(decrement);
	        node.appendChild(track);
	        node.appendChild(increment);
	        return node;
	    }
	    Private.createNode = createNode;
	    /**
	     * Find the scroll bar part which contains the given target.
	     */
	    function findPart(scrollBar, target) {
	        // Test the thumb.
	        if (scrollBar.thumbNode.contains(target)) {
	            return 'thumb';
	        }
	        // Test the track.
	        if (scrollBar.trackNode.contains(target)) {
	            return 'track';
	        }
	        // Test the decrement button.
	        if (scrollBar.decrementNode.contains(target)) {
	            return 'decrement';
	        }
	        // Test the increment button.
	        if (scrollBar.incrementNode.contains(target)) {
	            return 'increment';
	        }
	        // Indicate no match.
	        return null;
	    }
	    Private.findPart = findPart;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/scrollbar.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/splitlayout.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/splitlayout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.1.1/lib/index.js');
	var boxengine_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/boxengine.js');
	var layout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/layout.js');
	var panellayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/panellayout.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A layout which arranges its widgets into resizable sections.
	 */
	var SplitLayout = (function (_super) {
	    __extends(SplitLayout, _super);
	    /**
	     * Construct a new split layout.
	     *
	     * @param options - The options for initializing the layout.
	     */
	    function SplitLayout(options) {
	        var _this = _super.call(this) || this;
	        _this._fixed = 0;
	        _this._spacing = 4;
	        _this._dirty = false;
	        _this._hasNormedSizes = false;
	        _this._sizers = [];
	        _this._items = [];
	        _this._handles = [];
	        _this._box = null;
	        _this._alignment = 'start';
	        _this._orientation = 'horizontal';
	        _this.renderer = options.renderer;
	        if (options.orientation !== undefined) {
	            _this._orientation = options.orientation;
	        }
	        if (options.alignment !== undefined) {
	            _this._alignment = options.alignment;
	        }
	        if (options.spacing !== undefined) {
	            _this._spacing = Private.clampSpacing(options.spacing);
	        }
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    SplitLayout.prototype.dispose = function () {
	        // Dispose of the layout items.
	        algorithm_1.each(this._items, function (item) { item.dispose(); });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        this._sizers.length = 0;
	        this._handles.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(SplitLayout.prototype, "orientation", {
	        /**
	         * Get the layout orientation for the split layout.
	         */
	        get: function () {
	            return this._orientation;
	        },
	        /**
	         * Set the layout orientation for the split layout.
	         */
	        set: function (value) {
	            if (this._orientation === value) {
	                return;
	            }
	            this._orientation = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['orientation'] = value;
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitLayout.prototype, "alignment", {
	        /**
	         * Get the content alignment for the split layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand  to fill the
	         * entire split layout.
	         */
	        get: function () {
	            return this._alignment;
	        },
	        /**
	         * Set the content alignment for the split layout.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand  to fill the
	         * entire split layout.
	         */
	        set: function (value) {
	            if (this._alignment === value) {
	                return;
	            }
	            this._alignment = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.dataset['alignment'] = value;
	            this.parent.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitLayout.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the split layout.
	         */
	        get: function () {
	            return this._spacing;
	        },
	        /**
	         * Set the inter-element spacing for the split layout.
	         */
	        set: function (value) {
	            value = Private.clampSpacing(value);
	            if (this._spacing === value) {
	                return;
	            }
	            this._spacing = value;
	            if (!this.parent) {
	                return;
	            }
	            this.parent.fit();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitLayout.prototype, "handles", {
	        /**
	         * A read-only array of the split handles in the layout.
	         */
	        get: function () {
	            return this._handles;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the relative sizes of the widgets in the layout.
	     *
	     * @returns A new array of the relative sizes of the widgets.
	     *
	     * #### Notes
	     * The returned sizes reflect the sizes of the widgets normalized
	     * relative to their siblings.
	     *
	     * This method **does not** measure the DOM nodes.
	     */
	    SplitLayout.prototype.relativeSizes = function () {
	        return Private.normalize(this._sizers.map(function (sizer) { return sizer.size; }));
	    };
	    /**
	     * Set the relative sizes for the widgets in the layout.
	     *
	     * @param sizes - The relative sizes for the widgets in the panel.
	     *
	     * #### Notes
	     * Extra values are ignored, too few will yield an undefined layout.
	     *
	     * The actual geometry of the DOM nodes is updated asynchronously.
	     */
	    SplitLayout.prototype.setRelativeSizes = function (sizes) {
	        // Copy the sizes and pad with zeros as needed.
	        var n = this._sizers.length;
	        var temp = sizes.slice(0, n);
	        while (temp.length < n) {
	            temp.push(0);
	        }
	        // Normalize the padded sizes.
	        var normed = Private.normalize(temp);
	        // Apply the normalized sizes to the sizers.
	        for (var i = 0; i < n; ++i) {
	            var sizer = this._sizers[i];
	            sizer.sizeHint = normed[i];
	            sizer.size = normed[i];
	        }
	        // Set the flag indicating the sizes are normalized.
	        this._hasNormedSizes = true;
	        // Trigger an update of the parent widget.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Move the offset position of a split handle.
	     *
	     * @param index - The index of the handle of the interest.
	     *
	     * @param position - The desired offset position of the handle.
	     *
	     * #### Notes
	     * The position is relative to the offset parent.
	     *
	     * This will move the handle as close as possible to the desired
	     * position. The sibling widgets will be adjusted as necessary.
	     */
	    SplitLayout.prototype.moveHandle = function (index, position) {
	        // Bail if the index is invalid or the handle is hidden.
	        var handle = this._handles[index];
	        if (!handle || handle.classList.contains('p-mod-hidden')) {
	            return;
	        }
	        // Compute the desired delta movement for the handle.
	        var delta;
	        if (this._orientation === 'horizontal') {
	            delta = position - handle.offsetLeft;
	        }
	        else {
	            delta = position - handle.offsetTop;
	        }
	        // Bail if there is no handle movement.
	        if (delta === 0) {
	            return;
	        }
	        // Prevent widget resizing unless needed.
	        for (var _i = 0, _a = this._sizers; _i < _a.length; _i++) {
	            var sizer = _a[_i];
	            if (sizer.size > 0) {
	                sizer.sizeHint = sizer.size;
	            }
	        }
	        // Adjust the sizers to reflect the handle movement.
	        boxengine_1.BoxEngine.adjust(this._sizers, index, delta);
	        // Update the layout of the widgets.
	        if (this.parent) {
	            this.parent.update();
	        }
	    };
	    /**
	     * Perform layout initialization which requires the parent widget.
	     */
	    SplitLayout.prototype.init = function () {
	        this.parent.dataset['orientation'] = this.orientation;
	        this.parent.dataset['alignment'] = this.alignment;
	        _super.prototype.init.call(this);
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.attachWidget = function (index, widget) {
	        // Create the item, handle, and sizer for the new widget.
	        var item = new layout_1.LayoutItem(widget);
	        var handle = Private.createHandle(this.renderer);
	        var average = Private.averageSize(this._sizers);
	        var sizer = Private.createSizer(average);
	        // Insert the item, handle, and sizer into the internal arrays.
	        algorithm_1.ArrayExt.insert(this._items, index, item);
	        algorithm_1.ArrayExt.insert(this._sizers, index, sizer);
	        algorithm_1.ArrayExt.insert(this._handles, index, handle);
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget and handle nodes to the parent.
	        this.parent.node.appendChild(widget.node);
	        this.parent.node.appendChild(handle);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Move the item, sizer, and handle for the widget.
	        algorithm_1.ArrayExt.move(this._items, fromIndex, toIndex);
	        algorithm_1.ArrayExt.move(this._sizers, fromIndex, toIndex);
	        algorithm_1.ArrayExt.move(this._handles, fromIndex, toIndex);
	        // Post a fit request to the parent to show/hide last handle.
	        this.parent.fit();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    SplitLayout.prototype.detachWidget = function (index, widget) {
	        // Remove the item, handle, and sizer for the widget.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        var handle = algorithm_1.ArrayExt.removeAt(this._handles, index);
	        algorithm_1.ArrayExt.removeAt(this._sizers, index);
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget and handle nodes from the parent.
	        this.parent.node.removeChild(widget.node);
	        this.parent.node.removeChild(handle);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Dispose of the layout item.
	        item.dispose();
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    SplitLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    SplitLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    SplitLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    SplitLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    SplitLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    SplitLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    SplitLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    SplitLayout.prototype._fit = function () {
	        // Update the handles and track the visible widget count.
	        var nVisible = 0;
	        var lastHandleIndex = -1;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            if (this._items[i].isHidden) {
	                this._handles[i].classList.add('p-mod-hidden');
	            }
	            else {
	                this._handles[i].classList.remove('p-mod-hidden');
	                lastHandleIndex = i;
	                nVisible++;
	            }
	        }
	        // Hide the handle for the last visible widget.
	        if (lastHandleIndex !== -1) {
	            this._handles[lastHandleIndex].classList.add('p-mod-hidden');
	        }
	        // Update the fixed space for the visible items.
	        this._fixed = this._spacing * Math.max(0, nVisible - 1);
	        // Setup the computed minimum size.
	        var horz = this._orientation === 'horizontal';
	        var minW = horz ? this._fixed : 0;
	        var minH = horz ? 0 : this._fixed;
	        // Update the sizers and computed size limits.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item and corresponding box sizer.
	            var item = this._items[i];
	            var sizer = this._sizers[i];
	            // Prevent resizing unless necessary.
	            if (sizer.size > 0) {
	                sizer.sizeHint = sizer.size;
	            }
	            // If the item is hidden, it should consume zero size.
	            if (item.isHidden) {
	                sizer.minSize = 0;
	                sizer.maxSize = 0;
	                continue;
	            }
	            // Update the size limits for the item.
	            item.fit();
	            // Update the stretch factor.
	            sizer.stretch = SplitLayout.getStretch(item.widget);
	            // Update the sizer limits and computed min size.
	            if (horz) {
	                sizer.minSize = item.minWidth;
	                sizer.maxSize = item.maxWidth;
	                minW += item.minWidth;
	                minH = Math.max(minH, item.minHeight);
	            }
	            else {
	                sizer.minSize = item.minHeight;
	                sizer.maxSize = item.maxHeight;
	                minH += item.minHeight;
	                minW = Math.max(minW, item.minWidth);
	            }
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    SplitLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Bail early if there are no visible items to layout.
	        if (nVisible === 0) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the actual layout bounds adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Compute the adjusted layout space.
	        var space;
	        var horz = this._orientation === 'horizontal';
	        if (horz) {
	            space = Math.max(0, width - this._fixed);
	        }
	        else {
	            space = Math.max(0, height - this._fixed);
	        }
	        // Scale the size hints if they are normalized.
	        if (this._hasNormedSizes) {
	            for (var _i = 0, _a = this._sizers; _i < _a.length; _i++) {
	                var sizer = _a[_i];
	                sizer.sizeHint *= space;
	            }
	            this._hasNormedSizes = false;
	        }
	        // Distribute the layout space to the box sizers.
	        var delta = boxengine_1.BoxEngine.calc(this._sizers, space);
	        // Set up the variables for justification and alignment offset.
	        var extra = 0;
	        var offset = 0;
	        // Account for alignment if there is extra layout space.
	        if (delta > 0) {
	            switch (this._alignment) {
	                case 'start':
	                    break;
	                case 'center':
	                    extra = 0;
	                    offset = delta / 2;
	                    break;
	                case 'end':
	                    extra = 0;
	                    offset = delta;
	                    break;
	                case 'justify':
	                    extra = delta / nVisible;
	                    offset = 0;
	                    break;
	                default:
	                    throw 'unreachable';
	            }
	        }
	        // Layout the items using the computed box sizes.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Fetch the computed size for the widget.
	            var size = this._sizers[i].size;
	            // Fetch the style for the handle.
	            var handleStyle = this._handles[i].style;
	            // Update the widget and handle, and advance the relevant edge.
	            if (horz) {
	                item.update(left + offset, top, size + extra, height);
	                left += size + extra;
	                handleStyle.top = top + "px";
	                handleStyle.left = left + offset + "px";
	                handleStyle.width = this._spacing + "px";
	                handleStyle.height = height + "px";
	                left += this._spacing;
	            }
	            else {
	                item.update(left, top + offset, width, size + extra);
	                top += size + extra;
	                handleStyle.top = top + offset + "px";
	                handleStyle.left = left + "px";
	                handleStyle.width = width + "px";
	                handleStyle.height = this._spacing + "px";
	                top += this._spacing;
	            }
	        }
	    };
	    return SplitLayout;
	}(panellayout_1.PanelLayout));
	exports.SplitLayout = SplitLayout;
	/**
	 * The namespace for the `SplitLayout` class statics.
	 */
	(function (SplitLayout) {
	    /**
	     * Get the split layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The split layout stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return Private.stretchProperty.get(widget);
	    }
	    SplitLayout.getStretch = getStretch;
	    /**
	     * Set the split layout stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        Private.stretchProperty.set(widget, value);
	    }
	    SplitLayout.setStretch = setStretch;
	})(SplitLayout = exports.SplitLayout || (exports.SplitLayout = {}));
	exports.SplitLayout = SplitLayout;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The property descriptor for a widget stretch factor.
	     */
	    Private.stretchProperty = new properties_1.AttachedProperty({
	        name: 'stretch',
	        create: function () { return 0; },
	        coerce: function (owner, value) { return Math.max(0, Math.floor(value)); },
	        changed: onChildSizingChanged
	    });
	    /**
	     * Create a new box sizer with the given size hint.
	     */
	    function createSizer(size) {
	        var sizer = new boxengine_1.BoxSizer();
	        sizer.sizeHint = Math.floor(size);
	        return sizer;
	    }
	    Private.createSizer = createSizer;
	    /**
	     * Create a new split handle node using the given renderer.
	     */
	    function createHandle(renderer) {
	        var handle = renderer.createHandle();
	        handle.style.position = 'absolute';
	        return handle;
	    }
	    Private.createHandle = createHandle;
	    /**
	     * Clamp a spacing value to an integer >= 0.
	     */
	    function clampSpacing(value) {
	        return Math.max(0, Math.floor(value));
	    }
	    Private.clampSpacing = clampSpacing;
	    /**
	     * Compute the average size of an array of box sizers.
	     */
	    function averageSize(sizers) {
	        return sizers.reduce(function (v, s) { return v + s.size; }, 0) / sizers.length || 0;
	    }
	    Private.averageSize = averageSize;
	    /**
	     * Normalize an array of values.
	     */
	    function normalize(values) {
	        var n = values.length;
	        if (n === 0) {
	            return [];
	        }
	        var sum = values.reduce(function (a, b) { return a + Math.abs(b); }, 0);
	        return sum === 0 ? values.map(function (v) { return 1 / n; }) : values.map(function (v) { return v / sum; });
	    }
	    Private.normalize = normalize;
	    /**
	     * The change handler for the attached sizing properties.
	     */
	    function onChildSizingChanged(child) {
	        if (child.parent && child.parent.layout instanceof SplitLayout) {
	            child.parent.fit();
	        }
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/splitlayout.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/splitpanel.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/splitpanel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var dragdrop_1 = __jupyter_require__('@phosphor/dragdrop@^1.1.1/lib/index.js');
	var panel_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/panel.js');
	var splitlayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/splitlayout.js');
	/**
	 * A panel which arranges its widgets into resizable sections.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[SplitLayout]].
	 */
	var SplitPanel = (function (_super) {
	    __extends(SplitPanel, _super);
	    /**
	     * Construct a new split panel.
	     *
	     * @param options - The options for initializing the split panel.
	     */
	    function SplitPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { layout: Private.createLayout(options) }) || this;
	        _this._pressData = null;
	        _this.addClass('p-SplitPanel');
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the panel.
	     */
	    SplitPanel.prototype.dispose = function () {
	        this._releaseMouse();
	        _super.prototype.dispose.call(this);
	    };
	    Object.defineProperty(SplitPanel.prototype, "orientation", {
	        /**
	         * Get the layout orientation for the split panel.
	         */
	        get: function () {
	            return this.layout.orientation;
	        },
	        /**
	         * Set the layout orientation for the split panel.
	         */
	        set: function (value) {
	            this.layout.orientation = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "alignment", {
	        /**
	         * Get the content alignment for the split panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire split panel.
	         */
	        get: function () {
	            return this.layout.alignment;
	        },
	        /**
	         * Set the content alignment for the split panel.
	         *
	         * #### Notes
	         * This is the alignment of the widgets in the layout direction.
	         *
	         * The alignment has no effect if the widgets can expand to fill the
	         * entire split panel.
	         */
	        set: function (value) {
	            this.layout.alignment = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "spacing", {
	        /**
	         * Get the inter-element spacing for the split panel.
	         */
	        get: function () {
	            return this.layout.spacing;
	        },
	        /**
	         * Set the inter-element spacing for the split panel.
	         */
	        set: function (value) {
	            this.layout.spacing = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "renderer", {
	        /**
	         * The renderer used by the split panel.
	         */
	        get: function () {
	            return this.layout.renderer;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SplitPanel.prototype, "handles", {
	        /**
	         * A read-only array of the split handles in the panel.
	         */
	        get: function () {
	            return this.layout.handles;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the relative sizes of the widgets in the panel.
	     *
	     * @returns A new array of the relative sizes of the widgets.
	     *
	     * #### Notes
	     * The returned sizes reflect the sizes of the widgets normalized
	     * relative to their siblings.
	     *
	     * This method **does not** measure the DOM nodes.
	     */
	    SplitPanel.prototype.relativeSizes = function () {
	        return this.layout.relativeSizes();
	    };
	    /**
	     * Set the relative sizes for the widgets in the panel.
	     *
	     * @param sizes - The relative sizes for the widgets in the panel.
	     *
	     * #### Notes
	     * Extra values are ignored, too few will yield an undefined layout.
	     *
	     * The actual geometry of the DOM nodes is updated asynchronously.
	     */
	    SplitPanel.prototype.setRelativeSizes = function (sizes) {
	        this.layout.setRelativeSizes(sizes);
	    };
	    /**
	     * Handle the DOM events for the split panel.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    SplitPanel.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'mousedown':
	                this._evtMouseDown(event);
	                break;
	            case 'mousemove':
	                this._evtMouseMove(event);
	                break;
	            case 'mouseup':
	                this._evtMouseUp(event);
	                break;
	            case 'keydown':
	                this._evtKeyDown(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	        }
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    SplitPanel.prototype.onBeforeAttach = function (msg) {
	        this.node.addEventListener('mousedown', this);
	    };
	    /**
	     * A message handler invoked on an `'after-detach'` message.
	     */
	    SplitPanel.prototype.onAfterDetach = function (msg) {
	        this.node.removeEventListener('mousedown', this);
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    SplitPanel.prototype.onChildAdded = function (msg) {
	        msg.child.addClass('p-SplitPanel-child');
	        this._releaseMouse();
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    SplitPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass('p-SplitPanel-child');
	        this._releaseMouse();
	    };
	    /**
	     * Handle the `'keydown'` event for the split panel.
	     */
	    SplitPanel.prototype._evtKeyDown = function (event) {
	        // Stop input events during drag.
	        event.preventDefault();
	        event.stopPropagation();
	        // Release the mouse if `Escape` is pressed.
	        if (event.keyCode === 27) {
	            this._releaseMouse();
	        }
	    };
	    /**
	     * Handle the `'mousedown'` event for the split panel.
	     */
	    SplitPanel.prototype._evtMouseDown = function (event) {
	        // Do nothing if the left mouse button is not pressed.
	        if (event.button !== 0) {
	            return;
	        }
	        // Find the handle which contains the mouse target, if any.
	        var layout = this.layout;
	        var index = algorithm_1.ArrayExt.findFirstIndex(layout.handles, function (handle) {
	            return handle.contains(event.target);
	        });
	        // Bail early if the mouse press was not on a handle.
	        if (index === -1) {
	            return;
	        }
	        // Stop the event when a split handle is pressed.
	        event.preventDefault();
	        event.stopPropagation();
	        // Add the extra document listeners.
	        document.addEventListener('mouseup', this, true);
	        document.addEventListener('mousemove', this, true);
	        document.addEventListener('keydown', this, true);
	        document.addEventListener('contextmenu', this, true);
	        // Compute the offset delta for the handle press.
	        var delta;
	        var handle = layout.handles[index];
	        var rect = handle.getBoundingClientRect();
	        if (layout.orientation === 'horizontal') {
	            delta = event.clientX - rect.left;
	        }
	        else {
	            delta = event.clientY - rect.top;
	        }
	        // Override the cursor and store the press data.
	        var style = window.getComputedStyle(handle);
	        var override = dragdrop_1.Drag.overrideCursor(style.cursor);
	        this._pressData = { index: index, delta: delta, override: override };
	    };
	    /**
	     * Handle the `'mousemove'` event for the split panel.
	     */
	    SplitPanel.prototype._evtMouseMove = function (event) {
	        // Stop the event when dragging a split handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Compute the desired offset position for the handle.
	        var pos;
	        var layout = this.layout;
	        var rect = this.node.getBoundingClientRect();
	        if (layout.orientation === 'horizontal') {
	            pos = event.clientX - rect.left - this._pressData.delta;
	        }
	        else {
	            pos = event.clientY - rect.top - this._pressData.delta;
	        }
	        // Move the handle as close to the desired position as possible.
	        layout.moveHandle(this._pressData.index, pos);
	    };
	    /**
	     * Handle the `'mouseup'` event for the split panel.
	     */
	    SplitPanel.prototype._evtMouseUp = function (event) {
	        // Do nothing if the left mouse button is not released.
	        if (event.button !== 0) {
	            return;
	        }
	        // Stop the event when releasing a handle.
	        event.preventDefault();
	        event.stopPropagation();
	        // Finalize the mouse release.
	        this._releaseMouse();
	    };
	    /**
	     * Release the mouse grab for the split panel.
	     */
	    SplitPanel.prototype._releaseMouse = function () {
	        // Bail early if no drag is in progress.
	        if (!this._pressData) {
	            return;
	        }
	        // Clear the override cursor.
	        this._pressData.override.dispose();
	        this._pressData = null;
	        // Remove the extra document listeners.
	        document.removeEventListener('mouseup', this, true);
	        document.removeEventListener('mousemove', this, true);
	        document.removeEventListener('keydown', this, true);
	        document.removeEventListener('contextmenu', this, true);
	    };
	    return SplitPanel;
	}(panel_1.Panel));
	exports.SplitPanel = SplitPanel;
	/**
	 * The namespace for the `SplitPanel` class statics.
	 */
	(function (SplitPanel) {
	    /**
	     * The default implementation of `IRenderer`.
	     */
	    var Renderer = (function () {
	        function Renderer() {
	        }
	        /**
	         * Create a new handle for use with a split panel.
	         *
	         * @returns A new handle element for a split panel.
	         */
	        Renderer.prototype.createHandle = function () {
	            var handle = document.createElement('div');
	            handle.className = 'p-SplitPanel-handle';
	            return handle;
	        };
	        return Renderer;
	    }());
	    SplitPanel.Renderer = Renderer;
	    /**
	     * The default `Renderer` instance.
	     */
	    SplitPanel.defaultRenderer = new Renderer();
	    /**
	     * Get the split panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @returns The split panel stretch factor for the widget.
	     */
	    function getStretch(widget) {
	        return splitlayout_1.SplitLayout.getStretch(widget);
	    }
	    SplitPanel.getStretch = getStretch;
	    /**
	     * Set the split panel stretch factor for the given widget.
	     *
	     * @param widget - The widget of interest.
	     *
	     * @param value - The value for the stretch factor.
	     */
	    function setStretch(widget, value) {
	        splitlayout_1.SplitLayout.setStretch(widget, value);
	    }
	    SplitPanel.setStretch = setStretch;
	})(SplitPanel = exports.SplitPanel || (exports.SplitPanel = {}));
	exports.SplitPanel = SplitPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a split layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new splitlayout_1.SplitLayout({
	            renderer: options.renderer || SplitPanel.defaultRenderer,
	            orientation: options.orientation,
	            alignment: options.alignment,
	            spacing: options.spacing
	        });
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/splitpanel.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/stackedlayout.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/stackedlayout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var layout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/layout.js');
	var panellayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/panellayout.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A layout where visible widgets are stacked atop one another.
	 *
	 * #### Notes
	 * The Z-order of the visible widgets follows their layout order.
	 */
	var StackedLayout = (function (_super) {
	    __extends(StackedLayout, _super);
	    function StackedLayout() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._dirty = false;
	        _this._items = [];
	        _this._box = null;
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the layout.
	     */
	    StackedLayout.prototype.dispose = function () {
	        // Dispose of the layout items.
	        algorithm_1.each(this._items, function (item) { item.dispose(); });
	        // Clear the layout state.
	        this._box = null;
	        this._items.length = 0;
	        // Dispose of the rest of the layout.
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Attach a widget to the parent's DOM node.
	     *
	     * @param index - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to attach to the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.attachWidget = function (index, widget) {
	        // Create and add a new layout item for the widget.
	        algorithm_1.ArrayExt.insert(this._items, index, new layout_1.LayoutItem(widget));
	        // Send a `'before-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeAttach);
	        }
	        // Add the widget's node to the parent.
	        this.parent.node.appendChild(widget.node);
	        // Send an `'after-attach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterAttach);
	        }
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * Move a widget in the parent's DOM node.
	     *
	     * @param fromIndex - The previous index of the widget in the layout.
	     *
	     * @param toIndex - The current index of the widget in the layout.
	     *
	     * @param widget - The widget to move in the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.moveWidget = function (fromIndex, toIndex, widget) {
	        // Move the layout item for the widget.
	        algorithm_1.ArrayExt.move(this._items, fromIndex, toIndex);
	        // Post an update request for the parent widget.
	        this.parent.update();
	    };
	    /**
	     * Detach a widget from the parent's DOM node.
	     *
	     * @param index - The previous index of the widget in the layout.
	     *
	     * @param widget - The widget to detach from the parent.
	     *
	     * #### Notes
	     * This is a reimplementation of the superclass method.
	     */
	    StackedLayout.prototype.detachWidget = function (index, widget) {
	        // Remove the layout item for the widget.
	        var item = algorithm_1.ArrayExt.removeAt(this._items, index);
	        // Send a `'before-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.BeforeDetach);
	        }
	        // Remove the widget's node from the parent.
	        this.parent.node.removeChild(widget.node);
	        // Send an `'after-detach'` message if the parent is attached.
	        if (this.parent.isAttached) {
	            messaging_1.MessageLoop.sendMessage(widget, widget_1.Widget.Msg.AfterDetach);
	        }
	        // Reset the z-index for the widget.
	        item.widget.node.style.zIndex = '';
	        // Dispose of the layout item.
	        item.dispose();
	        // Post a fit request for the parent widget.
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'before-show'` message.
	     */
	    StackedLayout.prototype.onBeforeShow = function (msg) {
	        _super.prototype.onBeforeShow.call(this, msg);
	        this.parent.update();
	    };
	    /**
	     * A message handler invoked on a `'before-attach'` message.
	     */
	    StackedLayout.prototype.onBeforeAttach = function (msg) {
	        _super.prototype.onBeforeAttach.call(this, msg);
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-shown'` message.
	     */
	    StackedLayout.prototype.onChildShown = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'child-hidden'` message.
	     */
	    StackedLayout.prototype.onChildHidden = function (msg) {
	        this.parent.fit();
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    StackedLayout.prototype.onResize = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(msg.width, msg.height);
	        }
	    };
	    /**
	     * A message handler invoked on an `'update-request'` message.
	     */
	    StackedLayout.prototype.onUpdateRequest = function (msg) {
	        if (this.parent.isVisible) {
	            this._update(-1, -1);
	        }
	    };
	    /**
	     * A message handler invoked on a `'fit-request'` message.
	     */
	    StackedLayout.prototype.onFitRequest = function (msg) {
	        if (this.parent.isAttached) {
	            this._fit();
	        }
	    };
	    /**
	     * Fit the layout to the total size required by the widgets.
	     */
	    StackedLayout.prototype._fit = function () {
	        // Set up the computed minimum size.
	        var minW = 0;
	        var minH = 0;
	        // Update the computed minimum size.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Update the size limits for the item.
	            item.fit();
	            // Update the computed minimum size.
	            minW = Math.max(minW, item.minWidth);
	            minH = Math.max(minH, item.minHeight);
	        }
	        // Update the box sizing and add it to the computed min size.
	        var box = this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        minW += box.horizontalSum;
	        minH += box.verticalSum;
	        // Update the parent's min size constraints.
	        var style = this.parent.node.style;
	        style.minWidth = minW + "px";
	        style.minHeight = minH + "px";
	        // Set the dirty flag to ensure only a single update occurs.
	        this._dirty = true;
	        // Notify the ancestor that it should fit immediately. This may
	        // cause a resize of the parent, fulfilling the required update.
	        if (this.parent.parent) {
	            messaging_1.MessageLoop.sendMessage(this.parent.parent, widget_1.Widget.Msg.FitRequest);
	        }
	        // If the dirty flag is still set, the parent was not resized.
	        // Trigger the required update on the parent widget immediately.
	        if (this._dirty) {
	            messaging_1.MessageLoop.sendMessage(this.parent, widget_1.Widget.Msg.UpdateRequest);
	        }
	    };
	    /**
	     * Update the layout position and size of the widgets.
	     *
	     * The parent offset dimensions should be `-1` if unknown.
	     */
	    StackedLayout.prototype._update = function (offsetWidth, offsetHeight) {
	        // Clear the dirty flag to indicate the update occurred.
	        this._dirty = false;
	        // Compute the visible item count.
	        var nVisible = 0;
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            nVisible += +!this._items[i].isHidden;
	        }
	        // Bail early if there are no visible items to layout.
	        if (nVisible === 0) {
	            return;
	        }
	        // Measure the parent if the offset dimensions are unknown.
	        if (offsetWidth < 0) {
	            offsetWidth = this.parent.node.offsetWidth;
	        }
	        if (offsetHeight < 0) {
	            offsetHeight = this.parent.node.offsetHeight;
	        }
	        // Ensure the parent box sizing data is computed.
	        if (!this._box) {
	            this._box = domutils_1.ElementExt.boxSizing(this.parent.node);
	        }
	        // Compute the actual layout bounds adjusted for border and padding.
	        var top = this._box.paddingTop;
	        var left = this._box.paddingLeft;
	        var width = offsetWidth - this._box.horizontalSum;
	        var height = offsetHeight - this._box.verticalSum;
	        // Update the widget stacking order and layout geometry.
	        for (var i = 0, n = this._items.length; i < n; ++i) {
	            // Fetch the item.
	            var item = this._items[i];
	            // Ignore hidden items.
	            if (item.isHidden) {
	                continue;
	            }
	            // Set the z-index for the widget.
	            item.widget.node.style.zIndex = "" + i;
	            // Update the item geometry.
	            item.update(left, top, width, height);
	        }
	    };
	    return StackedLayout;
	}(panellayout_1.PanelLayout));
	exports.StackedLayout = StackedLayout;
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/stackedlayout.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/stackedpanel.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/stackedpanel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var panel_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/panel.js');
	var stackedlayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/stackedlayout.js');
	/**
	 * A panel where visible widgets are stacked atop one another.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[StackedLayout]].
	 */
	var StackedPanel = (function (_super) {
	    __extends(StackedPanel, _super);
	    /**
	     * Construct a new stacked panel.
	     *
	     * @param options - The options for initializing the panel.
	     */
	    function StackedPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { layout: Private.createLayout(options) }) || this;
	        _this._widgetRemoved = new signaling_1.Signal(_this);
	        _this.addClass('p-StackedPanel');
	        return _this;
	    }
	    Object.defineProperty(StackedPanel.prototype, "widgetRemoved", {
	        /**
	         * A signal emitted when a widget is removed from a stacked panel.
	         */
	        get: function () {
	            return this._widgetRemoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on a `'child-added'` message.
	     */
	    StackedPanel.prototype.onChildAdded = function (msg) {
	        msg.child.addClass('p-StackedPanel-child');
	    };
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    StackedPanel.prototype.onChildRemoved = function (msg) {
	        msg.child.removeClass('p-StackedPanel-child');
	        this._widgetRemoved.emit(msg.child);
	    };
	    return StackedPanel;
	}(panel_1.Panel));
	exports.StackedPanel = StackedPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create a stacked layout for the given panel options.
	     */
	    function createLayout(options) {
	        return options.layout || new stackedlayout_1.StackedLayout();
	    }
	    Private.createLayout = createLayout;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/stackedpanel.js **/


/** START DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/tabpanel.js **/
jupyter.define('@phosphor/widgets@1.3.0/lib/tabpanel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.1/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.2.1/lib/index.js');
	var boxlayout_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/boxlayout.js');
	var stackedpanel_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/stackedpanel.js');
	var tabbar_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/tabbar.js');
	var widget_1 = __jupyter_require__('@phosphor/widgets@1.3.0/lib/widget.js');
	/**
	 * A widget which combines a `TabBar` and a `StackedPanel`.
	 *
	 * #### Notes
	 * This is a simple panel which handles the common case of a tab bar
	 * placed next to a content area. The selected tab controls the widget
	 * which is shown in the content area.
	 *
	 * For use cases which require more control than is provided by this
	 * panel, the `TabBar` widget may be used independently.
	 */
	var TabPanel = (function (_super) {
	    __extends(TabPanel, _super);
	    /**
	     * Construct a new tab panel.
	     *
	     * @param options - The options for initializing the tab panel.
	     */
	    function TabPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._currentChanged = new signaling_1.Signal(_this);
	        _this.addClass('p-TabPanel');
	        // Create the tab bar and stacked panel.
	        _this.tabBar = new tabbar_1.TabBar(options);
	        _this.tabBar.addClass('p-TabPanel-tabBar');
	        _this.stackedPanel = new stackedpanel_1.StackedPanel();
	        _this.stackedPanel.addClass('p-TabPanel-stackedPanel');
	        // Connect the tab bar signal handlers.
	        _this.tabBar.tabMoved.connect(_this._onTabMoved, _this);
	        _this.tabBar.currentChanged.connect(_this._onCurrentChanged, _this);
	        _this.tabBar.tabCloseRequested.connect(_this._onTabCloseRequested, _this);
	        _this.tabBar.tabActivateRequested.connect(_this._onTabActivateRequested, _this);
	        // Connect the stacked panel signal handlers.
	        _this.stackedPanel.widgetRemoved.connect(_this._onWidgetRemoved, _this);
	        // Get the data related to the placement.
	        _this._tabPlacement = options.tabPlacement || 'top';
	        var direction = Private.directionFromPlacement(_this._tabPlacement);
	        var orientation = Private.orientationFromPlacement(_this._tabPlacement);
	        // Configure the tab bar for the placement.
	        _this.tabBar.orientation = orientation;
	        _this.tabBar.dataset['placement'] = _this._tabPlacement;
	        // Create the box layout.
	        var layout = new boxlayout_1.BoxLayout({ direction: direction, spacing: 0 });
	        // Set the stretch factors for the child widgets.
	        boxlayout_1.BoxLayout.setStretch(_this.tabBar, 0);
	        boxlayout_1.BoxLayout.setStretch(_this.stackedPanel, 1);
	        // Add the child widgets to the layout.
	        layout.addWidget(_this.tabBar);
	        layout.addWidget(_this.stackedPanel);
	        // Install the layout on the tab panel.
	        _this.layout = layout;
	        return _this;
	    }
	    Object.defineProperty(TabPanel.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current tab is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected tab is changed
	         * either through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current
	         * tab changes due to tabs being inserted, removed, or moved. It is
	         * only emitted when the actual current tab node is changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentIndex", {
	        /**
	         * Get the index of the currently selected tab.
	         *
	         * #### Notes
	         * This will be `-1` if no tab is selected.
	         */
	        get: function () {
	            return this.tabBar.currentIndex;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * #### Notes
	         * If the index is out of range, it will be set to `-1`.
	         */
	        set: function (value) {
	            this.tabBar.currentIndex = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentWidget", {
	        /**
	         * Get the currently selected widget.
	         *
	         * #### Notes
	         * This will be `null` if there is no selected tab.
	         */
	        get: function () {
	            var title = this.tabBar.currentTitle;
	            return title ? title.owner : null;
	        },
	        /**
	         * Set the currently selected widget.
	         *
	         * #### Notes
	         * If the widget is not in the panel, it will be set to `null`.
	         */
	        set: function (value) {
	            this.tabBar.currentTitle = value ? value.title : null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabsMovable", {
	        /**
	         * Get the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        get: function () {
	            return this.tabBar.tabsMovable;
	        },
	        /**
	         * Set the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        set: function (value) {
	            this.tabBar.tabsMovable = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabPlacement", {
	        /**
	         * Get the tab placement for the tab panel.
	         *
	         * #### Notes
	         * This controls the position of the tab bar relative to the content.
	         */
	        get: function () {
	            return this._tabPlacement;
	        },
	        /**
	         * Set the tab placement for the tab panel.
	         *
	         * #### Notes
	         * This controls the position of the tab bar relative to the content.
	         */
	        set: function (value) {
	            // Bail if the placement does not change.
	            if (this._tabPlacement === value) {
	                return;
	            }
	            // Update the internal value.
	            this._tabPlacement = value;
	            // Get the values related to the placement.
	            var direction = Private.directionFromPlacement(value);
	            var orientation = Private.orientationFromPlacement(value);
	            // Configure the tab bar for the placement.
	            this.tabBar.orientation = orientation;
	            this.tabBar.dataset['placement'] = value;
	            // Update the layout direction.
	            this.layout.direction = direction;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the panel.
	         */
	        get: function () {
	            return this.stackedPanel.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a widget to the end of the tab panel.
	     *
	     * @param widget - The widget to add to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.addWidget = function (widget) {
	        this.insertWidget(this.widgets.length, widget);
	    };
	    /**
	     * Insert a widget into the tab panel at a specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.insertWidget = function (index, widget) {
	        if (widget !== this.currentWidget) {
	            widget.hide();
	        }
	        this.stackedPanel.insertWidget(index, widget);
	        this.tabBar.insertTab(index, widget.title);
	    };
	    /**
	     * Handle the `currentChanged` signal from the tab bar.
	     */
	    TabPanel.prototype._onCurrentChanged = function (sender, args) {
	        // Extract the previous and current title from the args.
	        var previousIndex = args.previousIndex, previousTitle = args.previousTitle, currentIndex = args.currentIndex, currentTitle = args.currentTitle;
	        // Extract the widgets from the titles.
	        var previousWidget = previousTitle ? previousTitle.owner : null;
	        var currentWidget = currentTitle ? currentTitle.owner : null;
	        // Hide the previous widget.
	        if (previousWidget) {
	            previousWidget.hide();
	        }
	        // Show the current widget.
	        if (currentWidget) {
	            currentWidget.show();
	        }
	        // Emit the `currentChanged` signal for the tab panel.
	        this._currentChanged.emit({
	            previousIndex: previousIndex, previousWidget: previousWidget, currentIndex: currentIndex, currentWidget: currentWidget
	        });
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	    };
	    /**
	     * Handle the `tabActivateRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabActivateRequested = function (sender, args) {
	        args.title.owner.activate();
	    };
	    /**
	     * Handle the `tabCloseRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabCloseRequested = function (sender, args) {
	        args.title.owner.close();
	    };
	    /**
	     * Handle the `tabMoved` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabMoved = function (sender, args) {
	        this.stackedPanel.insertWidget(args.toIndex, args.title.owner);
	    };
	    /**
	     * Handle the `widgetRemoved` signal from the stacked panel.
	     */
	    TabPanel.prototype._onWidgetRemoved = function (sender, widget) {
	        this.tabBar.removeTab(widget.title);
	    };
	    return TabPanel;
	}(widget_1.Widget));
	exports.TabPanel = TabPanel;
	/**
	 * The namespace for the module implementation details.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Convert a tab placement to tab bar orientation.
	     */
	    function orientationFromPlacement(plc) {
	        return placementToOrientationMap[plc];
	    }
	    Private.orientationFromPlacement = orientationFromPlacement;
	    /**
	     * Convert a tab placement to a box layout direction.
	     */
	    function directionFromPlacement(plc) {
	        return placementToDirectionMap[plc];
	    }
	    Private.directionFromPlacement = directionFromPlacement;
	    /**
	     * A mapping of tab placement to tab bar orientation.
	     */
	    var placementToOrientationMap = {
	        'top': 'horizontal',
	        'left': 'vertical',
	        'right': 'vertical',
	        'bottom': 'horizontal'
	    };
	    /**
	     * A mapping of tab placement to box layout direction.
	     */
	    var placementToDirectionMap = {
	        'top': 'top-to-bottom',
	        'left': 'left-to-right',
	        'right': 'right-to-left',
	        'bottom': 'bottom-to-top'
	    };
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @phosphor/widgets@1.3.0/lib/tabpanel.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	// widget_core implements some common patterns for the core widget collection
	// that are not to be used directly by third-party widget authors.
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var CoreWidgetModel = (function (_super) {
	    __extends(CoreWidgetModel, _super);
	    function CoreWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CoreWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'CoreWidgetModel',
	        });
	    };
	    return CoreWidgetModel;
	}(widget_1.WidgetModel));
	exports.CoreWidgetModel = CoreWidgetModel;
	var CoreDOMWidgetModel = (function (_super) {
	    __extends(CoreDOMWidgetModel, _super);
	    function CoreDOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CoreDOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'CoreDOMWidgetModel',
	        });
	    };
	    return CoreDOMWidgetModel;
	}(widget_1.DOMWidgetModel));
	exports.CoreDOMWidgetModel = CoreDOMWidgetModel;
	var CoreLabeledDOMWidgetModel = (function (_super) {
	    __extends(CoreLabeledDOMWidgetModel, _super);
	    function CoreLabeledDOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CoreLabeledDOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'CoreLabeledDOMWidgetModel',
	        });
	    };
	    return CoreLabeledDOMWidgetModel;
	}(widget_1.LabeledDOMWidgetModel));
	exports.CoreLabeledDOMWidgetModel = CoreLabeledDOMWidgetModel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_layout.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_layout.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	/**
	 * css properties exposed by the layout widget with their default values.
	 */
	var css_properties = {
	    align_content: null,
	    align_items: null,
	    align_self: null,
	    border: null,
	    bottom: null,
	    display: null,
	    flex: null,
	    flex_flow: null,
	    height: null,
	    justify_content: null,
	    left: null,
	    margin: null,
	    max_height: null,
	    max_width: null,
	    min_height: null,
	    min_width: null,
	    overflow: null,
	    overflow_x: null,
	    overflow_y: null,
	    order: null,
	    padding: null,
	    right: null,
	    top: null,
	    visibility: null,
	    width: null
	};
	var LayoutModel = (function (_super) {
	    __extends(LayoutModel, _super);
	    function LayoutModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LayoutModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'LayoutModel',
	            _view_name: 'LayoutView'
	        }, css_properties);
	    };
	    return LayoutModel;
	}(widget_core_1.CoreWidgetModel));
	exports.LayoutModel = LayoutModel;
	var LayoutView = (function (_super) {
	    __extends(LayoutView, _super);
	    function LayoutView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    LayoutView.prototype.initialize = function (parameters) {
	        this._traitNames = [];
	        _super.prototype.initialize.call(this, parameters);
	        // Register the traits that live on the Python side
	        for (var _i = 0, _a = Object.keys(css_properties); _i < _a.length; _i++) {
	            var key = _a[_i];
	            this.registerTrait(key);
	        }
	    };
	    /**
	     * Register a CSS trait that is known by the model
	     * @param trait
	     */
	    LayoutView.prototype.registerTrait = function (trait) {
	        var _this = this;
	        this._traitNames.push(trait);
	        // Listen to changes, and set the value on change.
	        this.listenTo(this.model, 'change:' + trait, function (model, value) {
	            _this.handleChange(trait, value);
	        });
	        // Set the initial value on display.
	        this.handleChange(trait, this.model.get(trait));
	    };
	    /**
	     * Get the the name of the css property from the trait name
	     * @param  model attribute name
	     * @return css property name
	     */
	    LayoutView.prototype.css_name = function (trait) {
	        return trait.replace('_', '-');
	    };
	    /**
	     * Handles when a trait value changes
	     */
	    LayoutView.prototype.handleChange = function (trait, value) {
	        // should be synchronous so that we can measure later.
	        var parent = this.options.parent;
	        if (parent) {
	            if (value === null) {
	                parent.el.style.removeProperty(this.css_name(trait));
	            }
	            else {
	                parent.el.style[this.css_name(trait)] = value;
	            }
	        }
	        else {
	            console.warn('Style not applied because a parent view does not exist');
	        }
	    };
	    /**
	     * Remove the styling from the parent view.
	     */
	    LayoutView.prototype.unlayout = function () {
	        var _this = this;
	        var parent = this.options.parent;
	        this._traitNames.forEach(function (trait) {
	            if (parent) {
	                parent.el.style.removeProperty(_this.css_name(trait));
	            }
	            else {
	                console.warn('Style not removed because a parent view does not exist');
	            }
	        }, this);
	    };
	    return LayoutView;
	}(widget_1.WidgetView));
	exports.LayoutView = LayoutView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_layout.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_style.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_style.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var StyleModel = (function (_super) {
	    __extends(StyleModel, _super);
	    function StyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    StyleModel.prototype.defaults = function () {
	        var Derived = this.constructor;
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'StyleModel',
	            _view_name: 'StyleView',
	        }, _.reduce(Object.keys(Derived.styleProperties), function (obj, key) {
	            obj[key] = Derived.styleProperties[key].default;
	            return obj;
	        }, {}));
	    };
	    return StyleModel;
	}(widget_core_1.CoreWidgetModel));
	StyleModel.styleProperties = {};
	exports.StyleModel = StyleModel;
	var StyleView = (function (_super) {
	    __extends(StyleView, _super);
	    function StyleView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    StyleView.prototype.initialize = function (parameters) {
	        this._traitNames = [];
	        _super.prototype.initialize.call(this, parameters);
	        // Register the traits that live on the Python side
	        var ModelType = this.model.constructor;
	        for (var _i = 0, _a = Object.keys(ModelType.styleProperties); _i < _a.length; _i++) {
	            var key = _a[_i];
	            this.registerTrait(key);
	        }
	    };
	    /**
	     * Register a CSS trait that is known by the model
	     * @param trait
	     */
	    StyleView.prototype.registerTrait = function (trait) {
	        var _this = this;
	        this._traitNames.push(trait);
	        // Listen to changes, and set the value on change.
	        this.listenTo(this.model, 'change:' + trait, function (model, value) {
	            _this.handleChange(trait, value);
	        });
	        // Set the initial value on display.
	        this.handleChange(trait, this.model.get(trait));
	    };
	    /**
	     * Handles when a trait value changes
	     */
	    StyleView.prototype.handleChange = function (trait, value) {
	        // should be synchronous so that we can measure later.
	        var parent = this.options.parent;
	        if (parent) {
	            var ModelType = this.model.constructor;
	            var styleProperties = ModelType.styleProperties;
	            var attribute = styleProperties[trait].attribute;
	            var selector = styleProperties[trait].selector;
	            var elements = selector ? parent.el.querySelectorAll(selector) : [parent.el];
	            if (value === null) {
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style.removeProperty(attribute);
	                }
	            }
	            else {
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style[attribute] = value;
	                }
	            }
	        }
	        else {
	            console.warn('Style not applied because a parent view does not exist');
	        }
	    };
	    /**
	     * Remove the styling from the parent view.
	     */
	    StyleView.prototype.unstyle = function () {
	        var parent = this.options.parent;
	        var ModelType = this.model.constructor;
	        var styleProperties = ModelType.styleProperties;
	        this._traitNames.forEach(function (trait) {
	            if (parent) {
	                var attribute = styleProperties[trait].attribute;
	                var selector = styleProperties[trait].selector;
	                var elements = selector ? parent.el.querySelectorAll(selector) : [parent.el];
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style.removeProperty(attribute);
	                }
	            }
	            else {
	                console.warn('Style not removed because a parent view does not exist');
	            }
	        }, this);
	    };
	    return StyleView;
	}(widget_1.WidgetView));
	exports.StyleView = StyleView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_style.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_link.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_link.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var DirectionalLinkModel = (function (_super) {
	    __extends(DirectionalLinkModel, _super);
	    function DirectionalLinkModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DirectionalLinkModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            target: undefined,
	            source: undefined,
	            _model_name: 'DirectionalLinkModel'
	        });
	    };
	    DirectionalLinkModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.on('change', this.updateBindings, this);
	        this.updateBindings();
	    };
	    DirectionalLinkModel.prototype.updateValue = function (sourceModel, sourceAttr, targetModel, targetAttr) {
	        if (this._updating) {
	            return;
	        }
	        this._updating = true;
	        try {
	            if (targetModel) {
	                targetModel.set(targetAttr, sourceModel.get(sourceAttr));
	                targetModel.save_changes();
	            }
	        }
	        finally {
	            this._updating = false;
	        }
	    };
	    DirectionalLinkModel.prototype.updateBindings = function () {
	        var _this = this;
	        this.cleanup();
	        _a = this.get('source') || [null, null], this.sourceModel = _a[0], this.sourceAttr = _a[1];
	        _b = this.get('target') || [null, null], this.targetModel = _b[0], this.targetAttr = _b[1];
	        if (this.sourceModel) {
	            this.listenTo(this.sourceModel, 'change:' + this.sourceAttr, function () {
	                _this.updateValue(_this.sourceModel, _this.sourceAttr, _this.targetModel, _this.targetAttr);
	            });
	            this.updateValue(this.sourceModel, this.sourceAttr, this.targetModel, this.targetAttr);
	            this.listenToOnce(this.sourceModel, 'destroy', this.cleanup);
	        }
	        if (this.targetModel) {
	            this.listenToOnce(this.targetModel, 'destroy', this.cleanup);
	        }
	        var _a, _b;
	    };
	    DirectionalLinkModel.prototype.cleanup = function () {
	        // Stop listening to 'change' and 'destroy' events of the source and target
	        if (this.sourceModel) {
	            this.stopListening(this.sourceModel, 'change:' + this.sourceAttr, null);
	            this.stopListening(this.sourceModel, 'destroy', null);
	        }
	        if (this.targetModel) {
	            this.stopListening(this.targetModel, 'destroy', null);
	        }
	    };
	    return DirectionalLinkModel;
	}(widget_core_1.CoreWidgetModel));
	DirectionalLinkModel.serializers = __assign({}, widget_core_1.CoreWidgetModel.serializers, { target: { deserialize: widget_1.unpack_models }, source: { deserialize: widget_1.unpack_models } });
	exports.DirectionalLinkModel = DirectionalLinkModel;
	var LinkModel = (function (_super) {
	    __extends(LinkModel, _super);
	    function LinkModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LinkModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'LinkModel'
	        });
	    };
	    LinkModel.prototype.updateBindings = function () {
	        var _this = this;
	        _super.prototype.updateBindings.call(this);
	        if (this.targetModel) {
	            this.listenTo(this.targetModel, 'change:' + this.targetAttr, function () {
	                _this.updateValue(_this.targetModel, _this.targetAttr, _this.sourceModel, _this.sourceAttr);
	            });
	        }
	    };
	    LinkModel.prototype.cleanup = function () {
	        _super.prototype.cleanup.call(this);
	        if (this.targetModel) {
	            this.stopListening(this.targetModel, 'change:' + this.targetAttr, null);
	        }
	    };
	    return LinkModel;
	}(DirectionalLinkModel));
	exports.LinkModel = LinkModel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_link.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_bool.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_bool.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var BoolModel = (function (_super) {
	    __extends(BoolModel, _super);
	    function BoolModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoolModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: false,
	            disabled: false,
	            _model_name: 'BoolModel'
	        });
	    };
	    return BoolModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.BoolModel = BoolModel;
	var CheckboxModel = (function (_super) {
	    __extends(CheckboxModel, _super);
	    function CheckboxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CheckboxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            indent: true,
	            _view_name: 'CheckboxView',
	            _model_name: 'CheckboxModel'
	        });
	    };
	    return CheckboxModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.CheckboxModel = CheckboxModel;
	var CheckboxView = (function (_super) {
	    __extends(CheckboxView, _super);
	    function CheckboxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    CheckboxView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-checkbox');
	        // adding a zero-width space to the label to help 
	        // the browser set the baseline correctly
	        this.label.innerHTML = '&#8203;';
	        // label containing the checkbox and description span
	        this.checkboxLabel = document.createElement('label');
	        this.checkboxLabel.classList.add('widget-label-basic');
	        this.el.appendChild(this.checkboxLabel);
	        // checkbox
	        this.checkbox = document.createElement('input');
	        this.checkbox.setAttribute('type', 'checkbox');
	        this.checkboxLabel.appendChild(this.checkbox);
	        // span to the right of the checkbox that will render the description
	        this.descriptionSpan = document.createElement('span');
	        this.checkboxLabel.appendChild(this.descriptionSpan);
	        this.listenTo(this.model, 'change:indent', this.updateIndent);
	        this.update(); // Set defaults.
	        this.updateDescription();
	        this.updateIndent();
	    };
	    /**
	     * Overriden from super class
	     *
	     * Update the description span (rather than the label) since
	     * we want the description to the right of the checkbox.
	     */
	    CheckboxView.prototype.updateDescription = function () {
	        // can be called before the view is fully initialized
	        if (this.checkboxLabel == null)
	            return;
	        var description = this.model.get('description');
	        this.descriptionSpan.innerHTML = description;
	        this.typeset(this.descriptionSpan);
	        this.descriptionSpan.title = description;
	        this.checkbox.title = description;
	    };
	    /**
	     * Update the visibility of the label in the super class
	     * to provide the optional indent.
	     */
	    CheckboxView.prototype.updateIndent = function () {
	        var indent = this.model.get('indent');
	        this.label.style.display = indent ? '' : 'none';
	    };
	    CheckboxView.prototype.events = function () {
	        return {
	            'click input[type="checkbox"]': '_handle_click'
	        };
	    };
	    /**
	     * Handles when the checkbox is clicked.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    CheckboxView.prototype._handle_click = function () {
	        var value = this.model.get('value');
	        this.model.set('value', !value, { updated_view: this });
	        this.touch();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed. The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    CheckboxView.prototype.update = function (options) {
	        this.checkbox.checked = this.model.get('value');
	        if (options === undefined || options.updated_view != this) {
	            this.checkbox.disabled = this.model.get('disabled');
	        }
	        return _super.prototype.update.call(this);
	    };
	    return CheckboxView;
	}(widget_1.LabeledDOMWidgetView));
	exports.CheckboxView = CheckboxView;
	var ToggleButtonModel = (function (_super) {
	    __extends(ToggleButtonModel, _super);
	    function ToggleButtonModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ToggleButtonModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'ToggleButtonView',
	            _model_name: 'ToggleButtonModel',
	            tooltip: '',
	            icon: '',
	            button_style: ''
	        });
	    };
	    return ToggleButtonModel;
	}(BoolModel));
	exports.ToggleButtonModel = ToggleButtonModel;
	var ToggleButtonView = (function (_super) {
	    __extends(ToggleButtonView, _super);
	    function ToggleButtonView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    ToggleButtonView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.className = 'jupyter-widgets jupyter-button widget-toggle-button';
	        this.listenTo(this.model, 'change:button_style', this.update_button_style);
	        this.set_button_style();
	        this.update(); // Set defaults.
	    };
	    ToggleButtonView.prototype.update_button_style = function () {
	        this.update_mapped_classes(ToggleButtonView.class_map, 'button_style');
	    };
	    ToggleButtonView.prototype.set_button_style = function () {
	        this.set_mapped_classes(ToggleButtonView.class_map, 'button_style');
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed. The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ToggleButtonView.prototype.update = function (options) {
	        if (this.model.get('value')) {
	            this.el.classList.add('mod-active');
	        }
	        else {
	            this.el.classList.remove('mod-active');
	        }
	        if (options === undefined || options.updated_view !== this) {
	            this.el.disabled = this.model.get('disabled');
	            this.el.setAttribute('title', this.model.get('tooltip'));
	            var description = this.model.get('description');
	            var icon = this.model.get('icon');
	            if (description.trim().length === 0 && icon.trim().length === 0) {
	                this.el.innerHTML = '&nbsp;'; // Preserve button height
	            }
	            else {
	                this.el.textContent = '';
	                if (icon.trim().length) {
	                    var i = document.createElement('i');
	                    this.el.appendChild(i);
	                    i.classList.add('fa');
	                    i.classList.add('fa-' + icon);
	                }
	                this.el.appendChild(document.createTextNode(description));
	            }
	        }
	        return _super.prototype.update.call(this);
	    };
	    ToggleButtonView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'click': '_handle_click'
	        };
	    };
	    /**
	     * Handles and validates user input.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    ToggleButtonView.prototype._handle_click = function (event) {
	        event.preventDefault();
	        var value = this.model.get('value');
	        this.model.set('value', !value, { updated_view: this });
	        this.touch();
	    };
	    Object.defineProperty(ToggleButtonView.prototype, "tagName", {
	        /**
	         * The default tag name.
	         *
	         * #### Notes
	         * This is a read-only attribute.
	         */
	        get: function () {
	            // We can't make this an attribute with a default value
	            // since it would be set after it is needed in the
	            // constructor.
	            return 'button';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ToggleButtonView;
	}(widget_1.DOMWidgetView));
	ToggleButtonView.class_map = {
	    primary: ['mod-primary'],
	    success: ['mod-success'],
	    info: ['mod-info'],
	    warning: ['mod-warning'],
	    danger: ['mod-danger']
	};
	exports.ToggleButtonView = ToggleButtonView;
	var ValidModel = (function (_super) {
	    __extends(ValidModel, _super);
	    function ValidModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ValidModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            readout: 'Invalid',
	            _view_name: 'ValidView',
	            _model_name: 'ValidModel'
	        });
	    };
	    return ValidModel;
	}(BoolModel));
	exports.ValidModel = ValidModel;
	var ValidView = (function (_super) {
	    __extends(ValidView, _super);
	    function ValidView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    ValidView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-valid');
	        this.el.classList.add('widget-inline-hbox');
	        var icon = document.createElement('i');
	        this.el.appendChild(icon);
	        this.readout = document.createElement('span');
	        this.readout.classList.add('widget-valid-readout');
	        this.readout.classList.add('widget-readout');
	        this.el.appendChild(this.readout);
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ValidView.prototype.update = function () {
	        this.el.classList.remove('mod-valid');
	        this.el.classList.remove('mod-invalid');
	        this.readout.textContent = this.model.get('readout');
	        if (this.model.get('value')) {
	            this.el.classList.add('mod-valid');
	        }
	        else {
	            this.el.classList.add('mod-invalid');
	        }
	    };
	    return ValidView;
	}(widget_1.LabeledDOMWidgetView));
	exports.ValidView = ValidView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_bool.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_button.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_button.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var widget_style_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_style.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var ButtonStyleModel = (function (_super) {
	    __extends(ButtonStyleModel, _super);
	    function ButtonStyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ButtonStyleModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ButtonStyleModel',
	        });
	    };
	    return ButtonStyleModel;
	}(widget_style_1.StyleModel));
	ButtonStyleModel.styleProperties = {
	    button_color: {
	        selector: '',
	        attribute: 'background-color',
	        default: null
	    },
	    font_weight: {
	        selector: '',
	        attribute: 'font-weight',
	        default: ''
	    }
	};
	exports.ButtonStyleModel = ButtonStyleModel;
	var ButtonModel = (function (_super) {
	    __extends(ButtonModel, _super);
	    function ButtonModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ButtonModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            description: '',
	            tooltip: '',
	            disabled: false,
	            icon: '',
	            button_style: '',
	            _view_name: 'ButtonView',
	            _model_name: 'ButtonModel',
	            style: null
	        });
	    };
	    return ButtonModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ButtonModel = ButtonModel;
	var ButtonView = (function (_super) {
	    __extends(ButtonView, _super);
	    function ButtonView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    ButtonView.prototype.render = function () {
	        this.el.className = 'jupyter-widgets jupyter-button widget-button';
	        this.listenTo(this.model, 'change:button_style', this.update_button_style);
	        this.set_button_style();
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed. The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ButtonView.prototype.update = function () {
	        this.el.disabled = this.model.get('disabled');
	        this.el.setAttribute('title', this.model.get('tooltip'));
	        var description = this.model.get('description');
	        var icon = this.model.get('icon');
	        if (description.trim().length || icon.trim().length) {
	            this.el.textContent = '';
	            if (icon.trim().length) {
	                var i = document.createElement('i');
	                i.classList.add('fa');
	                i.classList.add('fa-' + icon);
	                if (description.trim().length === 0) {
	                    i.classList.add('center');
	                }
	                this.el.appendChild(i);
	            }
	            this.el.appendChild(document.createTextNode(description));
	        }
	        return _super.prototype.update.call(this);
	    };
	    ButtonView.prototype.update_button_style = function () {
	        this.update_mapped_classes(ButtonView.class_map, 'button_style');
	    };
	    ButtonView.prototype.set_button_style = function () {
	        this.set_mapped_classes(ButtonView.class_map, 'button_style');
	    };
	    /**
	     * Dictionary of events and handlers
	     */
	    ButtonView.prototype.events = function () {
	        // TODO: return typing not needed in Typescript later than 1.8.x
	        // See http://stackoverflow.com/questions/22077023/why-cant-i-indirectly-return-an-object-literal-to-satisfy-an-index-signature-re and https://github.com/Microsoft/TypeScript/pull/7029
	        return { 'click': '_handle_click' };
	    };
	    /**
	     * Handles when the button is clicked.
	     */
	    ButtonView.prototype._handle_click = function (event) {
	        event.preventDefault();
	        this.send({ event: 'click' });
	    };
	    Object.defineProperty(ButtonView.prototype, "tagName", {
	        /**
	         * The default tag name.
	         *
	         * #### Notes
	         * This is a read-only attribute.
	         */
	        get: function () {
	            // We can't make this an attribute with a default value
	            // since it would be set after it is needed in the
	            // constructor.
	            return 'button';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ButtonView;
	}(widget_1.DOMWidgetView));
	ButtonView.class_map = {
	    primary: ['mod-primary'],
	    success: ['mod-success'],
	    info: ['mod-info'],
	    warning: ['mod-warning'],
	    danger: ['mod-danger']
	};
	exports.ButtonView = ButtonView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_button.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_box.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_box.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var utils_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js');
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.0/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.2.0/lib/index.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	var JupyterPhosphorPanelWidget = (function (_super) {
	    __extends(JupyterPhosphorPanelWidget, _super);
	    function JupyterPhosphorPanelWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        return _this;
	    }
	    /**
	     * Process the phosphor message.
	     *
	     * Any custom phosphor widget used inside a Jupyter widget should override
	     * the processMessage function like this.
	     */
	    JupyterPhosphorPanelWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        this._view.processPhosphorMessage(msg);
	    };
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorPanelWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    return JupyterPhosphorPanelWidget;
	}(widgets_1.Panel));
	exports.JupyterPhosphorPanelWidget = JupyterPhosphorPanelWidget;
	var BoxModel = (function (_super) {
	    __extends(BoxModel, _super);
	    function BoxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'BoxView',
	            _model_name: 'BoxModel',
	            children: [],
	            box_style: ''
	        });
	    };
	    return BoxModel;
	}(widget_core_1.CoreDOMWidgetModel));
	BoxModel.serializers = __assign({}, widget_core_1.CoreDOMWidgetModel.serializers, { children: { deserialize: widget_1.unpack_models } });
	exports.BoxModel = BoxModel;
	var HBoxModel = (function (_super) {
	    __extends(HBoxModel, _super);
	    function HBoxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    HBoxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'HBoxView',
	            _model_name: 'HBoxModel',
	        });
	    };
	    return HBoxModel;
	}(BoxModel));
	exports.HBoxModel = HBoxModel;
	var VBoxModel = (function (_super) {
	    __extends(VBoxModel, _super);
	    function VBoxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    VBoxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'VBoxView',
	            _model_name: 'VBoxModel',
	        });
	    };
	    return VBoxModel;
	}(BoxModel));
	exports.VBoxModel = VBoxModel;
	var BoxView = (function (_super) {
	    __extends(BoxView, _super);
	    function BoxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoxView.prototype._createElement = function (tagName) {
	        this.pWidget = new JupyterPhosphorPanelWidget({ view: this });
	        return this.pWidget.node;
	    };
	    BoxView.prototype._setElement = function (el) {
	        if (this.el || el !== this.pWidget.node) {
	            // Boxes don't allow setting the element beyond the initial creation.
	            throw new Error('Cannot reset the DOM element.');
	        }
	        this.el = this.pWidget.node;
	        this.$el = $(this.pWidget.node);
	    };
	    /**
	     * Public constructor
	     */
	    BoxView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.children_views = new widget_1.ViewList(this.add_child_model, null, this);
	        this.listenTo(this.model, 'change:children', this.update_children);
	        this.listenTo(this.model, 'change:box_style', this.update_box_style);
	        this.pWidget.addClass('jupyter-widgets');
	        this.pWidget.addClass('widget-container');
	        this.pWidget.addClass('widget-box');
	    };
	    /**
	     * Called when view is rendered.
	     */
	    BoxView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.update_children();
	        this.set_box_style();
	    };
	    BoxView.prototype.update_children = function () {
	        this.children_views.update(this.model.get('children')).then(function (views) {
	            // Notify all children that their sizes may have changed.
	            views.forEach(function (view) {
	                messaging_1.MessageLoop.postMessage(view.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	            });
	        });
	    };
	    BoxView.prototype.update_box_style = function () {
	        this.update_mapped_classes(BoxView.class_map, 'box_style');
	    };
	    BoxView.prototype.set_box_style = function () {
	        this.set_mapped_classes(BoxView.class_map, 'box_style');
	    };
	    BoxView.prototype.add_child_model = function (model) {
	        var _this = this;
	        // we insert a dummy element so the order is preserved when we add
	        // the rendered content later.
	        var dummy = new widgets_1.Widget();
	        this.pWidget.addWidget(dummy);
	        return this.create_child_view(model).then(function (view) {
	            // replace the dummy widget with the new one.
	            var i = algorithm_1.ArrayExt.firstIndexOf(_this.pWidget.widgets, dummy);
	            _this.pWidget.insertWidget(i, view.pWidget);
	            dummy.dispose();
	            return view;
	        }).catch(utils_1.reject('Could not add child view to box', true));
	    };
	    BoxView.prototype.remove = function () {
	        this.children_views = null;
	        _super.prototype.remove.call(this);
	    };
	    return BoxView;
	}(widget_1.DOMWidgetView));
	BoxView.class_map = {
	    success: ['alert', 'alert-success'],
	    info: ['alert', 'alert-info'],
	    warning: ['alert', 'alert-warning'],
	    danger: ['alert', 'alert-danger']
	};
	exports.BoxView = BoxView;
	var HBoxView = (function (_super) {
	    __extends(HBoxView, _super);
	    function HBoxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    HBoxView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.pWidget.addClass('widget-hbox');
	    };
	    return HBoxView;
	}(BoxView));
	exports.HBoxView = HBoxView;
	var VBoxView = (function (_super) {
	    __extends(VBoxView, _super);
	    function VBoxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    VBoxView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.pWidget.addClass('widget-vbox');
	    };
	    return VBoxView;
	}(BoxView));
	exports.VBoxView = VBoxView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_box.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_image.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_image.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var ImageModel = (function (_super) {
	    __extends(ImageModel, _super);
	    function ImageModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ImageModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ImageModel',
	            _view_name: 'ImageView',
	            format: 'png',
	            width: '',
	            height: '',
	            _b64value: ''
	        });
	    };
	    return ImageModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ImageModel = ImageModel;
	var ImageView = (function (_super) {
	    __extends(ImageView, _super);
	    function ImageView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ImageView.prototype.render = function () {
	        /**
	         * Called when view is rendered.
	         */
	        this.pWidget.addClass('jupyter-widgets');
	        this.pWidget.addClass('widget-image');
	        this.update(); // Set defaults.
	    };
	    ImageView.prototype.update = function () {
	        /**
	         * Update the contents of this view
	         *
	         * Called when the model is changed.  The model may have been
	         * changed by another view or by a state update from the back-end.
	         */
	        var image_src = 'data:image/' + this.model.get('format') + ';base64,' + this.model.get('_b64value');
	        this.el.setAttribute('src', image_src);
	        var width = this.model.get('width');
	        if (width !== undefined && width.length > 0) {
	            this.el.setAttribute('width', width);
	        }
	        else {
	            this.el.removeAttribute('width');
	        }
	        var height = this.model.get('height');
	        if (height !== undefined && height.length > 0) {
	            this.el.setAttribute('height', height);
	        }
	        else {
	            this.el.removeAttribute('height');
	        }
	        return _super.prototype.update.call(this);
	    };
	    Object.defineProperty(ImageView.prototype, "tagName", {
	        /**
	         * The default tag name.
	         *
	         * #### Notes
	         * This is a read-only attribute.
	         */
	        get: function () {
	            // We can't make this an attribute with a default value
	            // since it would be set after it is needed in the
	            // constructor.
	            return 'img';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ImageView;
	}(widget_1.DOMWidgetView));
	exports.ImageView = ImageView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_image.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_color.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_color.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var ColorPickerModel = (function (_super) {
	    __extends(ColorPickerModel, _super);
	    function ColorPickerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ColorPickerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: 'black',
	            concise: false,
	            _model_name: 'ColorPickerModel',
	            _view_name: 'ColorPickerView'
	        });
	    };
	    return ColorPickerModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.ColorPickerModel = ColorPickerModel;
	var ColorPickerView = (function (_super) {
	    __extends(ColorPickerView, _super);
	    function ColorPickerView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ColorPickerView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-colorpicker');
	        this._color_container = document.createElement('div');
	        this._color_container.className = 'widget-inline-hbox widget-colorpicker-input';
	        this.el.appendChild(this._color_container);
	        this._textbox = document.createElement('input');
	        this._textbox.setAttribute('type', 'text');
	        this._color_container.appendChild(this._textbox);
	        this._textbox.value = this.model.get('value');
	        this._colorpicker = document.createElement('input');
	        this._colorpicker.setAttribute('type', 'color');
	        this._color_container.appendChild(this._colorpicker);
	        this.listenTo(this.model, 'change:value', this._update_value);
	        this.listenTo(this.model, 'change:concise', this._update_concise);
	        this._update_concise();
	        this._update_value();
	    };
	    ColorPickerView.prototype.events = function () {
	        return {
	            'change [type="color"]': '_picker_change',
	            'change [type="text"]': '_text_change'
	        };
	    };
	    ColorPickerView.prototype._update_value = function () {
	        var value = this.model.get('value');
	        this._colorpicker.value = color2hex(value);
	        this._textbox.value = value;
	    };
	    ColorPickerView.prototype._update_concise = function () {
	        var concise = this.model.get('concise');
	        if (concise) {
	            this.el.classList.add('concise');
	            this._textbox.style.display = 'none';
	        }
	        else {
	            this.el.classList.remove('concise');
	            this._textbox.style.display = '';
	        }
	    };
	    ColorPickerView.prototype._picker_change = function () {
	        this.model.set('value', this._colorpicker.value);
	        this.touch();
	    };
	    ColorPickerView.prototype._text_change = function () {
	        var value = this._validate_color(this._textbox.value, this.model.get('value'));
	        this.model.set('value', value);
	        this.touch();
	    };
	    ColorPickerView.prototype._validate_color = function (color, fallback) {
	        return color.match(/#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$/) ||
	            named_colors[color.toLowerCase()] ? color : fallback;
	    };
	    return ColorPickerView;
	}(widget_1.LabeledDOMWidgetView));
	exports.ColorPickerView = ColorPickerView;
	var named_colors = { aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#00ffff', aquamarine: '#7fffd4', azure: '#f0ffff', beige: '#f5f5dc', bisque: '#ffe4c4', black: '#000000', blanchedalmond: '#ffebcd', blue: '#0000ff', blueviolet: '#8a2be2', brown: '#a52a2a', burlywood: '#deb887', cadetblue: '#5f9ea0', chartreuse: '#7fff00', chocolate: '#d2691e', coral: '#ff7f50', cornflowerblue: '#6495ed', cornsilk: '#fff8dc', crimson: '#dc143c', cyan: '#00ffff', darkblue: '#00008b', darkcyan: '#008b8b', darkgoldenrod: '#b8860b', darkgray: '#a9a9a9', darkgrey: '#a9a9a9', darkgreen: '#006400', darkkhaki: '#bdb76b', darkmagenta: '#8b008b', darkolivegreen: '#556b2f', darkorange: '#ff8c00', darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a', darkseagreen: '#8fbc8f', darkslateblue: '#483d8b', darkslategray: '#2f4f4f', darkslategrey: '#2f4f4f', darkturquoise: '#00ced1', darkviolet: '#9400d3', deeppink: '#ff1493', deepskyblue: '#00bfff', dimgray: '#696969', dimgrey: '#696969', dodgerblue: '#1e90ff', firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22', fuchsia: '#ff00ff', gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff', gold: '#ffd700', goldenrod: '#daa520', gray: '#808080', grey: '#808080', green: '#008000', greenyellow: '#adff2f', honeydew: '#f0fff0', hotpink: '#ff69b4', indianred: '#cd5c5c', indigo: '#4b0082', ivory: '#fffff0', khaki: '#f0e68c', lavender: '#e6e6fa', lavenderblush: '#fff0f5', lawngreen: '#7cfc00', lemonchiffon: '#fffacd', lightblue: '#add8e6', lightcoral: '#f08080', lightcyan: '#e0ffff', lightgoldenrodyellow: '#fafad2', lightgreen: '#90ee90', lightgray: '#d3d3d3', lightgrey: '#d3d3d3', lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa', lightskyblue: '#87cefa', lightslategray: '#778899', lightslategrey: '#778899', lightsteelblue: '#b0c4de', lightyellow: '#ffffe0', lime: '#00ff00', limegreen: '#32cd32', linen: '#faf0e6', magenta: '#ff00ff', maroon: '#800000', mediumaquamarine: '#66cdaa', mediumblue: '#0000cd', mediumorchid: '#ba55d3', mediumpurple: '#9370db', mediumseagreen: '#3cb371', mediumslateblue: '#7b68ee', mediumspringgreen: '#00fa9a', mediumturquoise: '#48d1cc', mediumvioletred: '#c71585', midnightblue: '#191970', mintcream: '#f5fffa', mistyrose: '#ffe4e1', moccasin: '#ffe4b5', navajowhite: '#ffdead', navy: '#000080', oldlace: '#fdf5e6', olive: '#808000', olivedrab: '#6b8e23', orange: '#ffa500', orangered: '#ff4500', orchid: '#da70d6', palegoldenrod: '#eee8aa', palegreen: '#98fb98', paleturquoise: '#afeeee', palevioletred: '#db7093', papayawhip: '#ffefd5', peachpuff: '#ffdab9', peru: '#cd853f', pink: '#ffc0cb', plum: '#dda0dd', powderblue: '#b0e0e6', purple: '#800080', red: '#ff0000', rosybrown: '#bc8f8f', royalblue: '#4169e1', saddlebrown: '#8b4513', salmon: '#fa8072', sandybrown: '#f4a460', seagreen: '#2e8b57', seashell: '#fff5ee', sienna: '#a0522d', silver: '#c0c0c0', skyblue: '#87ceeb', slateblue: '#6a5acd', slategray: '#708090', slategrey: '#708090', snow: '#fffafa', springgreen: '#00ff7f', steelblue: '#4682b4', tan: '#d2b48c', teal: '#008080', thistle: '#d8bfd8', tomato: '#ff6347', turquoise: '#40e0d0', violet: '#ee82ee', wheat: '#f5deb3', white: '#ffffff', whitesmoke: '#f5f5f5', yellow: '#ffff00', yellowgreen: '#9acd32', };
	/*
	 * From a valid html color (named color, 6-digits or 3-digits hex format)
	 * return a 6-digits hexadecimal color #rrggbb.
	 */
	function color2hex(color) {
	    return named_colors[color.toLowerCase()] || rgb3_to_rgb6(color);
	}
	function rgb3_to_rgb6(rgb) {
	    if (rgb.length === 7) {
	        return rgb;
	    }
	    else {
	        return '#' + rgb.charAt(1) + rgb.charAt(1) +
	            rgb.charAt(2) + rgb.charAt(2) +
	            rgb.charAt(3) + rgb.charAt(3);
	    }
	}
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_color.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_date.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_date.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	function serialize_date(value) {
	    if (value === null) {
	        return null;
	    }
	    else {
	        return {
	            year: value.getUTCFullYear(),
	            month: value.getUTCMonth(),
	            date: value.getUTCDate()
	        };
	    }
	}
	exports.serialize_date = serialize_date;
	;
	;
	function deserialize_date(value) {
	    if (value === null) {
	        return null;
	    }
	    else {
	        var date = new Date();
	        date.setUTCFullYear(value.year, value.month, value.date);
	        date.setUTCHours(0, 0, 0, 0);
	        return date;
	    }
	}
	exports.deserialize_date = deserialize_date;
	;
	var DatePickerModel = (function (_super) {
	    __extends(DatePickerModel, _super);
	    function DatePickerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DatePickerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: null,
	            _model_name: 'DatePickerModel',
	            _view_name: 'DatePickerView'
	        });
	    };
	    return DatePickerModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	DatePickerModel.serializers = __assign({}, widget_core_1.CoreLabeledDOMWidgetModel.serializers, { value: {
	        serialize: serialize_date,
	        deserialize: deserialize_date
	    } });
	exports.DatePickerModel = DatePickerModel;
	var DatePickerView = (function (_super) {
	    __extends(DatePickerView, _super);
	    function DatePickerView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DatePickerView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-datepicker');
	        this._datepicker = document.createElement('input');
	        this._datepicker.setAttribute('type', 'date');
	        this.el.appendChild(this._datepicker);
	        this.listenTo(this.model, 'change:value', this._update_value);
	        this._update_value();
	    };
	    DatePickerView.prototype.events = function () {
	        return {
	            'change [type="date"]': '_picker_change',
	        };
	    };
	    DatePickerView.prototype._update_value = function () {
	        var value = this.model.get('value');
	        this._datepicker.valueAsDate = value;
	    };
	    DatePickerView.prototype._picker_change = function () {
	        this.model.set('value', this._datepicker.valueAsDate);
	        this.touch();
	    };
	    return DatePickerView;
	}(widget_1.LabeledDOMWidgetView));
	exports.DatePickerView = DatePickerView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_date.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/services-shim.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/services-shim.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js');
	var shims;
	(function (shims) {
	    var services;
	    (function (services) {
	        /**
	         * Public constructor
	         * @param jsServicesKernel - @jupyterlab/services Kernel.IKernel instance
	         */
	        var CommManager = (function () {
	            function CommManager(jsServicesKernel) {
	                /**
	                 * Register a comm in the mapping
	                 */
	                this.register_comm = function (comm) {
	                    this.comms[comm.comm_id] = Promise.resolve(comm);
	                    comm.kernel = this.kernel;
	                    return comm.comm_id;
	                };
	                this.targets = Object.create(null);
	                this.comms = Object.create(null);
	                this.kernel = null;
	                this.jsServicesKernel = null;
	                this.init_kernel(jsServicesKernel);
	            }
	            ;
	            /**
	             * Hookup kernel events.
	             * @param  {Kernel.IKernel} jsServicesKernel - @jupyterlab/services Kernel.IKernel instance
	             */
	            CommManager.prototype.init_kernel = function (jsServicesKernel) {
	                this.kernel = jsServicesKernel; // These aren't really the same.
	                this.jsServicesKernel = jsServicesKernel;
	            };
	            ;
	            /**
	             * Creates a new connected comm
	             * @param  {string} target_name
	             * @param  {object} data
	             * @param  {object} callbacks
	             * @param  {object} metadata
	             * @param  {string} comm_id
	             * @return {Comm}
	             */
	            CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata, comm_id) {
	                var comm = new Comm(this.jsServicesKernel.connectToComm(target_name, comm_id));
	                this.register_comm(comm);
	                comm.open(data, callbacks, metadata);
	                return comm;
	            };
	            ;
	            /**
	             * Register a comm target
	             * @param  {string} target_name
	             * @param  {(Comm, object) => void} f - callback that is called when the
	             *                         comm is made.  Signature of f(comm, msg).
	             */
	            CommManager.prototype.register_target = function (target_name, f) {
	                var _this = this;
	                var handle = this.jsServicesKernel.registerCommTarget(target_name, function (jsServicesComm, msg) {
	                    // Create the comm.
	                    var comm = new Comm(jsServicesComm);
	                    _this.register_comm(comm);
	                    // Call the callback for the comm.
	                    try {
	                        return f(comm, msg);
	                    }
	                    catch (e) {
	                        comm.close();
	                        var wrapped_error = new utils.WrappedError('Exception opening new comm', e);
	                        console.error(wrapped_error);
	                        return;
	                    }
	                });
	                this.targets[target_name] = handle;
	            };
	            ;
	            /**
	             * Unregisters a comm target
	             * @param  {string} target_name
	             */
	            CommManager.prototype.unregister_target = function (target_name, f) {
	                var handle = this.targets[target_name];
	                handle.dispose();
	                delete this.targets[target_name];
	            };
	            ;
	            return CommManager;
	        }());
	        services.CommManager = CommManager;
	        /**
	         * Public constructor
	         * @param  {IComm} jsServicesComm - @jupyterlab/services IComm instance
	         */
	        var Comm = (function () {
	            function Comm(jsServicesComm) {
	                this.jsServicesComm = null;
	                this.jsServicesComm = jsServicesComm;
	            }
	            Object.defineProperty(Comm.prototype, "comm_id", {
	                /**
	                 * Comm id
	                 * @return {string}
	                 */
	                get: function () {
	                    return this.jsServicesComm.commId;
	                },
	                enumerable: true,
	                configurable: true
	            });
	            Object.defineProperty(Comm.prototype, "target_name", {
	                /**
	                 * Target name
	                 * @return {string}
	                 */
	                get: function () {
	                    return this.jsServicesComm.targetName;
	                },
	                enumerable: true,
	                configurable: true
	            });
	            /**
	             * Opens a sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @return msg id
	             */
	            Comm.prototype.open = function (data, callbacks, metadata) {
	                var future = this.jsServicesComm.open(data, metadata);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            ;
	            /**
	             * Sends a message to the sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @param  buffers
	             * @return message id
	             */
	            Comm.prototype.send = function (data, callbacks, metadata, buffers) {
	                var future = this.jsServicesComm.send(data, metadata, buffers);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            ;
	            /**
	             * Closes the sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @return msg id
	             */
	            Comm.prototype.close = function (data, callbacks, metadata) {
	                var future = this.jsServicesComm.close(data, metadata);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            ;
	            /**
	             * Register a message handler
	             * @param  callback, which is given a message
	             */
	            Comm.prototype.on_msg = function (callback) {
	                this.jsServicesComm.onMsg = callback.bind(this);
	            };
	            ;
	            /**
	             * Register a handler for when the comm is closed by the backend
	             * @param  callback, which is given a message
	             */
	            Comm.prototype.on_close = function (callback) {
	                this.jsServicesComm.onClose = callback.bind(this);
	            };
	            ;
	            /**
	             * Hooks callback object up with @jupyterlab/services IKernelFuture
	             * @param  @jupyterlab/services IKernelFuture instance
	             * @param  callbacks
	             */
	            Comm.prototype._hookupCallbacks = function (future, callbacks) {
	                if (callbacks) {
	                    future.onReply = function (msg) {
	                        if (callbacks.shell && callbacks.shell.reply)
	                            callbacks.shell.reply(msg);
	                        // TODO: Handle payloads.  See https://github.com/jupyter/notebook/blob/master/notebook/static/services/kernels/kernel.js#L923-L947
	                    };
	                    future.onStdin = function (msg) {
	                        if (callbacks.input)
	                            callbacks.input(msg);
	                    };
	                    future.onIOPub = function (msg) {
	                        if (callbacks.iopub) {
	                            if (callbacks.iopub.status && msg.header.msg_type === 'status') {
	                                callbacks.iopub.status(msg);
	                            }
	                            else if (callbacks.iopub.clear_output && msg.header.msg_type === 'clear_output') {
	                                callbacks.iopub.clear_output(msg);
	                            }
	                            else if (callbacks.iopub.output) {
	                                switch (msg.header.msg_type) {
	                                    case 'display_data':
	                                    case 'execute_result':
	                                        callbacks.iopub.output(msg);
	                                        break;
	                                }
	                                ;
	                            }
	                        }
	                    };
	                }
	            };
	            ;
	            return Comm;
	        }());
	        services.Comm = Comm;
	    })(services = shims.services || (shims.services = {}));
	})(shims = exports.shims || (exports.shims = {}));
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/services-shim.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_int.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_int.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_style_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_style.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	__jupyter_require__('jquery-ui@^1.12.1/ui/widgets/slider.js');
	var d3format = __jupyter_require__('d3-format@^0.5.1/build/d3-format.js').format;
	var IntModel = (function (_super) {
	    __extends(IntModel, _super);
	    function IntModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntModel',
	            value: 0,
	            disabled: false,
	        });
	    };
	    return IntModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.IntModel = IntModel;
	var BoundedIntModel = (function (_super) {
	    __extends(BoundedIntModel, _super);
	    function BoundedIntModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedIntModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'BoundedIntModel',
	            max: 100,
	            min: 0
	        });
	    };
	    return BoundedIntModel;
	}(IntModel));
	exports.BoundedIntModel = BoundedIntModel;
	var SliderStyleModel = (function (_super) {
	    __extends(SliderStyleModel, _super);
	    function SliderStyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SliderStyleModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SliderStyleModel',
	        });
	    };
	    return SliderStyleModel;
	}(widget_style_1.StyleModel));
	SliderStyleModel.styleProperties = {
	    handle_color: {
	        selector: '.ui-slider-handle',
	        attribute: 'background-color',
	        default: null
	    }
	};
	exports.SliderStyleModel = SliderStyleModel;
	var IntSliderModel = (function (_super) {
	    __extends(IntSliderModel, _super);
	    function IntSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntSliderModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntSliderModel',
	            _view_name: 'IntSliderView',
	            step: 1,
	            orientation: 'horizontal',
	            readout: true,
	            readout_format: 'd',
	            continuous_update: true,
	            style: null
	        });
	    };
	    IntSliderModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.on('change:readout_format', this.update_readout_format, this);
	        this.update_readout_format();
	    };
	    IntSliderModel.prototype.update_readout_format = function () {
	        this.readout_formatter = d3format(this.get('readout_format'));
	    };
	    return IntSliderModel;
	}(BoundedIntModel));
	exports.IntSliderModel = IntSliderModel;
	var IntRangeSliderModel = (function (_super) {
	    __extends(IntRangeSliderModel, _super);
	    function IntRangeSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    return IntRangeSliderModel;
	}(IntSliderModel));
	exports.IntRangeSliderModel = IntRangeSliderModel;
	var BaseIntSliderView = (function (_super) {
	    __extends(BaseIntSliderView, _super);
	    function BaseIntSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseInt;
	        return _this;
	    }
	    BaseIntSliderView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-slider');
	        this.el.classList.add('widget-hslider');
	        (this.$slider = $('<div />'))
	            .slider({
	            slide: this.handleSliderChange.bind(this),
	            stop: this.handleSliderChanged.bind(this)
	        })
	            .addClass('slider');
	        // Put the slider in a container
	        this.slider_container = document.createElement('div');
	        this.slider_container.classList.add('slider-container');
	        this.slider_container.appendChild(this.$slider[0]);
	        this.el.appendChild(this.slider_container);
	        this.readout = document.createElement('div');
	        this.el.appendChild(this.readout);
	        this.readout.classList.add('widget-readout');
	        this.readout.contentEditable = 'true';
	        this.readout.style.display = 'none';
	        // Set defaults.
	        this.update();
	    };
	    BaseIntSliderView.prototype.update = function (options) {
	        /**
	         * Update the contents of this view
	         *
	         * Called when the model is changed.  The model may have been
	         * changed by another view or by a state update from the back-end.
	         */
	        if (options === undefined || options.updated_view !== this) {
	            // JQuery slider option keys.  These keys happen to have a
	            // one-to-one mapping with the corresponding keys of the model.
	            var jquery_slider_keys = ['step', 'disabled'];
	            var that_1 = this;
	            that_1.$slider.slider({});
	            _.each(jquery_slider_keys, function (key, i) {
	                var model_value = that_1.model.get(key);
	                if (model_value !== undefined) {
	                    that_1.$slider.slider('option', key, model_value);
	                }
	            });
	            var max = this.model.get('max');
	            var min = this.model.get('min');
	            if (min <= max) {
	                if (max !== undefined)
	                    this.$slider.slider('option', 'max', max);
	                if (min !== undefined)
	                    this.$slider.slider('option', 'min', min);
	            }
	            // WORKAROUND FOR JQUERY SLIDER BUG.
	            // The horizontal position of the slider handle
	            // depends on the value of the slider at the time
	            // of orientation change.  Before applying the new
	            // workaround, we set the value to the minimum to
	            // make sure that the horizontal placement of the
	            // handle in the vertical slider is always
	            // consistent.
	            var orientation_1 = this.model.get('orientation');
	            this.$slider.slider('option', 'orientation', orientation_1);
	            // Use the right CSS classes for vertical & horizontal sliders
	            if (orientation_1 === 'vertical') {
	                this.el.classList.remove('widget-hslider');
	                this.el.classList.add('widget-vslider');
	                this.el.classList.remove('widget-inline-hbox');
	                this.el.classList.add('widget-inline-vbox');
	            }
	            else {
	                this.el.classList.remove('widget-vslider');
	                this.el.classList.add('widget-hslider');
	                this.el.classList.remove('widget-inline-vbox');
	                this.el.classList.add('widget-inline-hbox');
	            }
	            var readout = this.model.get('readout');
	            if (readout) {
	                this.readout.style.display = '';
	                this.displayed.then(function () {
	                    if (that_1.readout_overflow()) {
	                        that_1.readout.classList.add('overflow');
	                    }
	                    else {
	                        that_1.readout.classList.remove('overflow');
	                    }
	                });
	            }
	            else {
	                this.readout.style.display = 'none';
	            }
	        }
	        return _super.prototype.update.call(this);
	    };
	    /**
	     * Returns true if the readout box content overflows.
	     */
	    BaseIntSliderView.prototype.readout_overflow = function () {
	        return this.readout.scrollWidth > this.readout.clientWidth;
	    };
	    BaseIntSliderView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'slide': 'handleSliderChange',
	            'slidestop': 'handleSliderChanged',
	            'blur [contentEditable=true]': 'handleTextChange',
	            'keydown [contentEditable=true]': 'handleKeyDown'
	        };
	    };
	    BaseIntSliderView.prototype.handleKeyDown = function (e) {
	        if (e.keyCode === 13) {
	            e.preventDefault();
	            this.handleTextChange();
	        }
	    };
	    /**
	     * Validate the value of the slider before sending it to the back-end
	     * and applying it to the other views on the page.
	     */
	    BaseIntSliderView.prototype._validate_slide_value = function (x) {
	        return Math.floor(x);
	    };
	    return BaseIntSliderView;
	}(widget_1.LabeledDOMWidgetView));
	exports.BaseIntSliderView = BaseIntSliderView;
	var IntRangeSliderView = (function (_super) {
	    __extends(IntRangeSliderView, _super);
	    function IntRangeSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        // range numbers can be separated by a hyphen, colon, or an en-dash
	        _this._range_regex = /^\s*([+-]?\d+)\s*[-:–]\s*([+-]?\d+)/;
	        return _this;
	    }
	    IntRangeSliderView.prototype.update = function (options) {
	        _super.prototype.update.call(this, options);
	        this.$slider.slider('option', 'range', true);
	        // values for the range case are validated python-side in
	        // _Bounded{Int,Float}RangeWidget._validate
	        var value = this.model.get('value');
	        this.$slider.slider('option', 'values', value.slice());
	        this.readout.textContent = this.valueToString(value);
	        if (this.model.get('value') !== value) {
	            this.model.set('value', value, { updated_view: this });
	            this.touch();
	        }
	    };
	    /**
	     * Write value to a string
	     */
	    IntRangeSliderView.prototype.valueToString = function (value) {
	        var format = this.model.readout_formatter;
	        return value.map(function (v) {
	            return format(v);
	        }).join(' – ');
	    };
	    /**
	     * Parse value from a string
	     */
	    IntRangeSliderView.prototype.stringToValue = function (text) {
	        // ranges can be expressed either 'val-val' or 'val:val' (+spaces)
	        var match = this._range_regex.exec(text);
	        if (match) {
	            return [this._parse_value(match[1]), this._parse_value(match[2])];
	        }
	        else {
	            return null;
	        }
	    };
	    /**
	     * this handles the entry of text into the contentEditable label first, the
	     * value is checked if it contains a parseable value then it is clamped
	     * within the min-max range of the slider finally, the model is updated if
	     * the value is to be changed
	     *
	     * if any of these conditions are not met, the text is reset
	     */
	    IntRangeSliderView.prototype.handleTextChange = function () {
	        var value = this.stringToValue(this.readout.textContent);
	        var vmin = this.model.get('min');
	        var vmax = this.model.get('max');
	        // reject input where NaN or lower > upper
	        if (value === null ||
	            isNaN(value[0]) ||
	            isNaN(value[1]) ||
	            (value[0] > value[1])) {
	            this.readout.textContent = this.valueToString(this.model.get('value'));
	        }
	        else {
	            // clamp to range
	            value = [Math.max(Math.min(value[0], vmax), vmin),
	                Math.max(Math.min(value[1], vmax), vmin)];
	            if ((value[0] !== this.model.get('value')[0]) ||
	                (value[1] !== this.model.get('value')[1])) {
	                this.readout.textContent = this.valueToString(value);
	                this.model.set('value', value, { updated_view: this });
	                this.touch();
	            }
	            else {
	                this.readout.textContent = this.valueToString(this.model.get('value'));
	            }
	        }
	    };
	    /**
	     * Called when the slider value is changing.
	     */
	    IntRangeSliderView.prototype.handleSliderChange = function (e, ui) {
	        var actual_value = ui.values.map(this._validate_slide_value);
	        this.readout.textContent = this.valueToString(actual_value);
	        // Only persist the value while sliding if the continuous_update
	        // trait is set to true.
	        if (this.model.get('continuous_update')) {
	            this.handleSliderChanged(e, ui);
	        }
	    };
	    /**
	     * Called when the slider value has changed.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    IntRangeSliderView.prototype.handleSliderChanged = function (e, ui) {
	        var actual_value = ui.values.map(this._validate_slide_value);
	        this.model.set('value', actual_value, { updated_view: this });
	        this.touch();
	    };
	    return IntRangeSliderView;
	}(BaseIntSliderView));
	exports.IntRangeSliderView = IntRangeSliderView;
	var IntSliderView = (function (_super) {
	    __extends(IntSliderView, _super);
	    function IntSliderView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntSliderView.prototype.update = function (options) {
	        _super.prototype.update.call(this, options);
	        var min = this.model.get('min');
	        var max = this.model.get('max');
	        var value = this.model.get('value');
	        if (value > max) {
	            value = max;
	        }
	        else if (value < min) {
	            value = min;
	        }
	        this.$slider.slider('option', 'value', value);
	        this.readout.textContent = this.valueToString(value);
	        if (this.model.get('value') !== value) {
	            this.model.set('value', value, { updated_view: this });
	            this.touch();
	        }
	    };
	    /**
	     * Write value to a string
	     */
	    IntSliderView.prototype.valueToString = function (value) {
	        var format = this.model.readout_formatter;
	        return format(value);
	    };
	    /**
	     * Parse value from a string
	     */
	    IntSliderView.prototype.stringToValue = function (text) {
	        return this._parse_value(text);
	    };
	    /**
	     * this handles the entry of text into the contentEditable label first, the
	     * value is checked if it contains a parseable value then it is clamped
	     * within the min-max range of the slider finally, the model is updated if
	     * the value is to be changed
	     *
	     * if any of these conditions are not met, the text is reset
	     */
	    IntSliderView.prototype.handleTextChange = function () {
	        var value = this.stringToValue(this.readout.textContent);
	        var vmin = this.model.get('min');
	        var vmax = this.model.get('max');
	        if (isNaN(value)) {
	            this.readout.textContent = this.valueToString(this.model.get('value'));
	        }
	        else {
	            value = Math.max(Math.min(value, vmax), vmin);
	            if (value !== this.model.get('value')) {
	                this.readout.textContent = this.valueToString(value);
	                this.model.set('value', value, { updated_view: this });
	                this.touch();
	            }
	            else {
	                this.readout.textContent = this.valueToString(this.model.get('value'));
	            }
	        }
	    };
	    /**
	     * Called when the slider value is changing.
	     */
	    IntSliderView.prototype.handleSliderChange = function (e, ui) {
	        var actual_value = this._validate_slide_value(ui.value);
	        this.readout.textContent = this.valueToString(actual_value);
	        // Only persist the value while sliding if the continuous_update
	        // trait is set to true.
	        if (this.model.get('continuous_update')) {
	            this.handleSliderChanged(e, ui);
	        }
	    };
	    /**
	     * Called when the slider value has changed.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    IntSliderView.prototype.handleSliderChanged = function (e, ui) {
	        var actual_value = this._validate_slide_value(ui.value);
	        this.model.set('value', actual_value, { updated_view: this });
	        this.touch();
	    };
	    return IntSliderView;
	}(BaseIntSliderView));
	exports.IntSliderView = IntSliderView;
	var IntTextModel = (function (_super) {
	    __extends(IntTextModel, _super);
	    function IntTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntTextModel',
	            _view_name: 'IntTextView'
	        });
	    };
	    return IntTextModel;
	}(IntModel));
	exports.IntTextModel = IntTextModel;
	var BoundedIntTextModel = (function (_super) {
	    __extends(BoundedIntTextModel, _super);
	    function BoundedIntTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedIntTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'BoundedIntTextModel',
	            _view_name: 'IntTextView'
	        });
	    };
	    return BoundedIntTextModel;
	}(BoundedIntModel));
	exports.BoundedIntTextModel = BoundedIntTextModel;
	var IntTextView = (function (_super) {
	    __extends(IntTextView, _super);
	    function IntTextView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseInt;
	        return _this;
	    }
	    IntTextView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-text');
	        this.textbox = document.createElement('input');
	        this.textbox.setAttribute('type', 'text');
	        this.el.appendChild(this.textbox);
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    IntTextView.prototype.update = function (options) {
	        if (options === undefined || options.updated_view !== this) {
	            var value = this.model.get('value');
	            if (this._parse_value(this.textbox.value) !== value) {
	                this.textbox.value = value.toString();
	            }
	            var disabled = this.model.get('disabled');
	            if (disabled) {
	                this.textbox.setAttribute('disabled', disabled);
	            }
	            else {
	                this.textbox.removeAttribute('disabled');
	            }
	        }
	        return _super.prototype.update.call(this);
	    };
	    IntTextView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'keydown input': 'handleKeyDown',
	            'keypress input': 'handleKeypress',
	            'keyup input': 'handleChanging',
	            'paste input': 'handleChanging',
	            'cut input': 'handleChanging',
	            // Fires only when control is validated or looses focus.
	            'change input': 'handleChanged'
	        };
	    };
	    /**
	     * Handle key down
	     *
	     * Stop propagation so the event isn't sent to the application.
	     */
	    IntTextView.prototype.handleKeyDown = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles key press
	     *
	     * Stop propagation so the event isn't sent to the application.
	     */
	    IntTextView.prototype.handleKeypress = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles and validates user input.
	     *
	     * Try to parse value as an int.
	     */
	    IntTextView.prototype.handleChanging = function (e) {
	        var numericalValue = 0;
	        var trimmed = e.target.value.trim();
	        if (trimmed === '') {
	            return;
	        }
	        else {
	            if (!(['-', '-.', '.', '+.', '+'].indexOf(trimmed) >= 0)) {
	                numericalValue = this._parse_value(e.target.value);
	            }
	        }
	        // If parse failed, reset value to value stored in model.
	        if (isNaN(numericalValue)) {
	            e.target.value = this.model.get('value');
	        }
	        else if (!isNaN(numericalValue)) {
	            // Handle both the IntTextModel and the BoundedIntTextModel by
	            // checking to see if the max/min properties are defined
	            if (this.model.get('max') !== undefined) {
	                numericalValue = Math.min(this.model.get('max'), numericalValue);
	            }
	            if (this.model.get('min') !== undefined) {
	                numericalValue = Math.max(this.model.get('min'), numericalValue);
	            }
	            // Apply the value if it has changed.
	            if (numericalValue !== this.model.get('value')) {
	                // Calling model.set will trigger all of the other views of the
	                // model to update.
	                this.model.set('value', numericalValue, { updated_view: this });
	                this.touch();
	            }
	        }
	    };
	    /**
	     * Applies validated input.
	     */
	    IntTextView.prototype.handleChanged = function (e) {
	        if (e.target.value.trim() === '' || e.target.value !== this.model.get('value')) {
	            e.target.value = this.model.get('value');
	        }
	    };
	    return IntTextView;
	}(widget_1.LabeledDOMWidgetView));
	exports.IntTextView = IntTextView;
	var ProgressStyleModel = (function (_super) {
	    __extends(ProgressStyleModel, _super);
	    function ProgressStyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ProgressStyleModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ProgressStyleModel',
	        });
	    };
	    return ProgressStyleModel;
	}(widget_style_1.StyleModel));
	ProgressStyleModel.styleProperties = {
	    bar_color: {
	        selector: '.progress-bar',
	        attribute: 'background-color',
	        default: null
	    }
	};
	exports.ProgressStyleModel = ProgressStyleModel;
	var IntProgressModel = (function (_super) {
	    __extends(IntProgressModel, _super);
	    function IntProgressModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntProgressModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntProgressModel',
	            _view_name: 'ProgressView',
	            orientation: 'horizontal',
	            bar_style: '',
	            style: null
	        });
	    };
	    return IntProgressModel;
	}(BoundedIntModel));
	exports.IntProgressModel = IntProgressModel;
	var ProgressView = (function (_super) {
	    __extends(ProgressView, _super);
	    function ProgressView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ProgressView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.listenTo(this.model, 'change:bar_style', this.update_bar_style);
	        this.pWidget.addClass('jupyter-widgets');
	    };
	    ProgressView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        var orientation = this.model.get('orientation');
	        var className = orientation === 'horizontal' ?
	            'widget-hprogress' : 'widget-vprogress';
	        this.el.classList.add(className);
	        this.progress = document.createElement('div');
	        this.progress.classList.add('progress');
	        this.progress.style.position = 'relative';
	        this.el.appendChild(this.progress);
	        this.bar = document.createElement('div');
	        this.bar.classList.add('progress-bar');
	        this.bar.style.position = 'absolute';
	        this.bar.style.bottom = '0px';
	        this.bar.style.left = '0px';
	        this.progress.appendChild(this.bar);
	        // Set defaults.
	        this.update();
	        this.set_bar_style();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ProgressView.prototype.update = function () {
	        var value = this.model.get('value');
	        var max = this.model.get('max');
	        var min = this.model.get('min');
	        var orientation = this.model.get('orientation');
	        var percent = 100.0 * (value - min) / (max - min);
	        if (orientation === 'horizontal') {
	            this.el.classList.remove('widget-inline-vbox');
	            this.el.classList.remove('widget-vprogress');
	            this.el.classList.add('widget-inline-hbox');
	            this.el.classList.add('widget-hprogress');
	            this.bar.style.width = percent + '%';
	            this.bar.style.height = '100%';
	        }
	        else {
	            this.el.classList.remove('widget-inline-hbox');
	            this.el.classList.remove('widget-hprogress');
	            this.el.classList.add('widget-inline-vbox');
	            this.el.classList.add('widget-vprogress');
	            this.bar.style.width = '100%';
	            this.bar.style.height = percent + '%';
	        }
	        return _super.prototype.update.call(this);
	    };
	    ProgressView.prototype.update_bar_style = function () {
	        this.update_mapped_classes(ProgressView.class_map, 'bar_style', this.bar);
	    };
	    ProgressView.prototype.set_bar_style = function () {
	        this.set_mapped_classes(ProgressView.class_map, 'bar_style', this.bar);
	    };
	    return ProgressView;
	}(widget_1.LabeledDOMWidgetView));
	ProgressView.class_map = {
	    success: ['progress-bar-success'],
	    info: ['progress-bar-info'],
	    warning: ['progress-bar-warning'],
	    danger: ['progress-bar-danger']
	};
	exports.ProgressView = ProgressView;
	var PlayModel = (function (_super) {
	    __extends(PlayModel, _super);
	    function PlayModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    PlayModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'PlayModel',
	            _view_name: 'PlayView',
	            _playing: false,
	            _repeat: false,
	            show_repeat: true,
	            interval: 100,
	            step: 1,
	        });
	    };
	    PlayModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	    };
	    PlayModel.prototype.loop = function () {
	        if (this.get('_playing')) {
	            var next_value = this.get('value') + this.get('step');
	            if (next_value <= this.get('max')) {
	                this.set('value', next_value);
	                this.schedule_next();
	            }
	            else {
	                if (this.get('_repeat')) {
	                    this.set('value', this.get('min'));
	                    this.schedule_next();
	                }
	                else {
	                    this.set('_playing', false);
	                }
	            }
	            this.save_changes();
	        }
	    };
	    PlayModel.prototype.schedule_next = function () {
	        window.setTimeout(this.loop.bind(this), this.get('interval'));
	    };
	    PlayModel.prototype.stop = function () {
	        this.set('_playing', false);
	        this.set('value', this.get('min'));
	        this.save_changes();
	    };
	    PlayModel.prototype.pause = function () {
	        this.set('_playing', false);
	        this.save_changes();
	    };
	    PlayModel.prototype.play = function () {
	        this.set('_playing', true);
	        if (this.get('value') == this.get('max')) {
	            // if the value is at the end, reset if first, and then schedule the next
	            this.set('value', this.get('min'));
	            this.schedule_next();
	            this.save_changes();
	        }
	        else {
	            // otherwise directly start with the next value
	            // loop will call save_changes in this case
	            this.loop();
	        }
	    };
	    PlayModel.prototype.repeat = function () {
	        this.set('_repeat', !this.get('_repeat'));
	        this.save_changes();
	    };
	    return PlayModel;
	}(BoundedIntModel));
	exports.PlayModel = PlayModel;
	var PlayView = (function (_super) {
	    __extends(PlayView, _super);
	    function PlayView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    PlayView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-play');
	        this.playButton = document.createElement('button');
	        this.pauseButton = document.createElement('button');
	        this.stopButton = document.createElement('button');
	        this.repeatButton = document.createElement('button');
	        this.playButton.className = 'jupyter-button';
	        this.pauseButton.className = 'jupyter-button';
	        this.stopButton.className = 'jupyter-button';
	        this.repeatButton.className = 'jupyter-button';
	        this.el.appendChild(this.playButton); // Toggle button with playing
	        this.el.appendChild(this.pauseButton); // Disable if not playing
	        this.el.appendChild(this.stopButton); // Disable if not playing
	        this.el.appendChild(this.repeatButton); // Always enabled, but may be hidden
	        var playIcon = document.createElement('i');
	        playIcon.className = 'fa fa-play';
	        this.playButton.appendChild(playIcon);
	        var pauseIcon = document.createElement('i');
	        pauseIcon.className = 'fa fa-pause';
	        this.pauseButton.appendChild(pauseIcon);
	        var stopIcon = document.createElement('i');
	        stopIcon.className = 'fa fa-stop';
	        this.stopButton.appendChild(stopIcon);
	        var repeatIcon = document.createElement('i');
	        repeatIcon.className = 'fa fa-retweet';
	        this.repeatButton.appendChild(repeatIcon);
	        this.playButton.onclick = this.model.play.bind(this.model);
	        this.pauseButton.onclick = this.model.pause.bind(this.model);
	        this.stopButton.onclick = this.model.stop.bind(this.model);
	        this.repeatButton.onclick = this.model.repeat.bind(this.model);
	        this.listenTo(this.model, 'change:_playing', this.update_playing);
	        this.listenTo(this.model, 'change:_repeat', this.update_repeat);
	        this.listenTo(this.model, 'change:show_repeat', this.update_repeat);
	        this.update_playing();
	        this.update_repeat();
	    };
	    PlayView.prototype.update_playing = function () {
	        var playing = this.model.get('_playing');
	        if (playing) {
	            this.pauseButton.disabled = false;
	            this.playButton.classList.add('mod-active');
	        }
	        else {
	            this.pauseButton.disabled = true;
	            this.playButton.classList.remove('mod-active');
	        }
	    };
	    PlayView.prototype.update_repeat = function () {
	        var repeat = this.model.get('_repeat');
	        this.repeatButton.style.display = this.model.get('show_repeat') ? this.playButton.style.display : 'none';
	        if (repeat) {
	            this.repeatButton.classList.add('mod-active');
	        }
	        else {
	            this.repeatButton.classList.remove('mod-active');
	        }
	    };
	    return PlayView;
	}(widget_1.DOMWidgetView));
	exports.PlayView = PlayView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_int.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/slider.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/slider.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Slider 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Slider
	//>>group: Widgets
	//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
	//>>docs: http://api.jqueryui.com/slider/
	//>>demos: http://jqueryui.com/slider/
	//>>css.structure: ../../themes/base/core.css
	//>>css.structure: ../../themes/base/slider.css
	//>>css.theme: ../../themes/base/theme.css
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/mouse.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/keycode.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/version.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	return $.widget( "ui.slider", $.ui.mouse, {
		version: "1.12.1",
		widgetEventPrefix: "slide",
	
		options: {
			animate: false,
			classes: {
				"ui-slider": "ui-corner-all",
				"ui-slider-handle": "ui-corner-all",
	
				// Note: ui-widget-header isn't the most fittingly semantic framework class for this
				// element, but worked best visually with a variety of themes
				"ui-slider-range": "ui-corner-all ui-widget-header"
			},
			distance: 0,
			max: 100,
			min: 0,
			orientation: "horizontal",
			range: false,
			step: 1,
			value: 0,
			values: null,
	
			// Callbacks
			change: null,
			slide: null,
			start: null,
			stop: null
		},
	
		// Number of pages in a slider
		// (how many times can you page up/down to go through the whole range)
		numPages: 5,
	
		_create: function() {
			this._keySliding = false;
			this._mouseSliding = false;
			this._animateOff = true;
			this._handleIndex = null;
			this._detectOrientation();
			this._mouseInit();
			this._calculateNewMax();
	
			this._addClass( "ui-slider ui-slider-" + this.orientation,
				"ui-widget ui-widget-content" );
	
			this._refresh();
	
			this._animateOff = false;
		},
	
		_refresh: function() {
			this._createRange();
			this._createHandles();
			this._setupEvents();
			this._refreshValue();
		},
	
		_createHandles: function() {
			var i, handleCount,
				options = this.options,
				existingHandles = this.element.find( ".ui-slider-handle" ),
				handle = "<span tabindex='0'></span>",
				handles = [];
	
			handleCount = ( options.values && options.values.length ) || 1;
	
			if ( existingHandles.length > handleCount ) {
				existingHandles.slice( handleCount ).remove();
				existingHandles = existingHandles.slice( 0, handleCount );
			}
	
			for ( i = existingHandles.length; i < handleCount; i++ ) {
				handles.push( handle );
			}
	
			this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
	
			this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
	
			this.handle = this.handles.eq( 0 );
	
			this.handles.each( function( i ) {
				$( this )
					.data( "ui-slider-handle-index", i )
					.attr( "tabIndex", 0 );
			} );
		},
	
		_createRange: function() {
			var options = this.options;
	
			if ( options.range ) {
				if ( options.range === true ) {
					if ( !options.values ) {
						options.values = [ this._valueMin(), this._valueMin() ];
					} else if ( options.values.length && options.values.length !== 2 ) {
						options.values = [ options.values[ 0 ], options.values[ 0 ] ];
					} else if ( $.isArray( options.values ) ) {
						options.values = options.values.slice( 0 );
					}
				}
	
				if ( !this.range || !this.range.length ) {
					this.range = $( "<div>" )
						.appendTo( this.element );
	
					this._addClass( this.range, "ui-slider-range" );
				} else {
					this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
	
					// Handle range switching from true to min/max
					this.range.css( {
						"left": "",
						"bottom": ""
					} );
				}
				if ( options.range === "min" || options.range === "max" ) {
					this._addClass( this.range, "ui-slider-range-" + options.range );
				}
			} else {
				if ( this.range ) {
					this.range.remove();
				}
				this.range = null;
			}
		},
	
		_setupEvents: function() {
			this._off( this.handles );
			this._on( this.handles, this._handleEvents );
			this._hoverable( this.handles );
			this._focusable( this.handles );
		},
	
		_destroy: function() {
			this.handles.remove();
			if ( this.range ) {
				this.range.remove();
			}
	
			this._mouseDestroy();
		},
	
		_mouseCapture: function( event ) {
			var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
				that = this,
				o = this.options;
	
			if ( o.disabled ) {
				return false;
			}
	
			this.elementSize = {
				width: this.element.outerWidth(),
				height: this.element.outerHeight()
			};
			this.elementOffset = this.element.offset();
	
			position = { x: event.pageX, y: event.pageY };
			normValue = this._normValueFromMouse( position );
			distance = this._valueMax() - this._valueMin() + 1;
			this.handles.each( function( i ) {
				var thisDistance = Math.abs( normValue - that.values( i ) );
				if ( ( distance > thisDistance ) ||
					( distance === thisDistance &&
						( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
					distance = thisDistance;
					closestHandle = $( this );
					index = i;
				}
			} );
	
			allowed = this._start( event, index );
			if ( allowed === false ) {
				return false;
			}
			this._mouseSliding = true;
	
			this._handleIndex = index;
	
			this._addClass( closestHandle, null, "ui-state-active" );
			closestHandle.trigger( "focus" );
	
			offset = closestHandle.offset();
			mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
			this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
				left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
				top: event.pageY - offset.top -
					( closestHandle.height() / 2 ) -
					( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
					( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
					( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
			};
	
			if ( !this.handles.hasClass( "ui-state-hover" ) ) {
				this._slide( event, index, normValue );
			}
			this._animateOff = true;
			return true;
		},
	
		_mouseStart: function() {
			return true;
		},
	
		_mouseDrag: function( event ) {
			var position = { x: event.pageX, y: event.pageY },
				normValue = this._normValueFromMouse( position );
	
			this._slide( event, this._handleIndex, normValue );
	
			return false;
		},
	
		_mouseStop: function( event ) {
			this._removeClass( this.handles, null, "ui-state-active" );
			this._mouseSliding = false;
	
			this._stop( event, this._handleIndex );
			this._change( event, this._handleIndex );
	
			this._handleIndex = null;
			this._clickOffset = null;
			this._animateOff = false;
	
			return false;
		},
	
		_detectOrientation: function() {
			this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
		},
	
		_normValueFromMouse: function( position ) {
			var pixelTotal,
				pixelMouse,
				percentMouse,
				valueTotal,
				valueMouse;
	
			if ( this.orientation === "horizontal" ) {
				pixelTotal = this.elementSize.width;
				pixelMouse = position.x - this.elementOffset.left -
					( this._clickOffset ? this._clickOffset.left : 0 );
			} else {
				pixelTotal = this.elementSize.height;
				pixelMouse = position.y - this.elementOffset.top -
					( this._clickOffset ? this._clickOffset.top : 0 );
			}
	
			percentMouse = ( pixelMouse / pixelTotal );
			if ( percentMouse > 1 ) {
				percentMouse = 1;
			}
			if ( percentMouse < 0 ) {
				percentMouse = 0;
			}
			if ( this.orientation === "vertical" ) {
				percentMouse = 1 - percentMouse;
			}
	
			valueTotal = this._valueMax() - this._valueMin();
			valueMouse = this._valueMin() + percentMouse * valueTotal;
	
			return this._trimAlignValue( valueMouse );
		},
	
		_uiHash: function( index, value, values ) {
			var uiHash = {
				handle: this.handles[ index ],
				handleIndex: index,
				value: value !== undefined ? value : this.value()
			};
	
			if ( this._hasMultipleValues() ) {
				uiHash.value = value !== undefined ? value : this.values( index );
				uiHash.values = values || this.values();
			}
	
			return uiHash;
		},
	
		_hasMultipleValues: function() {
			return this.options.values && this.options.values.length;
		},
	
		_start: function( event, index ) {
			return this._trigger( "start", event, this._uiHash( index ) );
		},
	
		_slide: function( event, index, newVal ) {
			var allowed, otherVal,
				currentValue = this.value(),
				newValues = this.values();
	
			if ( this._hasMultipleValues() ) {
				otherVal = this.values( index ? 0 : 1 );
				currentValue = this.values( index );
	
				if ( this.options.values.length === 2 && this.options.range === true ) {
					newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
				}
	
				newValues[ index ] = newVal;
			}
	
			if ( newVal === currentValue ) {
				return;
			}
	
			allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
	
			// A slide can be canceled by returning false from the slide callback
			if ( allowed === false ) {
				return;
			}
	
			if ( this._hasMultipleValues() ) {
				this.values( index, newVal );
			} else {
				this.value( newVal );
			}
		},
	
		_stop: function( event, index ) {
			this._trigger( "stop", event, this._uiHash( index ) );
		},
	
		_change: function( event, index ) {
			if ( !this._keySliding && !this._mouseSliding ) {
	
				//store the last changed value index for reference when handles overlap
				this._lastChangedValue = index;
				this._trigger( "change", event, this._uiHash( index ) );
			}
		},
	
		value: function( newValue ) {
			if ( arguments.length ) {
				this.options.value = this._trimAlignValue( newValue );
				this._refreshValue();
				this._change( null, 0 );
				return;
			}
	
			return this._value();
		},
	
		values: function( index, newValue ) {
			var vals,
				newValues,
				i;
	
			if ( arguments.length > 1 ) {
				this.options.values[ index ] = this._trimAlignValue( newValue );
				this._refreshValue();
				this._change( null, index );
				return;
			}
	
			if ( arguments.length ) {
				if ( $.isArray( arguments[ 0 ] ) ) {
					vals = this.options.values;
					newValues = arguments[ 0 ];
					for ( i = 0; i < vals.length; i += 1 ) {
						vals[ i ] = this._trimAlignValue( newValues[ i ] );
						this._change( null, i );
					}
					this._refreshValue();
				} else {
					if ( this._hasMultipleValues() ) {
						return this._values( index );
					} else {
						return this.value();
					}
				}
			} else {
				return this._values();
			}
		},
	
		_setOption: function( key, value ) {
			var i,
				valsLength = 0;
	
			if ( key === "range" && this.options.range === true ) {
				if ( value === "min" ) {
					this.options.value = this._values( 0 );
					this.options.values = null;
				} else if ( value === "max" ) {
					this.options.value = this._values( this.options.values.length - 1 );
					this.options.values = null;
				}
			}
	
			if ( $.isArray( this.options.values ) ) {
				valsLength = this.options.values.length;
			}
	
			this._super( key, value );
	
			switch ( key ) {
				case "orientation":
					this._detectOrientation();
					this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
						._addClass( "ui-slider-" + this.orientation );
					this._refreshValue();
					if ( this.options.range ) {
						this._refreshRange( value );
					}
	
					// Reset positioning from previous orientation
					this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
					break;
				case "value":
					this._animateOff = true;
					this._refreshValue();
					this._change( null, 0 );
					this._animateOff = false;
					break;
				case "values":
					this._animateOff = true;
					this._refreshValue();
	
					// Start from the last handle to prevent unreachable handles (#9046)
					for ( i = valsLength - 1; i >= 0; i-- ) {
						this._change( null, i );
					}
					this._animateOff = false;
					break;
				case "step":
				case "min":
				case "max":
					this._animateOff = true;
					this._calculateNewMax();
					this._refreshValue();
					this._animateOff = false;
					break;
				case "range":
					this._animateOff = true;
					this._refresh();
					this._animateOff = false;
					break;
			}
		},
	
		_setOptionDisabled: function( value ) {
			this._super( value );
	
			this._toggleClass( null, "ui-state-disabled", !!value );
		},
	
		//internal value getter
		// _value() returns value trimmed by min and max, aligned by step
		_value: function() {
			var val = this.options.value;
			val = this._trimAlignValue( val );
	
			return val;
		},
	
		//internal values getter
		// _values() returns array of values trimmed by min and max, aligned by step
		// _values( index ) returns single value trimmed by min and max, aligned by step
		_values: function( index ) {
			var val,
				vals,
				i;
	
			if ( arguments.length ) {
				val = this.options.values[ index ];
				val = this._trimAlignValue( val );
	
				return val;
			} else if ( this._hasMultipleValues() ) {
	
				// .slice() creates a copy of the array
				// this copy gets trimmed by min and max and then returned
				vals = this.options.values.slice();
				for ( i = 0; i < vals.length; i += 1 ) {
					vals[ i ] = this._trimAlignValue( vals[ i ] );
				}
	
				return vals;
			} else {
				return [];
			}
		},
	
		// Returns the step-aligned value that val is closest to, between (inclusive) min and max
		_trimAlignValue: function( val ) {
			if ( val <= this._valueMin() ) {
				return this._valueMin();
			}
			if ( val >= this._valueMax() ) {
				return this._valueMax();
			}
			var step = ( this.options.step > 0 ) ? this.options.step : 1,
				valModStep = ( val - this._valueMin() ) % step,
				alignValue = val - valModStep;
	
			if ( Math.abs( valModStep ) * 2 >= step ) {
				alignValue += ( valModStep > 0 ) ? step : ( -step );
			}
	
			// Since JavaScript has problems with large floats, round
			// the final value to 5 digits after the decimal point (see #4124)
			return parseFloat( alignValue.toFixed( 5 ) );
		},
	
		_calculateNewMax: function() {
			var max = this.options.max,
				min = this._valueMin(),
				step = this.options.step,
				aboveMin = Math.round( ( max - min ) / step ) * step;
			max = aboveMin + min;
			if ( max > this.options.max ) {
	
				//If max is not divisible by step, rounding off may increase its value
				max -= step;
			}
			this.max = parseFloat( max.toFixed( this._precision() ) );
		},
	
		_precision: function() {
			var precision = this._precisionOf( this.options.step );
			if ( this.options.min !== null ) {
				precision = Math.max( precision, this._precisionOf( this.options.min ) );
			}
			return precision;
		},
	
		_precisionOf: function( num ) {
			var str = num.toString(),
				decimal = str.indexOf( "." );
			return decimal === -1 ? 0 : str.length - decimal - 1;
		},
	
		_valueMin: function() {
			return this.options.min;
		},
	
		_valueMax: function() {
			return this.max;
		},
	
		_refreshRange: function( orientation ) {
			if ( orientation === "vertical" ) {
				this.range.css( { "width": "", "left": "" } );
			}
			if ( orientation === "horizontal" ) {
				this.range.css( { "height": "", "bottom": "" } );
			}
		},
	
		_refreshValue: function() {
			var lastValPercent, valPercent, value, valueMin, valueMax,
				oRange = this.options.range,
				o = this.options,
				that = this,
				animate = ( !this._animateOff ) ? o.animate : false,
				_set = {};
	
			if ( this._hasMultipleValues() ) {
				this.handles.each( function( i ) {
					valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
						that._valueMin() ) * 100;
					_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
					$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
					if ( that.options.range === true ) {
						if ( that.orientation === "horizontal" ) {
							if ( i === 0 ) {
								that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
									left: valPercent + "%"
								}, o.animate );
							}
							if ( i === 1 ) {
								that.range[ animate ? "animate" : "css" ]( {
									width: ( valPercent - lastValPercent ) + "%"
								}, {
									queue: false,
									duration: o.animate
								} );
							}
						} else {
							if ( i === 0 ) {
								that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
									bottom: ( valPercent ) + "%"
								}, o.animate );
							}
							if ( i === 1 ) {
								that.range[ animate ? "animate" : "css" ]( {
									height: ( valPercent - lastValPercent ) + "%"
								}, {
									queue: false,
									duration: o.animate
								} );
							}
						}
					}
					lastValPercent = valPercent;
				} );
			} else {
				value = this.value();
				valueMin = this._valueMin();
				valueMax = this._valueMax();
				valPercent = ( valueMax !== valueMin ) ?
						( value - valueMin ) / ( valueMax - valueMin ) * 100 :
						0;
				_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
				this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
	
				if ( oRange === "min" && this.orientation === "horizontal" ) {
					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
						width: valPercent + "%"
					}, o.animate );
				}
				if ( oRange === "max" && this.orientation === "horizontal" ) {
					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
						width: ( 100 - valPercent ) + "%"
					}, o.animate );
				}
				if ( oRange === "min" && this.orientation === "vertical" ) {
					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
						height: valPercent + "%"
					}, o.animate );
				}
				if ( oRange === "max" && this.orientation === "vertical" ) {
					this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
						height: ( 100 - valPercent ) + "%"
					}, o.animate );
				}
			}
		},
	
		_handleEvents: {
			keydown: function( event ) {
				var allowed, curVal, newVal, step,
					index = $( event.target ).data( "ui-slider-handle-index" );
	
				switch ( event.keyCode ) {
					case $.ui.keyCode.HOME:
					case $.ui.keyCode.END:
					case $.ui.keyCode.PAGE_UP:
					case $.ui.keyCode.PAGE_DOWN:
					case $.ui.keyCode.UP:
					case $.ui.keyCode.RIGHT:
					case $.ui.keyCode.DOWN:
					case $.ui.keyCode.LEFT:
						event.preventDefault();
						if ( !this._keySliding ) {
							this._keySliding = true;
							this._addClass( $( event.target ), null, "ui-state-active" );
							allowed = this._start( event, index );
							if ( allowed === false ) {
								return;
							}
						}
						break;
				}
	
				step = this.options.step;
				if ( this._hasMultipleValues() ) {
					curVal = newVal = this.values( index );
				} else {
					curVal = newVal = this.value();
				}
	
				switch ( event.keyCode ) {
					case $.ui.keyCode.HOME:
						newVal = this._valueMin();
						break;
					case $.ui.keyCode.END:
						newVal = this._valueMax();
						break;
					case $.ui.keyCode.PAGE_UP:
						newVal = this._trimAlignValue(
							curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
						);
						break;
					case $.ui.keyCode.PAGE_DOWN:
						newVal = this._trimAlignValue(
							curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
						break;
					case $.ui.keyCode.UP:
					case $.ui.keyCode.RIGHT:
						if ( curVal === this._valueMax() ) {
							return;
						}
						newVal = this._trimAlignValue( curVal + step );
						break;
					case $.ui.keyCode.DOWN:
					case $.ui.keyCode.LEFT:
						if ( curVal === this._valueMin() ) {
							return;
						}
						newVal = this._trimAlignValue( curVal - step );
						break;
				}
	
				this._slide( event, index, newVal );
			},
			keyup: function( event ) {
				var index = $( event.target ).data( "ui-slider-handle-index" );
	
				if ( this._keySliding ) {
					this._keySliding = false;
					this._stop( event, index );
					this._change( event, index );
					this._removeClass( $( event.target ), null, "ui-state-active" );
				}
			}
		}
	} );
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/slider.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/mouse.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/mouse.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Mouse 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Mouse
	//>>group: Widgets
	//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
	//>>docs: http://api.jqueryui.com/mouse/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/ie.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/version.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	var mouseHandled = false;
	$( document ).on( "mouseup", function() {
		mouseHandled = false;
	} );
	
	return $.widget( "ui.mouse", {
		version: "1.12.1",
		options: {
			cancel: "input, textarea, button, select, option",
			distance: 1,
			delay: 0
		},
		_mouseInit: function() {
			var that = this;
	
			this.element
				.on( "mousedown." + this.widgetName, function( event ) {
					return that._mouseDown( event );
				} )
				.on( "click." + this.widgetName, function( event ) {
					if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
						$.removeData( event.target, that.widgetName + ".preventClickEvent" );
						event.stopImmediatePropagation();
						return false;
					}
				} );
	
			this.started = false;
		},
	
		// TODO: make sure destroying one instance of mouse doesn't mess with
		// other instances of mouse
		_mouseDestroy: function() {
			this.element.off( "." + this.widgetName );
			if ( this._mouseMoveDelegate ) {
				this.document
					.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
					.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
			}
		},
	
		_mouseDown: function( event ) {
	
			// don't let more than one widget handle mouseStart
			if ( mouseHandled ) {
				return;
			}
	
			this._mouseMoved = false;
	
			// We may have missed mouseup (out of window)
			( this._mouseStarted && this._mouseUp( event ) );
	
			this._mouseDownEvent = event;
	
			var that = this,
				btnIsLeft = ( event.which === 1 ),
	
				// event.target.nodeName works around a bug in IE 8 with
				// disabled inputs (#7620)
				elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
					$( event.target ).closest( this.options.cancel ).length : false );
			if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
				return true;
			}
	
			this.mouseDelayMet = !this.options.delay;
			if ( !this.mouseDelayMet ) {
				this._mouseDelayTimer = setTimeout( function() {
					that.mouseDelayMet = true;
				}, this.options.delay );
			}
	
			if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
				this._mouseStarted = ( this._mouseStart( event ) !== false );
				if ( !this._mouseStarted ) {
					event.preventDefault();
					return true;
				}
			}
	
			// Click event may never have fired (Gecko & Opera)
			if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
				$.removeData( event.target, this.widgetName + ".preventClickEvent" );
			}
	
			// These delegates are required to keep context
			this._mouseMoveDelegate = function( event ) {
				return that._mouseMove( event );
			};
			this._mouseUpDelegate = function( event ) {
				return that._mouseUp( event );
			};
	
			this.document
				.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
				.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
	
			event.preventDefault();
	
			mouseHandled = true;
			return true;
		},
	
		_mouseMove: function( event ) {
	
			// Only check for mouseups outside the document if you've moved inside the document
			// at least once. This prevents the firing of mouseup in the case of IE<9, which will
			// fire a mousemove event if content is placed under the cursor. See #7778
			// Support: IE <9
			if ( this._mouseMoved ) {
	
				// IE mouseup check - mouseup happened when mouse was out of window
				if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
						!event.button ) {
					return this._mouseUp( event );
	
				// Iframe mouseup check - mouseup occurred in another document
				} else if ( !event.which ) {
	
					// Support: Safari <=8 - 9
					// Safari sets which to 0 if you press any of the following keys
					// during a drag (#14461)
					if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
							event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
						this.ignoreMissingWhich = true;
					} else if ( !this.ignoreMissingWhich ) {
						return this._mouseUp( event );
					}
				}
			}
	
			if ( event.which || event.button ) {
				this._mouseMoved = true;
			}
	
			if ( this._mouseStarted ) {
				this._mouseDrag( event );
				return event.preventDefault();
			}
	
			if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
				this._mouseStarted =
					( this._mouseStart( this._mouseDownEvent, event ) !== false );
				( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
			}
	
			return !this._mouseStarted;
		},
	
		_mouseUp: function( event ) {
			this.document
				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
	
			if ( this._mouseStarted ) {
				this._mouseStarted = false;
	
				if ( event.target === this._mouseDownEvent.target ) {
					$.data( event.target, this.widgetName + ".preventClickEvent", true );
				}
	
				this._mouseStop( event );
			}
	
			if ( this._mouseDelayTimer ) {
				clearTimeout( this._mouseDelayTimer );
				delete this._mouseDelayTimer;
			}
	
			this.ignoreMissingWhich = false;
			mouseHandled = false;
			event.preventDefault();
		},
	
		_mouseDistanceMet: function( event ) {
			return ( Math.max(
					Math.abs( this._mouseDownEvent.pageX - event.pageX ),
					Math.abs( this._mouseDownEvent.pageY - event.pageY )
				) >= this.options.distance
			);
		},
	
		_mouseDelayMet: function( /* event */ ) {
			return this.mouseDelayMet;
		},
	
		// These are placeholder methods, to be overriden by extending plugin
		_mouseStart: function( /* event */ ) {},
		_mouseDrag: function( /* event */ ) {},
		_mouseStop: function( /* event */ ) {},
		_mouseCapture: function( /* event */ ) { return true; }
	} );
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/mouse.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/ie.js **/
jupyter.define('jquery-ui@1.12.1/ui/ie.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	// This file is deprecated
	return $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/ie.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/version.js **/
jupyter.define('jquery-ui@1.12.1/ui/version.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	$.ui = $.ui || {};
	
	return $.ui.version = "1.12.1";
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/version.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widget.js **/
jupyter.define('jquery-ui@1.12.1/ui/widget.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Widget 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Widget
	//>>group: Core
	//>>description: Provides a factory for creating stateful widgets with a common API.
	//>>docs: http://api.jqueryui.com/jQuery.widget/
	//>>demos: http://jqueryui.com/widget/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	var widgetUuid = 0;
	var widgetSlice = Array.prototype.slice;
	
	$.cleanData = ( function( orig ) {
		return function( elems ) {
			var events, elem, i;
			for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
				try {
	
					// Only trigger remove when necessary to save time
					events = $._data( elem, "events" );
					if ( events && events.remove ) {
						$( elem ).triggerHandler( "remove" );
					}
	
				// Http://bugs.jquery.com/ticket/8235
				} catch ( e ) {}
			}
			orig( elems );
		};
	} )( $.cleanData );
	
	$.widget = function( name, base, prototype ) {
		var existingConstructor, constructor, basePrototype;
	
		// ProxiedPrototype allows the provided prototype to remain unmodified
		// so that it can be used as a mixin for multiple widgets (#8876)
		var proxiedPrototype = {};
	
		var namespace = name.split( "." )[ 0 ];
		name = name.split( "." )[ 1 ];
		var fullName = namespace + "-" + name;
	
		if ( !prototype ) {
			prototype = base;
			base = $.Widget;
		}
	
		if ( $.isArray( prototype ) ) {
			prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
		}
	
		// Create selector for plugin
		$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
			return !!$.data( elem, fullName );
		};
	
		$[ namespace ] = $[ namespace ] || {};
		existingConstructor = $[ namespace ][ name ];
		constructor = $[ namespace ][ name ] = function( options, element ) {
	
			// Allow instantiation without "new" keyword
			if ( !this._createWidget ) {
				return new constructor( options, element );
			}
	
			// Allow instantiation without initializing for simple inheritance
			// must use "new" keyword (the code above always passes args)
			if ( arguments.length ) {
				this._createWidget( options, element );
			}
		};
	
		// Extend with the existing constructor to carry over any static properties
		$.extend( constructor, existingConstructor, {
			version: prototype.version,
	
			// Copy the object used to create the prototype in case we need to
			// redefine the widget later
			_proto: $.extend( {}, prototype ),
	
			// Track widgets that inherit from this widget in case this widget is
			// redefined after a widget inherits from it
			_childConstructors: []
		} );
	
		basePrototype = new base();
	
		// We need to make the options hash a property directly on the new instance
		// otherwise we'll modify the options hash on the prototype that we're
		// inheriting from
		basePrototype.options = $.widget.extend( {}, basePrototype.options );
		$.each( prototype, function( prop, value ) {
			if ( !$.isFunction( value ) ) {
				proxiedPrototype[ prop ] = value;
				return;
			}
			proxiedPrototype[ prop ] = ( function() {
				function _super() {
					return base.prototype[ prop ].apply( this, arguments );
				}
	
				function _superApply( args ) {
					return base.prototype[ prop ].apply( this, args );
				}
	
				return function() {
					var __super = this._super;
					var __superApply = this._superApply;
					var returnValue;
	
					this._super = _super;
					this._superApply = _superApply;
	
					returnValue = value.apply( this, arguments );
	
					this._super = __super;
					this._superApply = __superApply;
	
					return returnValue;
				};
			} )();
		} );
		constructor.prototype = $.widget.extend( basePrototype, {
	
			// TODO: remove support for widgetEventPrefix
			// always use the name + a colon as the prefix, e.g., draggable:start
			// don't prefix for widgets that aren't DOM-based
			widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
		}, proxiedPrototype, {
			constructor: constructor,
			namespace: namespace,
			widgetName: name,
			widgetFullName: fullName
		} );
	
		// If this widget is being redefined then we need to find all widgets that
		// are inheriting from it and redefine all of them so that they inherit from
		// the new version of this widget. We're essentially trying to replace one
		// level in the prototype chain.
		if ( existingConstructor ) {
			$.each( existingConstructor._childConstructors, function( i, child ) {
				var childPrototype = child.prototype;
	
				// Redefine the child widget using the same prototype that was
				// originally used, but inherit from the new version of the base
				$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
					child._proto );
			} );
	
			// Remove the list of existing child constructors from the old constructor
			// so the old child constructors can be garbage collected
			delete existingConstructor._childConstructors;
		} else {
			base._childConstructors.push( constructor );
		}
	
		$.widget.bridge( name, constructor );
	
		return constructor;
	};
	
	$.widget.extend = function( target ) {
		var input = widgetSlice.call( arguments, 1 );
		var inputIndex = 0;
		var inputLength = input.length;
		var key;
		var value;
	
		for ( ; inputIndex < inputLength; inputIndex++ ) {
			for ( key in input[ inputIndex ] ) {
				value = input[ inputIndex ][ key ];
				if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
	
					// Clone objects
					if ( $.isPlainObject( value ) ) {
						target[ key ] = $.isPlainObject( target[ key ] ) ?
							$.widget.extend( {}, target[ key ], value ) :
	
							// Don't extend strings, arrays, etc. with objects
							$.widget.extend( {}, value );
	
					// Copy everything else by reference
					} else {
						target[ key ] = value;
					}
				}
			}
		}
		return target;
	};
	
	$.widget.bridge = function( name, object ) {
		var fullName = object.prototype.widgetFullName || name;
		$.fn[ name ] = function( options ) {
			var isMethodCall = typeof options === "string";
			var args = widgetSlice.call( arguments, 1 );
			var returnValue = this;
	
			if ( isMethodCall ) {
	
				// If this is an empty collection, we need to have the instance method
				// return undefined instead of the jQuery instance
				if ( !this.length && options === "instance" ) {
					returnValue = undefined;
				} else {
					this.each( function() {
						var methodValue;
						var instance = $.data( this, fullName );
	
						if ( options === "instance" ) {
							returnValue = instance;
							return false;
						}
	
						if ( !instance ) {
							return $.error( "cannot call methods on " + name +
								" prior to initialization; " +
								"attempted to call method '" + options + "'" );
						}
	
						if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
							return $.error( "no such method '" + options + "' for " + name +
								" widget instance" );
						}
	
						methodValue = instance[ options ].apply( instance, args );
	
						if ( methodValue !== instance && methodValue !== undefined ) {
							returnValue = methodValue && methodValue.jquery ?
								returnValue.pushStack( methodValue.get() ) :
								methodValue;
							return false;
						}
					} );
				}
			} else {
	
				// Allow multiple hashes to be passed on init
				if ( args.length ) {
					options = $.widget.extend.apply( null, [ options ].concat( args ) );
				}
	
				this.each( function() {
					var instance = $.data( this, fullName );
					if ( instance ) {
						instance.option( options || {} );
						if ( instance._init ) {
							instance._init();
						}
					} else {
						$.data( this, fullName, new object( options, this ) );
					}
				} );
			}
	
			return returnValue;
		};
	};
	
	$.Widget = function( /* options, element */ ) {};
	$.Widget._childConstructors = [];
	
	$.Widget.prototype = {
		widgetName: "widget",
		widgetEventPrefix: "",
		defaultElement: "<div>",
	
		options: {
			classes: {},
			disabled: false,
	
			// Callbacks
			create: null
		},
	
		_createWidget: function( options, element ) {
			element = $( element || this.defaultElement || this )[ 0 ];
			this.element = $( element );
			this.uuid = widgetUuid++;
			this.eventNamespace = "." + this.widgetName + this.uuid;
	
			this.bindings = $();
			this.hoverable = $();
			this.focusable = $();
			this.classesElementLookup = {};
	
			if ( element !== this ) {
				$.data( element, this.widgetFullName, this );
				this._on( true, this.element, {
					remove: function( event ) {
						if ( event.target === element ) {
							this.destroy();
						}
					}
				} );
				this.document = $( element.style ?
	
					// Element within the document
					element.ownerDocument :
	
					// Element is window or document
					element.document || element );
				this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
			}
	
			this.options = $.widget.extend( {},
				this.options,
				this._getCreateOptions(),
				options );
	
			this._create();
	
			if ( this.options.disabled ) {
				this._setOptionDisabled( this.options.disabled );
			}
	
			this._trigger( "create", null, this._getCreateEventData() );
			this._init();
		},
	
		_getCreateOptions: function() {
			return {};
		},
	
		_getCreateEventData: $.noop,
	
		_create: $.noop,
	
		_init: $.noop,
	
		destroy: function() {
			var that = this;
	
			this._destroy();
			$.each( this.classesElementLookup, function( key, value ) {
				that._removeClass( value, key );
			} );
	
			// We can probably remove the unbind calls in 2.0
			// all event bindings should go through this._on()
			this.element
				.off( this.eventNamespace )
				.removeData( this.widgetFullName );
			this.widget()
				.off( this.eventNamespace )
				.removeAttr( "aria-disabled" );
	
			// Clean up events and states
			this.bindings.off( this.eventNamespace );
		},
	
		_destroy: $.noop,
	
		widget: function() {
			return this.element;
		},
	
		option: function( key, value ) {
			var options = key;
			var parts;
			var curOption;
			var i;
	
			if ( arguments.length === 0 ) {
	
				// Don't return a reference to the internal hash
				return $.widget.extend( {}, this.options );
			}
	
			if ( typeof key === "string" ) {
	
				// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
				options = {};
				parts = key.split( "." );
				key = parts.shift();
				if ( parts.length ) {
					curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
					for ( i = 0; i < parts.length - 1; i++ ) {
						curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
						curOption = curOption[ parts[ i ] ];
					}
					key = parts.pop();
					if ( arguments.length === 1 ) {
						return curOption[ key ] === undefined ? null : curOption[ key ];
					}
					curOption[ key ] = value;
				} else {
					if ( arguments.length === 1 ) {
						return this.options[ key ] === undefined ? null : this.options[ key ];
					}
					options[ key ] = value;
				}
			}
	
			this._setOptions( options );
	
			return this;
		},
	
		_setOptions: function( options ) {
			var key;
	
			for ( key in options ) {
				this._setOption( key, options[ key ] );
			}
	
			return this;
		},
	
		_setOption: function( key, value ) {
			if ( key === "classes" ) {
				this._setOptionClasses( value );
			}
	
			this.options[ key ] = value;
	
			if ( key === "disabled" ) {
				this._setOptionDisabled( value );
			}
	
			return this;
		},
	
		_setOptionClasses: function( value ) {
			var classKey, elements, currentElements;
	
			for ( classKey in value ) {
				currentElements = this.classesElementLookup[ classKey ];
				if ( value[ classKey ] === this.options.classes[ classKey ] ||
						!currentElements ||
						!currentElements.length ) {
					continue;
				}
	
				// We are doing this to create a new jQuery object because the _removeClass() call
				// on the next line is going to destroy the reference to the current elements being
				// tracked. We need to save a copy of this collection so that we can add the new classes
				// below.
				elements = $( currentElements.get() );
				this._removeClass( currentElements, classKey );
	
				// We don't use _addClass() here, because that uses this.options.classes
				// for generating the string of classes. We want to use the value passed in from
				// _setOption(), this is the new value of the classes option which was passed to
				// _setOption(). We pass this value directly to _classes().
				elements.addClass( this._classes( {
					element: elements,
					keys: classKey,
					classes: value,
					add: true
				} ) );
			}
		},
	
		_setOptionDisabled: function( value ) {
			this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
	
			// If the widget is becoming disabled, then nothing is interactive
			if ( value ) {
				this._removeClass( this.hoverable, null, "ui-state-hover" );
				this._removeClass( this.focusable, null, "ui-state-focus" );
			}
		},
	
		enable: function() {
			return this._setOptions( { disabled: false } );
		},
	
		disable: function() {
			return this._setOptions( { disabled: true } );
		},
	
		_classes: function( options ) {
			var full = [];
			var that = this;
	
			options = $.extend( {
				element: this.element,
				classes: this.options.classes || {}
			}, options );
	
			function processClassString( classes, checkOption ) {
				var current, i;
				for ( i = 0; i < classes.length; i++ ) {
					current = that.classesElementLookup[ classes[ i ] ] || $();
					if ( options.add ) {
						current = $( $.unique( current.get().concat( options.element.get() ) ) );
					} else {
						current = $( current.not( options.element ).get() );
					}
					that.classesElementLookup[ classes[ i ] ] = current;
					full.push( classes[ i ] );
					if ( checkOption && options.classes[ classes[ i ] ] ) {
						full.push( options.classes[ classes[ i ] ] );
					}
				}
			}
	
			this._on( options.element, {
				"remove": "_untrackClassesElement"
			} );
	
			if ( options.keys ) {
				processClassString( options.keys.match( /\S+/g ) || [], true );
			}
			if ( options.extra ) {
				processClassString( options.extra.match( /\S+/g ) || [] );
			}
	
			return full.join( " " );
		},
	
		_untrackClassesElement: function( event ) {
			var that = this;
			$.each( that.classesElementLookup, function( key, value ) {
				if ( $.inArray( event.target, value ) !== -1 ) {
					that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
				}
			} );
		},
	
		_removeClass: function( element, keys, extra ) {
			return this._toggleClass( element, keys, extra, false );
		},
	
		_addClass: function( element, keys, extra ) {
			return this._toggleClass( element, keys, extra, true );
		},
	
		_toggleClass: function( element, keys, extra, add ) {
			add = ( typeof add === "boolean" ) ? add : extra;
			var shift = ( typeof element === "string" || element === null ),
				options = {
					extra: shift ? keys : extra,
					keys: shift ? element : keys,
					element: shift ? this.element : element,
					add: add
				};
			options.element.toggleClass( this._classes( options ), add );
			return this;
		},
	
		_on: function( suppressDisabledCheck, element, handlers ) {
			var delegateElement;
			var instance = this;
	
			// No suppressDisabledCheck flag, shuffle arguments
			if ( typeof suppressDisabledCheck !== "boolean" ) {
				handlers = element;
				element = suppressDisabledCheck;
				suppressDisabledCheck = false;
			}
	
			// No element argument, shuffle and use this.element
			if ( !handlers ) {
				handlers = element;
				element = this.element;
				delegateElement = this.widget();
			} else {
				element = delegateElement = $( element );
				this.bindings = this.bindings.add( element );
			}
	
			$.each( handlers, function( event, handler ) {
				function handlerProxy() {
	
					// Allow widgets to customize the disabled handling
					// - disabled as an array instead of boolean
					// - disabled class as method for disabling individual parts
					if ( !suppressDisabledCheck &&
							( instance.options.disabled === true ||
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
						return;
					}
					return ( typeof handler === "string" ? instance[ handler ] : handler )
						.apply( instance, arguments );
				}
	
				// Copy the guid so direct unbinding works
				if ( typeof handler !== "string" ) {
					handlerProxy.guid = handler.guid =
						handler.guid || handlerProxy.guid || $.guid++;
				}
	
				var match = event.match( /^([\w:-]*)\s*(.*)$/ );
				var eventName = match[ 1 ] + instance.eventNamespace;
				var selector = match[ 2 ];
	
				if ( selector ) {
					delegateElement.on( eventName, selector, handlerProxy );
				} else {
					element.on( eventName, handlerProxy );
				}
			} );
		},
	
		_off: function( element, eventName ) {
			eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
				this.eventNamespace;
			element.off( eventName ).off( eventName );
	
			// Clear the stack to avoid memory leaks (#10056)
			this.bindings = $( this.bindings.not( element ).get() );
			this.focusable = $( this.focusable.not( element ).get() );
			this.hoverable = $( this.hoverable.not( element ).get() );
		},
	
		_delay: function( handler, delay ) {
			function handlerProxy() {
				return ( typeof handler === "string" ? instance[ handler ] : handler )
					.apply( instance, arguments );
			}
			var instance = this;
			return setTimeout( handlerProxy, delay || 0 );
		},
	
		_hoverable: function( element ) {
			this.hoverable = this.hoverable.add( element );
			this._on( element, {
				mouseenter: function( event ) {
					this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
				},
				mouseleave: function( event ) {
					this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
				}
			} );
		},
	
		_focusable: function( element ) {
			this.focusable = this.focusable.add( element );
			this._on( element, {
				focusin: function( event ) {
					this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
				},
				focusout: function( event ) {
					this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
				}
			} );
		},
	
		_trigger: function( type, event, data ) {
			var prop, orig;
			var callback = this.options[ type ];
	
			data = data || {};
			event = $.Event( event );
			event.type = ( type === this.widgetEventPrefix ?
				type :
				this.widgetEventPrefix + type ).toLowerCase();
	
			// The original event may come from any element
			// so we need to reset the target on the new event
			event.target = this.element[ 0 ];
	
			// Copy original event properties over to the new event
			orig = event.originalEvent;
			if ( orig ) {
				for ( prop in orig ) {
					if ( !( prop in event ) ) {
						event[ prop ] = orig[ prop ];
					}
				}
			}
	
			this.element.trigger( event, data );
			return !( $.isFunction( callback ) &&
				callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
				event.isDefaultPrevented() );
		}
	};
	
	$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
		$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
			if ( typeof options === "string" ) {
				options = { effect: options };
			}
	
			var hasOptions;
			var effectName = !options ?
				method :
				options === true || typeof options === "number" ?
					defaultEffect :
					options.effect || defaultEffect;
	
			options = options || {};
			if ( typeof options === "number" ) {
				options = { duration: options };
			}
	
			hasOptions = !$.isEmptyObject( options );
			options.complete = callback;
	
			if ( options.delay ) {
				element.delay( options.delay );
			}
	
			if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
				element[ method ]( options );
			} else if ( effectName !== method && element[ effectName ] ) {
				element[ effectName ]( options.duration, options.easing, callback );
			} else {
				element.queue( function( next ) {
					$( this )[ method ]();
					if ( callback ) {
						callback.call( element[ 0 ] );
					}
					next();
				} );
			}
		};
	} );
	
	return $.widget;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widget.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/keycode.js **/
jupyter.define('jquery-ui@1.12.1/ui/keycode.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Keycode 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Keycode
	//>>group: Core
	//>>description: Provide keycodes as keynames
	//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	return $.ui.keyCode = {
		BACKSPACE: 8,
		COMMA: 188,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		LEFT: 37,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SPACE: 32,
		TAB: 9,
		UP: 38
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/keycode.js **/


/** START DEFINE BLOCK for d3-format@0.5.1/build/d3-format.js **/
jupyter.define('d3-format@0.5.1/build/d3-format.js', function (module, exports, __jupyter_require__) {
	(function (global, factory) {
	   true ? factory(exports) :
	  typeof define === 'function' && define.amd ? define(['exports'], factory) :
	  (factory((global.d3_format = {})));
	}(this, function (exports) { 'use strict';
	
	  // Computes the decimal coefficient and exponent of the specified number x with
	  // significant digits p, where x is positive and p is in [1, 21] or undefined.
	  // For example, formatDecimal(1.23) returns ["123", 0].
	  function formatDecimal(x, p) {
	    if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
	    var i, coefficient = x.slice(0, i);
	
	    // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
	    // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
	    return [
	      coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
	      +x.slice(i + 1)
	    ];
	  }
	
	  function exponent(x) {
	    return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
	  }
	
	  function formatGroup(grouping, thousands) {
	    return function(value, width) {
	      var i = value.length,
	          t = [],
	          j = 0,
	          g = grouping[0],
	          length = 0;
	
	      while (i > 0 && g > 0) {
	        if (length + g + 1 > width) g = Math.max(1, width - length);
	        t.push(value.substring(i -= g, i + g));
	        if ((length += g + 1) > width) break;
	        g = grouping[j = (j + 1) % grouping.length];
	      }
	
	      return t.reverse().join(thousands);
	    };
	  }
	
	  function formatDefault(x, p) {
	    x = x.toPrecision(p);
	
	    out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
	      switch (x[i]) {
	        case ".": i0 = i1 = i; break;
	        case "0": if (i0 === 0) i0 = i; i1 = i; break;
	        case "e": break out;
	        default: if (i0 > 0) i0 = 0; break;
	      }
	    }
	
	    return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
	  }
	
	  var prefixExponent;
	
	  function formatPrefixAuto(x, p) {
	    var d = formatDecimal(x, p);
	    if (!d) return x + "";
	    var coefficient = d[0],
	        exponent = d[1],
	        i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
	        n = coefficient.length;
	    return i === n ? coefficient
	        : i > n ? coefficient + new Array(i - n + 1).join("0")
	        : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
	        : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
	  }
	
	  function formatRounded(x, p) {
	    var d = formatDecimal(x, p);
	    if (!d) return x + "";
	    var coefficient = d[0],
	        exponent = d[1];
	    return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
	        : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
	        : coefficient + new Array(exponent - coefficient.length + 2).join("0");
	  }
	
	  var formatTypes = {
	    "": formatDefault,
	    "%": function(x, p) { return (x * 100).toFixed(p); },
	    "b": function(x) { return Math.round(x).toString(2); },
	    "c": function(x) { return x + ""; },
	    "d": function(x) { return Math.round(x).toString(10); },
	    "e": function(x, p) { return x.toExponential(p); },
	    "f": function(x, p) { return x.toFixed(p); },
	    "g": function(x, p) { return x.toPrecision(p); },
	    "o": function(x) { return Math.round(x).toString(8); },
	    "p": function(x, p) { return formatRounded(x * 100, p); },
	    "r": formatRounded,
	    "s": formatPrefixAuto,
	    "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
	    "x": function(x) { return Math.round(x).toString(16); }
	  };
	
	  // [[fill]align][sign][symbol][0][width][,][.precision][type]
	  var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
	
	  function formatSpecifier(specifier) {
	    return new FormatSpecifier(specifier);
	  }
	
	  function FormatSpecifier(specifier) {
	    if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
	
	    var match,
	        fill = match[1] || " ",
	        align = match[2] || ">",
	        sign = match[3] || "-",
	        symbol = match[4] || "",
	        zero = !!match[5],
	        width = match[6] && +match[6],
	        comma = !!match[7],
	        precision = match[8] && +match[8].slice(1),
	        type = match[9] || "";
	
	    // The "n" type is an alias for ",g".
	    if (type === "n") comma = true, type = "g";
	
	    // Map invalid types to the default format.
	    else if (!formatTypes[type]) type = "";
	
	    // If zero fill is specified, padding goes after sign and before digits.
	    if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
	
	    this.fill = fill;
	    this.align = align;
	    this.sign = sign;
	    this.symbol = symbol;
	    this.zero = zero;
	    this.width = width;
	    this.comma = comma;
	    this.precision = precision;
	    this.type = type;
	  }
	
	  FormatSpecifier.prototype.toString = function() {
	    return this.fill
	        + this.align
	        + this.sign
	        + this.symbol
	        + (this.zero ? "0" : "")
	        + (this.width == null ? "" : Math.max(1, this.width | 0))
	        + (this.comma ? "," : "")
	        + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
	        + this.type;
	  };
	
	  var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
	
	  function identity(x) {
	    return x;
	  }
	
	  function locale(locale) {
	    var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity,
	        currency = locale.currency,
	        decimal = locale.decimal;
	
	    function newFormat(specifier) {
	      specifier = formatSpecifier(specifier);
	
	      var fill = specifier.fill,
	          align = specifier.align,
	          sign = specifier.sign,
	          symbol = specifier.symbol,
	          zero = specifier.zero,
	          width = specifier.width,
	          comma = specifier.comma,
	          precision = specifier.precision,
	          type = specifier.type;
	
	      // Compute the prefix and suffix.
	      // For SI-prefix, the suffix is lazily computed.
	      var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
	          suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : "";
	
	      // What format function should we use?
	      // Is this an integer type?
	      // Can this type generate exponential notation?
	      var formatType = formatTypes[type],
	          maybeSuffix = !type || /[defgprs%]/.test(type);
	
	      // Set the default precision if not specified,
	      // or clamp the specified precision to the supported range.
	      // For significant precision, it must be in [1, 21].
	      // For fixed precision, it must be in [0, 20].
	      precision = precision == null ? (type ? 6 : 12)
	          : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
	          : Math.max(0, Math.min(20, precision));
	
	      function format(value) {
	        var valuePrefix = prefix,
	            valueSuffix = suffix,
	            i, n, c;
	
	        if (type === "c") {
	          valueSuffix = formatType(value) + valueSuffix;
	          value = "";
	        } else {
	          value = +value;
	
	          // Convert negative to positive, and compute the prefix.
	          // Note that -0 is not less than 0, but 1 / -0 is!
	          var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true);
	
	          // Perform the initial formatting.
	          value = formatType(value, precision);
	
	          // If the original value was negative, it may be rounded to zero during
	          // formatting; treat this as (positive) zero.
	          if (valueNegative) {
	            i = -1, n = value.length;
	            valueNegative = false;
	            while (++i < n) {
	              if (c = value.charCodeAt(i), (48 < c && c < 58)
	                  || (type === "x" && 96 < c && c < 103)
	                  || (type === "X" && 64 < c && c < 71)) {
	                valueNegative = true;
	                break;
	              }
	            }
	          }
	
	          // Compute the prefix and suffix.
	          valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
	          valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
	
	          // Break the formatted value into the integer “value” part that can be
	          // grouped, and fractional or exponential “suffix” part that is not.
	          if (maybeSuffix) {
	            i = -1, n = value.length;
	            while (++i < n) {
	              if (c = value.charCodeAt(i), 48 > c || c > 57) {
	                valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
	                value = value.slice(0, i);
	                break;
	              }
	            }
	          }
	        }
	
	        // If the fill character is not "0", grouping is applied before padding.
	        if (comma && !zero) value = group(value, Infinity);
	
	        // Compute the padding.
	        var length = valuePrefix.length + value.length + valueSuffix.length,
	            padding = length < width ? new Array(width - length + 1).join(fill) : "";
	
	        // If the fill character is "0", grouping is applied after padding.
	        if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
	
	        // Reconstruct the final output based on the desired alignment.
	        switch (align) {
	          case "<": return valuePrefix + value + valueSuffix + padding;
	          case "=": return valuePrefix + padding + value + valueSuffix;
	          case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
	        }
	        return padding + valuePrefix + value + valueSuffix;
	      }
	
	      format.toString = function() {
	        return specifier + "";
	      };
	
	      return format;
	    }
	
	    function formatPrefix(specifier, value) {
	      var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
	          e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,
	          k = Math.pow(10, -e),
	          prefix = prefixes[8 + e / 3];
	      return function(value) {
	        return f(k * value) + prefix;
	      };
	    }
	
	    return {
	      format: newFormat,
	      formatPrefix: formatPrefix
	    };
	  }
	
	  var defaultLocale = locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [3],
	    currency: ["$", ""]
	  });
	
	  var caES = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["", "\xa0€"]
	  });
	
	  var csCZ = locale({
	    decimal: ",",
	    thousands: "\xa0",
	    grouping: [3],
	    currency: ["", "\xa0Kč"]
	  });
	
	  var deCH = locale({
	    decimal: ",",
	    thousands: "'",
	    grouping: [3],
	    currency: ["", "\xa0CHF"]
	  });
	
	  var deDE = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["", "\xa0€"]
	  });
	
	  var enCA = locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [3],
	    currency: ["$", ""]
	  });
	
	  var enGB = locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [3],
	    currency: ["£", ""]
	  });
	
	  var esES = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["", "\xa0€"]
	  });
	
	  var fiFI = locale({
	    decimal: ",",
	    thousands: "\xa0",
	    grouping: [3],
	    currency: ["", "\xa0€"]
	  });
	
	  var frCA = locale({
	    decimal: ",",
	    thousands: "\xa0",
	    grouping: [3],
	    currency: ["", "$"]
	  });
	
	  var frFR = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["", "\xa0€"]
	  });
	
	  var heIL = locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [3],
	    currency: ["₪", ""]
	  });
	
	  var huHU = locale({
	    decimal: ",",
	    thousands: "\xa0",
	    grouping: [3],
	    currency: ["", "\xa0Ft"]
	  });
	
	  var itIT = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["€", ""]
	  });
	
	  var jaJP = locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [3],
	    currency: ["", "円"]
	  });
	
	  var koKR = locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [3],
	    currency: ["₩", ""]
	  });
	
	  var mkMK = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["", "\xa0ден."]
	  });
	
	  var nlNL = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["€\xa0", ""]
	  });
	
	  var plPL = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["", "zł"]
	  });
	
	  var ptBR = locale({
	    decimal: ",",
	    thousands: ".",
	    grouping: [3],
	    currency: ["R$", ""]
	  });
	
	  var ruRU = locale({
	    decimal: ",",
	    thousands: "\xa0",
	    grouping: [3],
	    currency: ["", "\xa0руб."]
	  });
	
	  var svSE = locale({
	    decimal: ",",
	    thousands: "\xa0",
	    grouping: [3],
	    currency: ["", "SEK"]
	  });
	
	  var zhCN = locale({
	    decimal: ".",
	    thousands: ",",
	    grouping: [3],
	    currency: ["¥", ""]
	  });
	
	  function precisionFixed(step) {
	    return Math.max(0, -exponent(Math.abs(step)));
	  }
	
	  function precisionPrefix(step, value) {
	    return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));
	  }
	
	  function precisionRound(step, max) {
	    step = Math.abs(step), max = Math.abs(max) - step;
	    return Math.max(0, exponent(max) - exponent(step)) + 1;
	  }
	
	  var format = defaultLocale.format;
	  var formatPrefix = defaultLocale.formatPrefix;
	
	  var version = "0.5.1";
	
	  exports.version = version;
	  exports.format = format;
	  exports.formatPrefix = formatPrefix;
	  exports.formatLocale = locale;
	  exports.formatCaEs = caES;
	  exports.formatCsCz = csCZ;
	  exports.formatDeCh = deCH;
	  exports.formatDeDe = deDE;
	  exports.formatEnCa = enCA;
	  exports.formatEnGb = enGB;
	  exports.formatEnUs = defaultLocale;
	  exports.formatEsEs = esES;
	  exports.formatFiFi = fiFI;
	  exports.formatFrCa = frCA;
	  exports.formatFrFr = frFR;
	  exports.formatHeIl = heIL;
	  exports.formatHuHu = huHU;
	  exports.formatItIt = itIT;
	  exports.formatJaJp = jaJP;
	  exports.formatKoKr = koKR;
	  exports.formatMkMk = mkMK;
	  exports.formatNlNl = nlNL;
	  exports.formatPlPl = plPL;
	  exports.formatPtBr = ptBR;
	  exports.formatRuRu = ruRU;
	  exports.formatSvSe = svSE;
	  exports.formatZhCn = zhCN;
	  exports.formatSpecifier = formatSpecifier;
	  exports.precisionFixed = precisionFixed;
	  exports.precisionPrefix = precisionPrefix;
	  exports.precisionRound = precisionRound;
	
	}));
})
/** END DEFINE BLOCK for d3-format@0.5.1/build/d3-format.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_float.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_float.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var widget_int_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_int.js');
	var d3format = __jupyter_require__('d3-format@^0.5.1/build/d3-format.js').format;
	var FloatModel = (function (_super) {
	    __extends(FloatModel, _super);
	    function FloatModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "FloatModel",
	            value: 0,
	            disabled: false,
	        });
	    };
	    return FloatModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.FloatModel = FloatModel;
	var BoundedFloatModel = (function (_super) {
	    __extends(BoundedFloatModel, _super);
	    function BoundedFloatModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedFloatModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "BoundedFloatModel",
	            max: 100.0,
	            min: 0.0
	        });
	    };
	    return BoundedFloatModel;
	}(FloatModel));
	exports.BoundedFloatModel = BoundedFloatModel;
	var FloatSliderModel = (function (_super) {
	    __extends(FloatSliderModel, _super);
	    function FloatSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatSliderModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "FloatSliderModel",
	            _view_name: "FloatSliderView",
	            step: 1.0,
	            orientation: "horizontal",
	            _range: false,
	            readout: true,
	            readout_format: '.2f',
	            slider_color: null,
	            continuous_update: true
	        });
	    };
	    FloatSliderModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.on('change:readout_format', this.update_readout_format, this);
	        this.update_readout_format();
	    };
	    FloatSliderModel.prototype.update_readout_format = function () {
	        this.readout_formatter = d3format(this.get('readout_format'));
	    };
	    return FloatSliderModel;
	}(BoundedFloatModel));
	exports.FloatSliderModel = FloatSliderModel;
	var FloatRangeSliderModel = (function (_super) {
	    __extends(FloatRangeSliderModel, _super);
	    function FloatRangeSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    return FloatRangeSliderModel;
	}(FloatSliderModel));
	exports.FloatRangeSliderModel = FloatRangeSliderModel;
	var FloatSliderView = (function (_super) {
	    __extends(FloatSliderView, _super);
	    function FloatSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseFloat;
	        return _this;
	    }
	    /**
	     * Validate the value of the slider before sending it to the back-end
	     * and applying it to the other views on the page.
	     */
	    FloatSliderView.prototype._validate_slide_value = function (x) {
	        return x;
	    };
	    return FloatSliderView;
	}(widget_int_1.IntSliderView));
	exports.FloatSliderView = FloatSliderView;
	var FloatRangeSliderView = (function (_super) {
	    __extends(FloatRangeSliderView, _super);
	    function FloatRangeSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseFloat;
	        // matches: whitespace?, float, whitespace?, (hyphen, colon, or en-dash), whitespace?, float
	        _this._range_regex = /^\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][-:]?\d+)?)\s*[-:–]\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)/;
	        return _this;
	    }
	    /**
	     * Validate the value of the slider before sending it to the back-end
	     * and applying it to the other views on the page.
	     */
	    FloatRangeSliderView.prototype._validate_slide_value = function (x) {
	        return x;
	    };
	    return FloatRangeSliderView;
	}(widget_int_1.IntRangeSliderView));
	exports.FloatRangeSliderView = FloatRangeSliderView;
	var FloatTextModel = (function (_super) {
	    __extends(FloatTextModel, _super);
	    function FloatTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "FloatTextModel",
	            _view_name: "FloatTextView"
	        });
	    };
	    return FloatTextModel;
	}(FloatModel));
	exports.FloatTextModel = FloatTextModel;
	var BoundedFloatTextModel = (function (_super) {
	    __extends(BoundedFloatTextModel, _super);
	    function BoundedFloatTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedFloatTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "BoundedFloatTextModel",
	            _view_name: "FloatTextView"
	        });
	    };
	    return BoundedFloatTextModel;
	}(BoundedFloatModel));
	exports.BoundedFloatTextModel = BoundedFloatTextModel;
	var FloatTextView = (function (_super) {
	    __extends(FloatTextView, _super);
	    function FloatTextView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseFloat;
	        return _this;
	    }
	    return FloatTextView;
	}(widget_int_1.IntTextView));
	exports.FloatTextView = FloatTextView;
	var FloatProgressModel = (function (_super) {
	    __extends(FloatProgressModel, _super);
	    function FloatProgressModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatProgressModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'FloatProgressModel',
	            _view_name: 'ProgressView',
	            orientation: 'horizontal',
	            bar_style: '',
	            style: null
	        });
	    };
	    return FloatProgressModel;
	}(BoundedFloatModel));
	exports.FloatProgressModel = FloatProgressModel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_float.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_controller.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_controller.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js');
	var ControllerButtonModel = (function (_super) {
	    __extends(ControllerButtonModel, _super);
	    function ControllerButtonModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerButtonModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ControllerButtonModel',
	            _view_name: 'ControllerButtonView',
	            value: 0.0,
	            pressed: false
	        });
	    };
	    return ControllerButtonModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ControllerButtonModel = ControllerButtonModel;
	/**
	 * Very simple view for a gamepad button.
	 */
	var ControllerButtonView = (function (_super) {
	    __extends(ControllerButtonView, _super);
	    function ControllerButtonView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerButtonView.prototype.render = function () {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-controller-button');
	        this.support = document.createElement('div');
	        this.support.style.position = 'relative';
	        this.support.style.margin = '1px';
	        this.support.style.width = '16px';
	        this.support.style.height = '16px';
	        this.support.style.border = '1px solid black';
	        this.support.style.background = 'lightgray';
	        this.el.appendChild(this.support);
	        this.bar = document.createElement('div');
	        this.bar.style.position = 'absolute';
	        this.bar.style.width = '100%';
	        this.bar.style.bottom = '0px';
	        this.bar.style.background = 'gray';
	        this.support.appendChild(this.bar);
	        this.update();
	        this.label = document.createElement('div');
	        this.label.textContent = this.model.get('description');
	        this.label.style.textAlign = 'center';
	        this.el.appendChild(this.label);
	    };
	    ControllerButtonView.prototype.update = function () {
	        this.bar.style.height = (100 * this.model.get('value')) + '%';
	    };
	    return ControllerButtonView;
	}(widget_1.DOMWidgetView));
	exports.ControllerButtonView = ControllerButtonView;
	var ControllerAxisModel = (function (_super) {
	    __extends(ControllerAxisModel, _super);
	    function ControllerAxisModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerAxisModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ControllerAxisModel',
	            _view_name: 'ControllerAxisView',
	            value: 0.0
	        });
	    };
	    return ControllerAxisModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ControllerAxisModel = ControllerAxisModel;
	/**
	 * Very simple view for a gamepad axis.
	 */
	var ControllerAxisView = (function (_super) {
	    __extends(ControllerAxisView, _super);
	    function ControllerAxisView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerAxisView.prototype.render = function () {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-controller-axis');
	        this.el.style.width = '16px';
	        this.el.style.padding = '4px';
	        this.support = document.createElement('div');
	        this.support.style.position = 'relative';
	        this.support.style.margin = '1px';
	        this.support.style.width = '4px';
	        this.support.style.height = '64px';
	        this.support.style.border = '1px solid black';
	        this.support.style.background = 'lightgray';
	        this.bullet = document.createElement('div');
	        this.bullet.style.position = 'absolute';
	        this.bullet.style.margin = '-4px';
	        this.bullet.style.width = '10px';
	        this.bullet.style.height = '10px';
	        this.bullet.style.background = 'gray';
	        this.label = document.createElement('div');
	        this.label.textContent = this.model.get('description');
	        this.label.style.textAlign = 'center';
	        this.support.appendChild(this.bullet);
	        this.el.appendChild(this.support);
	        this.el.appendChild(this.label);
	        this.update();
	    };
	    ControllerAxisView.prototype.update = function () {
	        this.bullet.style.top = (50 * (this.model.get('value') + 1)) + '%';
	    };
	    return ControllerAxisView;
	}(widget_1.DOMWidgetView));
	exports.ControllerAxisView = ControllerAxisView;
	var ControllerModel = (function (_super) {
	    __extends(ControllerModel, _super);
	    function ControllerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ControllerModel',
	            _view_name: 'ControllerView',
	            index: 0,
	            name: '',
	            mapping: '',
	            connected: false,
	            timestamp: 0,
	            buttons: [],
	            axes: []
	        });
	    };
	    ControllerModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        if (navigator.getGamepads === void 0) {
	            // Checks if the browser supports the gamepad API
	            this.readout = 'This browser does not support gamepads.';
	            console.error(this.readout);
	        }
	        else {
	            // Start the wait loop, and listen to updates of the only
	            // user-provided attribute, the gamepad index.
	            this.readout = 'Connect gamepad and press any button.';
	            if (this.get('connected')) {
	                // No need to re-create Button and Axis widgets, re-use
	                // the models provided by the backend which may already
	                // be wired to other things.
	                this.update_loop();
	            }
	            else {
	                // Wait for a gamepad to be connected.
	                this.wait_loop();
	            }
	        }
	    };
	    /**
	     * Waits for a gamepad to be connected at the provided index.
	     * Once one is connected, it will start the update loop, which
	     * populates the update of axes and button values.
	     */
	    ControllerModel.prototype.wait_loop = function () {
	        var index = this.get('index');
	        var pad = navigator.getGamepads()[index];
	        if (pad) {
	            var that = this;
	            this.setup(pad).then(function (controls) {
	                that.set(controls);
	                that.save_changes();
	                window.requestAnimationFrame(that.update_loop.bind(that));
	            });
	        }
	        else {
	            window.requestAnimationFrame(this.wait_loop.bind(this));
	        }
	    };
	    /**
	     * Given a native gamepad object, returns a promise for a dictionary of
	     * controls, of the form
	     * {
	     *     buttons: list of Button models,
	     *     axes: list of Axis models,
	     * }
	     */
	    ControllerModel.prototype.setup = function (pad) {
	        // Set up the main gamepad attributes
	        this.set({
	            name: pad.id,
	            mapping: pad.mapping,
	            connected: pad.connected,
	            timestamp: pad.timestamp
	        });
	        // Create buttons and axes. When done, start the update loop
	        var that = this;
	        return utils.resolvePromisesDict({
	            buttons: Promise.all(pad.buttons.map(function (btn, index) {
	                return that._create_button_model(index);
	            })),
	            axes: Promise.all(pad.axes.map(function (axis, index) {
	                return that._create_axis_model(index);
	            })),
	        });
	    };
	    /**
	     * Update axes and buttons values, until the gamepad is disconnected.
	     * When the gamepad is disconnected, this.reset_gamepad is called.
	     */
	    ControllerModel.prototype.update_loop = function () {
	        var index = this.get('index');
	        var id = this.get('name');
	        var pad = navigator.getGamepads()[index];
	        if (pad && index === pad.index && id === pad.id) {
	            this.set({
	                timestamp: pad.timestamp,
	                connected: pad.connected
	            });
	            this.save_changes();
	            this.get('buttons').forEach(function (model, index) {
	                model.set({
	                    value: pad.buttons[index].value,
	                    pressed: pad.buttons[index].pressed
	                });
	                model.save_changes();
	            });
	            this.get('axes').forEach(function (model, index) {
	                model.set('value', pad.axes[index]);
	                model.save_changes();
	            });
	            window.requestAnimationFrame(this.update_loop.bind(this));
	        }
	        else {
	            this.reset_gamepad();
	        }
	    };
	    /**
	     * Resets the gamepad attributes, and start the wait_loop.
	     */
	    ControllerModel.prototype.reset_gamepad = function () {
	        this.get('buttons').forEach(function (button) {
	            button.close();
	        });
	        this.get('axes').forEach(function (axis) {
	            axis.close();
	        });
	        this.set({
	            name: '',
	            mapping: '',
	            connected: false,
	            timestamp: 0.0,
	            buttons: [],
	            axes: []
	        });
	        this.save_changes();
	        window.requestAnimationFrame(this.wait_loop.bind(this));
	    };
	    /**
	     * Creates a gamepad button widget.
	     */
	    ControllerModel.prototype._create_button_model = function (index) {
	        return this.widget_manager.new_widget({
	            model_name: 'ControllerButtonModel',
	            model_module: 'jupyter-js-widgets',
	            model_module_version: this.get('_model_module_version'),
	            view_name: 'ControllerButtonView',
	            view_module: 'jupyter-js-widgets',
	            view_module_version: this.get('_view_module_version'),
	        }).then(function (model) {
	            model.set('description', index);
	            return model;
	        });
	    };
	    /**
	     * Creates a gamepad axis widget.
	     */
	    ControllerModel.prototype._create_axis_model = function (index) {
	        return this.widget_manager.new_widget({
	            model_name: 'ControllerAxisModel',
	            model_module: 'jupyter-js-widgets',
	            model_module_version: this.get('_model_module_version'),
	            view_name: 'ControllerAxisView',
	            view_module: 'jupyter-js-widgets',
	            view_module_version: this.get('_view_module_version'),
	        }).then(function (model) {
	            model.set('description', index);
	            return model;
	        });
	    };
	    return ControllerModel;
	}(widget_core_1.CoreDOMWidgetModel));
	ControllerModel.serializers = __assign({}, widget_core_1.CoreDOMWidgetModel.serializers, { buttons: { deserialize: widget_1.unpack_models }, axes: { deserialize: widget_1.unpack_models } });
	exports.ControllerModel = ControllerModel;
	/**
	 * A simple view for a gamepad.
	 */
	var ControllerView = (function (_super) {
	    __extends(ControllerView, _super);
	    function ControllerView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.button_views = new widget_1.ViewList(this.add_button, null, this);
	        this.listenTo(this.model, 'change:buttons', function (model, value) {
	            this.button_views.update(value);
	        });
	        this.axis_views = new widget_1.ViewList(this.add_axis, null, this);
	        this.listenTo(this.model, 'change:axes', function (model, value) {
	            this.axis_views.update(value);
	        });
	        this.listenTo(this.model, 'change:name', this.update_label);
	    };
	    ControllerView.prototype.render = function () {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-controller');
	        this.box = this.el;
	        this.label = document.createElement('div');
	        this.box.appendChild(this.label);
	        this.axis_box = document.createElement('div');
	        this.axis_box.style.display = 'flex';
	        this.box.appendChild(this.axis_box);
	        this.button_box = document.createElement('div');
	        this.button_box.style.display = 'flex';
	        this.box.appendChild(this.button_box);
	        this.button_views.update(this.model.get('buttons'));
	        this.axis_views.update(this.model.get('axes'));
	        this.update_label();
	    };
	    ControllerView.prototype.update_label = function () {
	        this.label.textContent = this.model.get('name') || this.model.readout;
	    };
	    ControllerView.prototype.add_button = function (model) {
	        var that = this;
	        var dummy = document.createElement('div');
	        that.button_box.appendChild(dummy);
	        return this.create_child_view(model).then(function (view) {
	            that.button_box.replaceChild(view.el, dummy);
	            that.displayed.then(function () {
	                view.trigger('displayed', that);
	            });
	            return view;
	        }).catch(utils.reject('Could not add button view', true));
	    };
	    ControllerView.prototype.add_axis = function (model) {
	        var that = this;
	        var dummy = document.createElement('div');
	        that.axis_box.appendChild(dummy);
	        return this.create_child_view(model).then(function (view) {
	            that.axis_box.replaceChild(view.el, dummy);
	            that.displayed.then(function () {
	                view.trigger('displayed', that);
	            });
	            return view;
	        }).catch(utils.reject('Could not add axis view', true));
	    };
	    ControllerView.prototype.remove = function () {
	        _super.prototype.remove.call(this);
	        this.button_views.remove();
	        this.axis_views.remove();
	    };
	    return ControllerView;
	}(widget_1.DOMWidgetView));
	exports.ControllerView = ControllerView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_controller.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selection.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selection.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	function scrollIfNeeded(area, elem) {
	    var ar = area.getBoundingClientRect();
	    var er = elem.getBoundingClientRect();
	    if (er.top < ar.top) {
	        area.scrollTop -= ar.top - er.top;
	    }
	    else if (er.bottom > ar.bottom) {
	        area.scrollTop += er.bottom - ar.bottom;
	    }
	}
	var SelectionModel = (function (_super) {
	    __extends(SelectionModel, _super);
	    function SelectionModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectionModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'SelectionModel', index: '', _options_labels: [], disabled: false });
	    };
	    return SelectionModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.SelectionModel = SelectionModel;
	var DropdownModel = (function (_super) {
	    __extends(DropdownModel, _super);
	    function DropdownModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DropdownModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'DropdownModel', _view_name: 'DropdownView', button_style: '' });
	    };
	    return DropdownModel;
	}(SelectionModel));
	exports.DropdownModel = DropdownModel;
	// TODO: Make a phosphor dropdown control, wrapped in DropdownView. Also, fix
	// bugs in keyboard handling. See
	// https://github.com/jupyter-widgets/ipywidgets/issues/1055 and
	// https://github.com/jupyter-widgets/ipywidgets/issues/1049
	// For now, we subclass SelectView to provide DropdownView
	// For the old code, see commit f68bfbc566f3a78a8f3350b438db8ed523ce3642
	var DropdownView = (function (_super) {
	    __extends(DropdownView, _super);
	    function DropdownView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor.
	     */
	    DropdownView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.listenTo(this.model, 'change:_options_labels', function () { return _this._updateOptions(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    DropdownView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-dropdown');
	        this.listbox = document.createElement('select');
	        this.el.appendChild(this.listbox);
	        this._updateOptions();
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     */
	    DropdownView.prototype.update = function () {
	        // Disable listbox if needed
	        this.listbox.disabled = this.model.get('disabled');
	        // Select the correct element
	        var index = this.model.get('index');
	        this.listbox.selectedIndex = index === null ? -1 : index;
	        return _super.prototype.update.call(this);
	    };
	    DropdownView.prototype._updateOptions = function () {
	        this.listbox.textContent = '';
	        var items = this.model.get('_options_labels');
	        for (var i = 0; i < items.length; i++) {
	            var item = items[i];
	            var option = document.createElement('option');
	            option.textContent = item.replace(/ /g, '\xa0'); // space -> &nbsp;
	            option.setAttribute('data-value', encodeURIComponent(item));
	            option.value = item;
	            this.listbox.appendChild(option);
	        }
	    };
	    DropdownView.prototype.events = function () {
	        return {
	            'change select': '_handle_change'
	        };
	    };
	    /**
	     * Handle when a new value is selected.
	     */
	    DropdownView.prototype._handle_change = function () {
	        this.model.set('index', this.listbox.selectedIndex === -1 ? null : this.listbox.selectedIndex);
	        this.touch();
	    };
	    return DropdownView;
	}(widget_1.LabeledDOMWidgetView));
	exports.DropdownView = DropdownView;
	var SelectModel = (function (_super) {
	    __extends(SelectModel, _super);
	    function SelectModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'SelectModel', _view_name: 'SelectView', rows: 5 });
	    };
	    return SelectModel;
	}(SelectionModel));
	exports.SelectModel = SelectModel;
	var SelectView = (function (_super) {
	    __extends(SelectView, _super);
	    function SelectView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor.
	     */
	    SelectView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.listenTo(this.model, 'change:_options_labels', function () { return _this._updateOptions(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    SelectView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-select');
	        this.listbox = document.createElement('select');
	        this.el.appendChild(this.listbox);
	        this._updateOptions();
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     */
	    SelectView.prototype.update = function () {
	        _super.prototype.update.call(this);
	        // Disable listbox if needed
	        this.listbox.disabled = this.model.get('disabled');
	        this.listbox.size = this.model.get('rows');
	        this.updateSelection();
	    };
	    SelectView.prototype.updateSelection = function () {
	        var index = this.model.get('index');
	        this.listbox.selectedIndex = index === null ? -1 : index;
	    };
	    SelectView.prototype._updateOptions = function () {
	        this.listbox.textContent = '';
	        var items = this.model.get('_options_labels');
	        for (var i = 0; i < items.length; i++) {
	            var item = items[i];
	            var option = document.createElement('option');
	            option.textContent = item.replace(/ /g, '\xa0'); // space -> &nbsp;
	            option.setAttribute('data-value', encodeURIComponent(item));
	            option.value = item;
	            this.listbox.appendChild(option);
	        }
	    };
	    SelectView.prototype.events = function () {
	        return {
	            'change select': '_handle_change'
	        };
	    };
	    /**
	     * Handle when a new value is selected.
	     */
	    SelectView.prototype._handle_change = function () {
	        // Don't use [] indexing to work around https://github.com/Microsoft/TypeScript/issues/14522
	        this.model.set('index', this.listbox.selectedIndex);
	        this.touch();
	    };
	    return SelectView;
	}(widget_1.LabeledDOMWidgetView));
	exports.SelectView = SelectView;
	var RadioButtonsModel = (function (_super) {
	    __extends(RadioButtonsModel, _super);
	    function RadioButtonsModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    RadioButtonsModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'RadioButtonsModel', _view_name: 'RadioButtonsView', tooltips: [], icons: [], button_style: '' });
	    };
	    return RadioButtonsModel;
	}(SelectionModel));
	exports.RadioButtonsModel = RadioButtonsModel;
	var RadioButtonsView = (function (_super) {
	    __extends(RadioButtonsView, _super);
	    function RadioButtonsView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    RadioButtonsView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-radio');
	        this.container = document.createElement('div');
	        this.el.appendChild(this.container);
	        this.container.classList.add('widget-radio-box');
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    RadioButtonsView.prototype.update = function (options) {
	        var view = this;
	        var items = this.model.get('_options_labels');
	        var radios = _.pluck(this.container.querySelectorAll('input[type="radio"]'), 'value');
	        var stale = items.length != radios.length;
	        if (!stale) {
	            for (var i = 0, len = items.length; i < len; ++i) {
	                if (radios[i] !== items[i]) {
	                    stale = true;
	                    break;
	                }
	            }
	        }
	        if (stale && (options === undefined || options.updated_view !== this)) {
	            // Add items to the DOM.
	            this.container.textContent = '';
	            _.each(items, function (item, index) {
	                var label = document.createElement('label');
	                label.textContent = item;
	                view.container.appendChild(label);
	                var radio = document.createElement('input');
	                radio.setAttribute('type', 'radio');
	                radio.value = index.toString();
	                radio.setAttribute('data-value', encodeURIComponent(item));
	                label.appendChild(radio);
	            });
	        }
	        _.each(items, function (item, index) {
	            var item_query = 'input[data-value="' +
	                encodeURIComponent(item) + '"]';
	            var radio = view.container.querySelectorAll(item_query);
	            if (radio.length > 0) {
	                var radio_el = radio[0];
	                radio_el.checked = view.model.get('index') === index;
	                radio_el.disabled = view.model.get('disabled');
	            }
	        });
	        // Schedule adjustPadding asynchronously to
	        // allow dom elements to be created properly
	        setTimeout(this.adjustPadding, 0, this);
	        return _super.prototype.update.call(this, options);
	    };
	    /**
	     * Adjust Padding to Multiple of Line Height
	     *
	     * Adjust margins so that the overall height
	     * is a multiple of a single line height.
	     *
	     * This widget needs it because radio options
	     * are spaced tighter than individual widgets
	     * yet we would like the full widget line up properly
	     * when displayed side-by-side with other widgets.
	     */
	    RadioButtonsView.prototype.adjustPadding = function (e) {
	        // Vertical margins on a widget
	        var elStyles = window.getComputedStyle(e.el);
	        var margins = parseInt(elStyles.marginTop) + parseInt(elStyles.marginBottom);
	        // Total spaces taken by a single-line widget
	        var lineHeight = e.label.offsetHeight + margins;
	        // Current adjustment value on this widget
	        var cStyles = window.getComputedStyle(e.container);
	        var containerMargin = parseInt(cStyles.marginBottom);
	        // How far we are off from a multiple of single windget lines
	        var diff = (e.el.offsetHeight + margins - containerMargin) % lineHeight;
	        // Apply the new adjustment
	        var extraMargin = diff == 0 ? 0 : (lineHeight - diff);
	        e.container.style.marginBottom = extraMargin + 'px';
	    };
	    RadioButtonsView.prototype.events = function () {
	        return {
	            'click input[type="radio"]': '_handle_click'
	        };
	    };
	    /**
	     * Handle when a value is clicked.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    RadioButtonsView.prototype._handle_click = function (event) {
	        this.model.set('index', parseInt(event.target.value), { updated_view: this });
	        this.touch();
	    };
	    return RadioButtonsView;
	}(widget_1.LabeledDOMWidgetView));
	exports.RadioButtonsView = RadioButtonsView;
	var ToggleButtonsModel = (function (_super) {
	    __extends(ToggleButtonsModel, _super);
	    function ToggleButtonsModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ToggleButtonsModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'ToggleButtonsModel', _view_name: 'ToggleButtonsView' });
	    };
	    return ToggleButtonsModel;
	}(SelectionModel));
	exports.ToggleButtonsModel = ToggleButtonsModel;
	var ToggleButtonsView = (function (_super) {
	    __extends(ToggleButtonsView, _super);
	    function ToggleButtonsView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ToggleButtonsView.prototype.initialize = function (options) {
	        this._css_state = {};
	        _super.prototype.initialize.call(this, options);
	        this.listenTo(this.model, 'change:button_style', this.update_button_style);
	    };
	    /**
	     * Called when view is rendered.
	     */
	    ToggleButtonsView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-toggle-buttons');
	        this.buttongroup = document.createElement('div');
	        this.el.appendChild(this.buttongroup);
	        this.update();
	        this.set_button_style();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ToggleButtonsView.prototype.update = function (options) {
	        var view = this;
	        var items = this.model.get('_options_labels');
	        var icons = this.model.get('icons') || [];
	        var previous_icons = this.model.previous('icons') || [];
	        var previous_bstyle = ToggleButtonsView.classMap[this.model.previous('button_style')] || '';
	        var tooltips = view.model.get('tooltips') || [];
	        var disabled = this.model.get('disabled');
	        var buttons = this.buttongroup.querySelectorAll('button');
	        var values = _.pluck(buttons, 'value');
	        var stale = false;
	        for (var i = 0, len = items.length; i < len; ++i) {
	            if (values[i] !== items[i] || icons[i] !== previous_icons[i]) {
	                stale = true;
	                break;
	            }
	        }
	        if (stale && options === undefined || options.updated_view !== this) {
	            // Add items to the DOM.
	            this.buttongroup.textContent = '';
	            _.each(items, function (item, index) {
	                var item_html;
	                var empty = item.trim().length === 0 &&
	                    (!icons[index] || icons[index].trim().length === 0);
	                if (empty) {
	                    item_html = '&nbsp;';
	                }
	                else {
	                    item_html = utils.escape_html(item);
	                }
	                var icon = document.createElement('i');
	                var button = document.createElement('button');
	                if (icons[index]) {
	                    icon.className = 'fa fa-' + icons[index];
	                }
	                button.setAttribute('type', 'button');
	                button.className = 'widget-toggle-button jupyter-button';
	                if (previous_bstyle) {
	                    button.classList.add(previous_bstyle);
	                }
	                button.innerHTML = item_html;
	                button.setAttribute('data-value', encodeURIComponent(item));
	                button.setAttribute('value', index.toString());
	                button.appendChild(icon);
	                button.disabled = disabled;
	                if (tooltips[index]) {
	                    button.setAttribute('title', tooltips[index]);
	                }
	                view.update_style_traits(button);
	                view.buttongroup.appendChild(button);
	            });
	        }
	        // Select active button.
	        _.each(items, function (item, index) {
	            var item_query = '[data-value="' + encodeURIComponent(item) + '"]';
	            var button = view.buttongroup.querySelector(item_query);
	            if (view.model.get('index') === index) {
	                button.classList.add('mod-active');
	            }
	            else {
	                button.classList.remove('mod-active');
	            }
	        });
	        return _super.prototype.update.call(this, options);
	    };
	    ToggleButtonsView.prototype.update_style_traits = function (button) {
	        for (var name in this._css_state) {
	            if (this._css_state.hasOwnProperty(name)) {
	                if (name === 'margin') {
	                    this.buttongroup.style[name] = this._css_state[name];
	                }
	                else if (name !== 'width') {
	                    if (button) {
	                        button.style[name] = this._css_state[name];
	                    }
	                    else {
	                        var buttons = this.buttongroup
	                            .querySelectorAll('button');
	                        if (buttons.length) {
	                            buttons[0].style[name] = this._css_state[name];
	                        }
	                    }
	                }
	            }
	        }
	    };
	    ToggleButtonsView.prototype.update_button_style = function () {
	        var _this = this;
	        var buttons = this.buttongroup.querySelectorAll('button');
	        _.each(buttons, function (button) {
	            _this.update_mapped_classes(ToggleButtonsView.classMap, 'button_style', button);
	        });
	    };
	    ToggleButtonsView.prototype.set_button_style = function () {
	        var _this = this;
	        var buttons = this.buttongroup.querySelectorAll('button');
	        _.each(buttons, function (button) {
	            _this.set_mapped_classes(ToggleButtonsView.classMap, 'button_style', button);
	        });
	    };
	    ToggleButtonsView.prototype.events = function () {
	        return {
	            'click button': '_handle_click'
	        };
	    };
	    /**
	     * Handle when a value is clicked.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    ToggleButtonsView.prototype._handle_click = function (event) {
	        this.model.set('index', parseInt(event.target.value), { updated_view: this });
	        this.touch();
	        // We also send a clicked event, since the value is only set if it changed.
	        // See https://github.com/jupyter-widgets/ipywidgets/issues/763
	        this.send({ event: 'click' });
	    };
	    return ToggleButtonsView;
	}(widget_1.LabeledDOMWidgetView));
	exports.ToggleButtonsView = ToggleButtonsView;
	(function (ToggleButtonsView) {
	    ToggleButtonsView.classMap = {
	        primary: ['mod-primary'],
	        success: ['mod-success'],
	        info: ['mod-info'],
	        warning: ['mod-warning'],
	        danger: ['mod-danger']
	    };
	})(ToggleButtonsView = exports.ToggleButtonsView || (exports.ToggleButtonsView = {}));
	exports.ToggleButtonsView = ToggleButtonsView;
	var SelectionSliderModel = (function (_super) {
	    __extends(SelectionSliderModel, _super);
	    function SelectionSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectionSliderModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'SelectionSliderModel', _view_name: 'SelectionSliderView', orientation: 'horizontal', readout: true, continuous_update: true });
	    };
	    return SelectionSliderModel;
	}(SelectionModel));
	exports.SelectionSliderModel = SelectionSliderModel;
	var SelectionSliderView = (function (_super) {
	    __extends(SelectionSliderView, _super);
	    function SelectionSliderView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    SelectionSliderView.prototype.render = function () {
	        var _this = this;
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-hslider');
	        this.el.classList.add('widget-slider');
	        (this.$slider = $('<div />'))
	            .slider({
	            slide: this.handleSliderChange.bind(this),
	            stop: this.handleSliderChanged.bind(this)
	        })
	            .addClass('slider');
	        // Put the slider in a container
	        this.slider_container = document.createElement('div');
	        this.slider_container.classList.add('slider-container');
	        this.slider_container.appendChild(this.$slider[0]);
	        this.el.appendChild(this.slider_container);
	        this.readout = document.createElement('div');
	        this.el.appendChild(this.readout);
	        this.readout.classList.add('widget-readout');
	        this.readout.style.display = 'none';
	        this.listenTo(this.model, 'change:slider_color', function (sender, value) {
	            _this.$slider.find('a').css('background', value);
	        });
	        this.$slider.find('a').css('background', this.model.get('slider_color'));
	        // Set defaults.
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    SelectionSliderView.prototype.update = function (options) {
	        if (options === undefined || options.updated_view != this) {
	            var labels = this.model.get('_options_labels');
	            var max = labels.length - 1;
	            var min = 0;
	            this.$slider.slider('option', 'step', 1);
	            this.$slider.slider('option', 'max', max);
	            this.$slider.slider('option', 'min', min);
	            // WORKAROUND FOR JQUERY SLIDER BUG.
	            // The horizontal position of the slider handle
	            // depends on the value of the slider at the time
	            // of orientation change.  Before applying the new
	            // workaround, we set the value to the minimum to
	            // make sure that the horizontal placement of the
	            // handle in the vertical slider is always
	            // consistent.
	            var orientation = this.model.get('orientation');
	            this.$slider.slider('option', 'value', min);
	            this.$slider.slider('option', 'orientation', orientation);
	            // Use the right CSS classes for vertical & horizontal sliders
	            if (orientation === 'vertical') {
	                this.el.classList.remove('widget-hslider');
	                this.el.classList.remove('widget-inline-hbox');
	                this.el.classList.add('widget-vslider');
	                this.el.classList.add('widget-inline-vbox');
	            }
	            else {
	                this.el.classList.remove('widget-vslider');
	                this.el.classList.remove('widget-inline-vbox');
	                this.el.classList.add('widget-hslider');
	                this.el.classList.add('widget-inline-hbox');
	            }
	            var readout = this.model.get('readout');
	            if (readout) {
	                // this.$readout.show();
	                this.readout.style.display = '';
	            }
	            else {
	                // this.$readout.hide();
	                this.readout.style.display = 'none';
	            }
	            this.updateSelection();
	        }
	        return _super.prototype.update.call(this, options);
	    };
	    SelectionSliderView.prototype.events = function () {
	        return {
	            'slide': 'handleSliderChange',
	            'slidestop': 'handleSliderChanged'
	        };
	    };
	    SelectionSliderView.prototype.updateSelection = function () {
	        var index = this.model.get('index');
	        this.$slider.slider('option', 'value', index);
	        this.updateReadout(index);
	    };
	    SelectionSliderView.prototype.updateReadout = function (index) {
	        var value = this.model.get('_options_labels')[index];
	        this.readout.textContent = value;
	    };
	    /**
	     * Called when the slider value is changing.
	     */
	    SelectionSliderView.prototype.handleSliderChange = function (e, ui) {
	        this.updateReadout(ui.value);
	        // Only persist the value while sliding if the continuous_update
	        // trait is set to true.
	        if (this.model.get('continuous_update')) {
	            this.handleSliderChanged(e, ui);
	        }
	    };
	    /**
	     * Called when the slider value has changed.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    SelectionSliderView.prototype.handleSliderChanged = function (e, ui) {
	        this.updateReadout(ui.value);
	        this.model.set('index', ui.value, { updated_view: this });
	        this.touch();
	    };
	    return SelectionSliderView;
	}(widget_1.LabeledDOMWidgetView));
	exports.SelectionSliderView = SelectionSliderView;
	var MultipleSelectionModel = (function (_super) {
	    __extends(MultipleSelectionModel, _super);
	    function MultipleSelectionModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    MultipleSelectionModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'MultipleSelectionModel' });
	    };
	    return MultipleSelectionModel;
	}(SelectionModel));
	exports.MultipleSelectionModel = MultipleSelectionModel;
	var SelectMultipleModel = (function (_super) {
	    __extends(SelectMultipleModel, _super);
	    function SelectMultipleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectMultipleModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'SelectMultipleModel', _view_name: 'SelectMultipleView', rows: null });
	    };
	    return SelectMultipleModel;
	}(MultipleSelectionModel));
	exports.SelectMultipleModel = SelectMultipleModel;
	var SelectMultipleView = (function (_super) {
	    __extends(SelectMultipleView, _super);
	    function SelectMultipleView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    SelectMultipleView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('widget-select-multiple');
	        this.listbox.multiple = true;
	    };
	    SelectMultipleView.prototype.updateSelection = function () {
	        // Set selected values
	        var selected = this.model.get('index') || [];
	        var options = this.listbox.options;
	        this.listbox.selectedIndex = -1;
	        selected.forEach(function (i) {
	            // Don't use [] indexing to work around https://github.com/Microsoft/TypeScript/issues/14522
	            options.item(i).selected = true;
	        });
	    };
	    /**
	     * Handle when a new value is selected.
	     */
	    SelectMultipleView.prototype._handle_change = function () {
	        var index = Array.prototype.map
	            .call(this.listbox.selectedOptions || [], function (option) {
	            return option.index;
	        });
	        this.model.set('index', index);
	        this.touch();
	    };
	    return SelectMultipleView;
	}(SelectView));
	exports.SelectMultipleView = SelectMultipleView;
	var SelectionRangeSliderModel = (function (_super) {
	    __extends(SelectionRangeSliderModel, _super);
	    function SelectionRangeSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectionRangeSliderModel.prototype.defaults = function () {
	        return __assign({}, _super.prototype.defaults.call(this), { _model_name: 'SelectionSliderModel', _view_name: 'SelectionSliderView', orientation: 'horizontal', readout: true, continuous_update: true });
	    };
	    return SelectionRangeSliderModel;
	}(MultipleSelectionModel));
	exports.SelectionRangeSliderModel = SelectionRangeSliderModel;
	var SelectionRangeSliderView = (function (_super) {
	    __extends(SelectionRangeSliderView, _super);
	    function SelectionRangeSliderView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    SelectionRangeSliderView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.$slider.slider('option', 'range', true);
	    };
	    SelectionRangeSliderView.prototype.updateSelection = function () {
	        var index = this.model.get('index');
	        this.$slider.slider('option', 'values', index);
	        this.updateReadout(index);
	    };
	    SelectionRangeSliderView.prototype.updateReadout = function (index) {
	        var labels = this.model.get('_options_labels');
	        var minValue = labels[index[0]];
	        var maxValue = labels[index[1]];
	        this.readout.textContent = minValue + "-" + maxValue;
	    };
	    /**
	     * Called when the slider value is changing.
	     */
	    SelectionRangeSliderView.prototype.handleSliderChange = function (e, ui) {
	        this.updateReadout(ui.values);
	        // Only persist the value while sliding if the continuous_update
	        // trait is set to true.
	        if (this.model.get('continuous_update')) {
	            this.handleSliderChanged(e, ui);
	        }
	    };
	    /**
	     * Called when the slider value has changed.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    SelectionRangeSliderView.prototype.handleSliderChanged = function (e, ui) {
	        // The jqueryui documentation indicates ui.values doesn't exist on the slidestop event,
	        // but it appears that it actually does: https://github.com/jquery/jquery-ui/blob/ae31f2b3b478975f70526bdf3299464b9afa8bb1/ui/widgets/slider.js#L313
	        this.updateReadout(ui.values);
	        this.model.set('index', ui.values, { updated_view: this });
	        this.touch();
	    };
	    return SelectionRangeSliderView;
	}(SelectionSliderView));
	exports.SelectionRangeSliderView = SelectionRangeSliderView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selection.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selectioncontainer.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selectioncontainer.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget.js');
	var widget_box_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/widget_box.js');
	var tabpanel_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/tabpanel.js');
	var accordion_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/accordion.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.2.0/lib/index.js');
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.0/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.0/lib/index.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/utils.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	var SelectionContainerModel = (function (_super) {
	    __extends(SelectionContainerModel, _super);
	    function SelectionContainerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectionContainerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SelectionContainerModel',
	            selected_index: 0,
	            _titles: {}
	        });
	    };
	    return SelectionContainerModel;
	}(widget_box_1.BoxModel));
	exports.SelectionContainerModel = SelectionContainerModel;
	var AccordionModel = (function (_super) {
	    __extends(AccordionModel, _super);
	    function AccordionModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    AccordionModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'AccordionModel',
	            _view_name: 'AccordionView'
	        });
	    };
	    return AccordionModel;
	}(SelectionContainerModel));
	exports.AccordionModel = AccordionModel;
	// We implement our own tab widget since Phoshpor's TabPanel uses an absolute
	// positioning BoxLayout, but we want a more an html/css-based Panel layout.
	var JupyterPhosphorAccordionWidget = (function (_super) {
	    __extends(JupyterPhosphorAccordionWidget, _super);
	    function JupyterPhosphorAccordionWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        return _this;
	    }
	    /**
	     * Process the phosphor message.
	     *
	     * Any custom phosphor widget used inside a Jupyter widget should override
	     * the processMessage function like this.
	     */
	    JupyterPhosphorAccordionWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        this._view.processPhosphorMessage(msg);
	    };
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorAccordionWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    return JupyterPhosphorAccordionWidget;
	}(accordion_1.Accordion));
	exports.JupyterPhosphorAccordionWidget = JupyterPhosphorAccordionWidget;
	var AccordionView = (function (_super) {
	    __extends(AccordionView, _super);
	    function AccordionView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    AccordionView.prototype._createElement = function (tagName) {
	        this.pWidget = new JupyterPhosphorAccordionWidget({ view: this });
	        return this.pWidget.node;
	    };
	    AccordionView.prototype._setElement = function (el) {
	        if (this.el || el !== this.pWidget.node) {
	            // Accordions don't allow setting the element beyond the initial creation.
	            throw new Error('Cannot reset the DOM element.');
	        }
	        this.el = this.pWidget.node;
	        this.$el = $(this.pWidget.node);
	    };
	    AccordionView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.children_views = new widget_1.ViewList(this.add_child_view, this.remove_child_view, this);
	        this.listenTo(this.model, 'change:children', function () { return _this.updateChildren(); });
	        this.listenTo(this.model, 'change:selected_index', function () { return _this.update_selected_index(); });
	        this.listenTo(this.model, 'change:_titles', function () { return _this.update_titles(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    AccordionView.prototype.render = function () {
	        var _this = this;
	        _super.prototype.render.call(this);
	        var accordion = this.pWidget;
	        accordion.addClass('jupyter-widgets');
	        accordion.addClass('widget-accordion');
	        accordion.addClass('widget-container');
	        accordion.selection.selectionChanged.connect(function (sender) {
	            if (!_this.updatingChildren) {
	                _this.model.set('selected_index', accordion.selection.index);
	                _this.touch();
	            }
	        });
	        this.children_views.update(this.model.get('children'));
	        this.update_titles();
	        this.update_selected_index();
	    };
	    /**
	     * Update children
	     */
	    AccordionView.prototype.updateChildren = function () {
	        // While we are updating, the index may not be valid, so deselect the
	        // tabs before updating so we don't get spurious changes in the index,
	        // which would then set off another sync cycle.
	        this.updatingChildren = true;
	        this.pWidget.selection.index = -1;
	        this.children_views.update(this.model.get('children'));
	        this.update_selected_index();
	        this.updatingChildren = false;
	    };
	    /**
	     * Set header titles
	     */
	    AccordionView.prototype.update_titles = function () {
	        var widgets = this.pWidget.widgets;
	        var titles = this.model.get('_titles');
	        for (var i = 0; i < widgets.length; i++) {
	            if (titles[i] !== void 0) {
	                widgets[i].title.label = titles[i];
	            }
	        }
	    };
	    /**
	     * Make the rendering and selected index consistent.
	     */
	    AccordionView.prototype.update_selected_index = function () {
	        this.pWidget.selection.index = this.model.get('selected_index');
	    };
	    /**
	     * Called when a child is removed from children list.
	     */
	    AccordionView.prototype.remove_child_view = function (view) {
	        this.pWidget.removeWidget(view.pWidget);
	        view.remove();
	    };
	    /**
	     * Called when a child is added to children list.
	     */
	    AccordionView.prototype.add_child_view = function (model, index) {
	        // Placeholder widget to keep our position in the tab panel while we create the view.
	        var accordion = this.pWidget;
	        var placeholder = new widgets_1.Widget();
	        placeholder.title.label = this.model.get('_titles')[index] || '';
	        ;
	        accordion.addWidget(placeholder);
	        return this.create_child_view(model).then(function (view) {
	            var widget = view.pWidget;
	            widget.title.label = placeholder.title.label;
	            var collapse = accordion.collapseWidgets[accordion.indexOf(placeholder)];
	            collapse.widget = widget;
	            placeholder.dispose();
	            return view;
	        }).catch(utils.reject('Could not add child view to box', true));
	    };
	    AccordionView.prototype.remove = function () {
	        this.children_views = null;
	        _super.prototype.remove.call(this);
	    };
	    return AccordionView;
	}(widget_1.DOMWidgetView));
	exports.AccordionView = AccordionView;
	var TabModel = (function (_super) {
	    __extends(TabModel, _super);
	    function TabModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    TabModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'TabModel',
	            _view_name: 'TabView'
	        });
	    };
	    return TabModel;
	}(SelectionContainerModel));
	exports.TabModel = TabModel;
	// We implement our own tab widget since Phoshpor's TabPanel uses an absolute
	// positioning BoxLayout, but we want a more an html/css-based Panel layout.
	var JupyterPhosphorTabPanelWidget = (function (_super) {
	    __extends(JupyterPhosphorTabPanelWidget, _super);
	    function JupyterPhosphorTabPanelWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        // We want the view's messages to be the messages the tabContents panel
	        // gets.
	        messaging_1.MessageLoop.installMessageHook(_this.tabContents, function (handler, msg) {
	            // There may be times when we want the view's handler to be called
	            // *after* the message has been processed by the widget, in which
	            // case we'll need to revisit using a message hook.
	            _this._view.processPhosphorMessage(msg);
	            return true;
	        });
	        return _this;
	    }
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorTabPanelWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    return JupyterPhosphorTabPanelWidget;
	}(tabpanel_1.TabPanel));
	exports.JupyterPhosphorTabPanelWidget = JupyterPhosphorTabPanelWidget;
	var TabView = (function (_super) {
	    __extends(TabView, _super);
	    function TabView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this.updatingTabs = false;
	        return _this;
	    }
	    TabView.prototype._createElement = function (tagName) {
	        this.pWidget = new JupyterPhosphorTabPanelWidget({
	            view: this,
	        });
	        return this.pWidget.node;
	    };
	    TabView.prototype._setElement = function (el) {
	        if (this.el || el !== this.pWidget.node) {
	            // TabViews don't allow setting the element beyond the initial creation.
	            throw new Error('Cannot reset the DOM element.');
	        }
	        this.el = this.pWidget.node;
	        this.$el = $(this.pWidget.node);
	    };
	    /**
	     * Public constructor.
	     */
	    TabView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.childrenViews = new widget_1.ViewList(this.addChildView, function (view) { view.remove(); }, this);
	        this.listenTo(this.model, 'change:children', function () { return _this.updateTabs(); });
	        this.listenTo(this.model, 'change:_titles', function () { return _this.updateTitles(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    TabView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        var tabs = this.pWidget;
	        tabs.addClass('jupyter-widgets');
	        tabs.addClass('widget-container');
	        tabs.addClass('widget-tab');
	        tabs.tabsMovable = true;
	        tabs.tabBar.insertBehavior = 'none'; // needed for insert behavior, see below.
	        tabs.tabBar.currentChanged.connect(this._onTabChanged, this);
	        tabs.tabBar.tabMoved.connect(this._onTabMoved, this);
	        tabs.tabBar.addClass('widget-tab-bar');
	        tabs.tabContents.addClass('widget-tab-contents');
	        // TODO: expose this option in python
	        tabs.tabBar.tabsMovable = false;
	        this.updateTabs();
	        this.update();
	    };
	    /**
	     * Render tab views based on the current model's children.
	     */
	    TabView.prototype.updateTabs = function () {
	        // While we are updating, the index may not be valid, so deselect the
	        // tabs before updating so we don't get spurious changes in the index,
	        // which would then set off another sync cycle.
	        this.updatingTabs = true;
	        this.pWidget.currentIndex = -1;
	        this.childrenViews.update(this.model.get('children'));
	        this.pWidget.currentIndex = this.model.get('selected_index');
	        this.updatingTabs = false;
	    };
	    /**
	     * Called when a child is added to children list.
	     */
	    TabView.prototype.addChildView = function (model, index) {
	        // Placeholder widget to keep our position in the tab panel while we create the view.
	        var label = this.model.get('_titles')[index] || '';
	        var tabs = this.pWidget;
	        var placeholder = new widgets_1.Widget();
	        placeholder.title.label = label;
	        tabs.addWidget(placeholder);
	        return this.create_child_view(model).then(function (view) {
	            var widget = view.pWidget;
	            widget.title.label = placeholder.title.label;
	            widget.title.closable = true;
	            var i = algorithm_1.ArrayExt.firstIndexOf(tabs.widgets, placeholder);
	            // insert after placeholder so that if placholder is selected, the
	            // real widget will be selected now (this depends on the tab bar
	            // insert behavior)
	            tabs.insertWidget(i + 1, widget);
	            placeholder.dispose();
	            return view;
	        }).catch(utils.reject('Could not add child view to box', true));
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    TabView.prototype.update = function () {
	        // Update the selected index in the overall update method because it
	        // should be run after the tabs have been updated. Otherwise the
	        // selected index may not be a valid tab in the tab bar.
	        this.updateSelectedIndex();
	        return _super.prototype.update.call(this);
	    };
	    /**
	     * Updates the tab page titles.
	     */
	    TabView.prototype.updateTitles = function () {
	        var titles = this.model.get('_titles') || {};
	        algorithm_1.each(this.pWidget.widgets, function (widget, i) {
	            widget.title.label = titles[i] || '';
	        });
	    };
	    /**
	     * Updates the selected index.
	     */
	    TabView.prototype.updateSelectedIndex = function () {
	        this.pWidget.currentIndex = this.model.get('selected_index');
	    };
	    TabView.prototype.remove = function () {
	        this.childrenViews = null;
	        _super.prototype.remove.call(this);
	    };
	    TabView.prototype._onTabChanged = function (sender, args) {
	        if (!this.updatingTabs) {
	            this.model.set('selected_index', args.currentIndex);
	            this.touch();
	        }
	    };
	    /**
	     * Handle the `tabMoved` signal from the tab bar.
	     */
	    TabView.prototype._onTabMoved = function (sender, args) {
	        var children = this.model.get('children').slice();
	        algorithm_1.ArrayExt.move(children, args.fromIndex, args.toIndex);
	        this.model.set('children', children);
	        this.touch();
	    };
	    return TabView;
	}(widget_1.DOMWidgetView));
	exports.TabView = TabView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/widget_selectioncontainer.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/tabpanel.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/tabpanel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.2.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@1.2.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.1.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.2.0/lib/index.js');
	/**
	 * A panel where visible widgets are stacked atop one another.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[PanelLayout]].
	 */
	var EventedPanel = (function (_super) {
	    __extends(EventedPanel, _super);
	    function EventedPanel() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._widgetRemoved = new signaling_1.Signal(_this);
	        return _this;
	    }
	    Object.defineProperty(EventedPanel.prototype, "widgetRemoved", {
	        /**
	         * A signal emitted when a widget is removed from the panel.
	         */
	        get: function () {
	            return this._widgetRemoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    EventedPanel.prototype.onChildRemoved = function (msg) {
	        this._widgetRemoved.emit(msg.child);
	    };
	    return EventedPanel;
	}(widgets_1.Panel));
	exports.EventedPanel = EventedPanel;
	/**
	 * A widget which combines a `TabBar` and a `EventedPanel`.
	 *
	 * #### Notes
	 * This is a simple panel which handles the common case of a tab bar
	 * placed next to a content area. The selected tab controls the widget
	 * which is shown in the content area.
	 *
	 * For use cases which require more control than is provided by this
	 * panel, the `TabBar` widget may be used independently.
	 *
	 * TODO: Support setting the direction??
	 */
	var TabPanel = (function (_super) {
	    __extends(TabPanel, _super);
	    /**
	     * Construct a new tab panel.
	     *
	     * @param options - The options for initializing the tab panel.
	     */
	    function TabPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._currentChanged = new signaling_1.Signal(_this);
	        _this.addClass('p-TabPanel');
	        // Create the tab bar and contents panel.
	        _this.tabBar = new widgets_1.TabBar(options);
	        _this.tabBar.addClass('p-TabPanel-tabBar');
	        _this.tabContents = new EventedPanel();
	        _this.tabContents.addClass('p-TabPanel-tabContents');
	        // Connect the tab bar signal handlers.
	        _this.tabBar.tabMoved.connect(_this._onTabMoved, _this);
	        _this.tabBar.currentChanged.connect(_this._onCurrentChanged, _this);
	        _this.tabBar.tabCloseRequested.connect(_this._onTabCloseRequested, _this);
	        _this.tabBar.tabActivateRequested.connect(_this._onTabActivateRequested, _this);
	        // Connect the evented panel signal handlers.
	        _this.tabContents.widgetRemoved.connect(_this._onWidgetRemoved, _this);
	        // Create the layout.
	        var layout = new widgets_1.PanelLayout();
	        // Add the child widgets to the layout.
	        layout.addWidget(_this.tabBar);
	        layout.addWidget(_this.tabContents);
	        // Install the layout on the tab panel.
	        _this.layout = layout;
	        return _this;
	    }
	    Object.defineProperty(TabPanel.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current tab is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected tab is changed
	         * either through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current
	         * tab changes due to tabs being inserted, removed, or moved. It is
	         * only emitted when the actual current tab node is changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentIndex", {
	        /**
	         * Get the index of the currently selected tab.
	         *
	         * #### Notes
	         * This will be `-1` if no tab is selected.
	         */
	        get: function () {
	            return this.tabBar.currentIndex;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * #### Notes
	         * If the index is out of range, it will be set to `-1`.
	         */
	        set: function (value) {
	            this.tabBar.currentIndex = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentWidget", {
	        /**
	         * Get the currently selected widget.
	         *
	         * #### Notes
	         * This will be `null` if there is no selected tab.
	         */
	        get: function () {
	            var title = this.tabBar.currentTitle;
	            return title ? title.owner : null;
	        },
	        /**
	         * Set the currently selected widget.
	         *
	         * #### Notes
	         * If the widget is not in the panel, it will be set to `null`.
	         */
	        set: function (value) {
	            this.tabBar.currentTitle = value ? value.title : null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabsMovable", {
	        /**
	         * Get the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        get: function () {
	            return this.tabBar.tabsMovable;
	        },
	        /**
	         * Set the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        set: function (value) {
	            this.tabBar.tabsMovable = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the panel.
	         */
	        get: function () {
	            return this.tabContents.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a widget to the end of the tab panel.
	     *
	     * @param widget - The widget to add to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.addWidget = function (widget) {
	        this.insertWidget(this.widgets.length, widget);
	    };
	    /**
	     * Insert a widget into the tab panel at a specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.insertWidget = function (index, widget) {
	        if (widget !== this.currentWidget) {
	            widget.hide();
	        }
	        this.tabContents.insertWidget(index, widget);
	        this.tabBar.insertTab(index, widget.title);
	    };
	    /**
	     * Handle the `currentChanged` signal from the tab bar.
	     */
	    TabPanel.prototype._onCurrentChanged = function (sender, args) {
	        // Extract the previous and current title from the args.
	        var previousIndex = args.previousIndex, previousTitle = args.previousTitle, currentIndex = args.currentIndex, currentTitle = args.currentTitle;
	        // Extract the widgets from the titles.
	        var previousWidget = previousTitle ? previousTitle.owner : null;
	        var currentWidget = currentTitle ? currentTitle.owner : null;
	        // Hide the previous widget.
	        if (previousWidget) {
	            previousWidget.hide();
	        }
	        // Show the current widget.
	        if (currentWidget) {
	            currentWidget.show();
	        }
	        // Emit the `currentChanged` signal for the tab panel.
	        this._currentChanged.emit({
	            previousIndex: previousIndex, previousWidget: previousWidget, currentIndex: currentIndex, currentWidget: currentWidget
	        });
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	    };
	    /**
	     * Handle the `tabActivateRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabActivateRequested = function (sender, args) {
	        args.title.owner.activate();
	    };
	    /**
	     * Handle the `tabCloseRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabCloseRequested = function (sender, args) {
	        args.title.owner.close();
	    };
	    /**
	     * Handle the `tabMoved` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabMoved = function (sender, args) {
	        this.tabContents.insertWidget(args.toIndex, args.title.owner);
	    };
	    /**
	     * Handle the `widgetRemoved` signal from the stacked panel.
	     */
	    TabPanel.prototype._onWidgetRemoved = function (sender, widget) {
	        this.tabBar.removeTab(widget.title);
	    };
	    return TabPanel;
	}(widgets_1.Widget));
	exports.TabPanel = TabPanel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/tabpanel.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/accordion.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/accordion.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@1.2.1/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.2.0/lib/index.js');
	var currentselection_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/currentselection.js');
	/**
	 * The class name added to Collapse instances.
	 */
	var COLLAPSE_CLASS = 'p-Collapse';
	/**
	 * The class name added to a Collapse's header.
	 */
	var COLLAPSE_HEADER_CLASS = 'p-Collapse-header';
	/**
	 * The class name added to a Collapse's contents.
	 */
	var COLLAPSE_CONTENTS_CLASS = 'p-Collapse-contents';
	/**
	 * The class name added to a Collapse when it is opened
	 */
	var COLLAPSE_CLASS_OPEN = 'p-Collapse-open';
	/**
	 * A panel that supports a collapsible header, made from the widget's title.
	 * Clicking on the title expands or contracts the widget.
	 */
	var Collapse = (function (_super) {
	    __extends(Collapse, _super);
	    function Collapse(options) {
	        var _this = _super.call(this, options) || this;
	        _this._collapseChanged = new signaling_1.Signal(_this);
	        _this.addClass(COLLAPSE_CLASS);
	        _this._header = new widgets_1.Widget();
	        _this._header.addClass(COLLAPSE_HEADER_CLASS);
	        _this._header.node.addEventListener('click', _this);
	        _this._content = new widgets_1.Panel();
	        _this._content.addClass(COLLAPSE_CONTENTS_CLASS);
	        var layout = new widgets_1.PanelLayout();
	        _this.layout = layout;
	        layout.addWidget(_this._header);
	        layout.addWidget(_this._content);
	        if (options.widget) {
	            _this.widget = options.widget;
	        }
	        _this.collapsed = false;
	        return _this;
	    }
	    Collapse.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        this._header = null;
	        this._widget = null;
	        this._content = null;
	    };
	    Object.defineProperty(Collapse.prototype, "widget", {
	        get: function () {
	            return this._widget;
	        },
	        set: function (widget) {
	            var oldWidget = this._widget;
	            if (oldWidget) {
	                oldWidget.disposed.disconnect(this._onChildDisposed, this);
	                oldWidget.title.changed.disconnect(this._onTitleChanged, this);
	                oldWidget.parent = null;
	            }
	            this._widget = widget;
	            widget.disposed.connect(this._onChildDisposed, this);
	            widget.title.changed.connect(this._onTitleChanged, this);
	            this._onTitleChanged(widget.title);
	            this._content.addWidget(widget);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Collapse.prototype, "collapsed", {
	        get: function () {
	            return this._collapsed;
	        },
	        set: function (value) {
	            // TODO: should we have this check here?
	            if (value === this._collapsed) {
	                return;
	            }
	            if (value) {
	                this._collapse();
	            }
	            else {
	                this._uncollapse();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Collapse.prototype.toggle = function () {
	        this.collapsed = !this.collapsed;
	    };
	    Object.defineProperty(Collapse.prototype, "collapseChanged", {
	        get: function () {
	            return this._collapseChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Collapse.prototype._collapse = function () {
	        this._collapsed = true;
	        if (this._content) {
	            this._content.hide();
	        }
	        this.removeClass(COLLAPSE_CLASS_OPEN);
	        this._collapseChanged.emit(void 0);
	    };
	    Collapse.prototype._uncollapse = function () {
	        this._collapsed = false;
	        if (this._content) {
	            this._content.show();
	        }
	        this.addClass(COLLAPSE_CLASS_OPEN);
	        this._collapseChanged.emit(void 0);
	    };
	    /**
	     * Handle the DOM events for the Collapse widget.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    Collapse.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(event);
	                break;
	            default:
	                break;
	        }
	    };
	    Collapse.prototype._evtClick = function (event) {
	        this.toggle();
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    Collapse.prototype._onTitleChanged = function (sender) {
	        this._header.node.textContent = this._widget.title.label;
	    };
	    Collapse.prototype._onChildDisposed = function (sender) {
	        this.dispose();
	    };
	    return Collapse;
	}(widgets_1.Widget));
	exports.Collapse = Collapse;
	/**
	 * The class name added to Accordion instances.
	 */
	var ACCORDION_CLASS = 'p-Accordion';
	/**
	 * The class name added to an Accordion child.
	 */
	var ACCORDION_CHILD_CLASS = 'p-Accordion-child';
	var ACCORDION_CHILD_ACTIVE_CLASS = 'p-Accordion-child-active';
	/**
	 * A panel that supports a collapsible header, made from the widget's title.
	 * Clicking on the title expands or contracts the widget.
	 */
	var Accordion = (function (_super) {
	    __extends(Accordion, _super);
	    function Accordion(options) {
	        var _this = _super.call(this, options) || this;
	        _this._selection = new currentselection_1.Selection(_this.widgets);
	        _this._selection.selectionChanged.connect(_this._onSelectionChanged, _this);
	        _this.addClass(ACCORDION_CLASS);
	        return _this;
	    }
	    Object.defineProperty(Accordion.prototype, "collapseWidgets", {
	        /**
	         * A read-only sequence of the widgets in the panel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        /*  get widgets(): ISequence<Widget> {
	            return new ArraySequence(toArray(map((this.layout as PanelLayout).widgets, (w: Collapse) => w.widget)));
	          }
	        */
	        get: function () {
	            return this.layout.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Accordion.prototype, "selection", {
	        get: function () {
	            return this._selection;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Accordion.prototype.indexOf = function (widget) {
	        return algorithm_1.ArrayExt.findFirstIndex(this.collapseWidgets, function (w) { return w.widget === widget; });
	    };
	    /**
	     * Add a widget to the end of the accordion.
	     *
	     * @param widget - The widget to add to the accordion.
	     *
	     * @returns The Collapse widget wrapping the added widget.
	     * #### Notes
	     * The widget will be wrapped in a CollapsedWidget.
	     */
	    Accordion.prototype.addWidget = function (widget) {
	        var collapse = this._wrapWidget(widget);
	        collapse.collapsed = true;
	        _super.prototype.addWidget.call(this, collapse);
	        this._selection.adjustSelectionForInsert(this.widgets.length - 1, collapse);
	        return collapse;
	    };
	    /**
	     * Insert a widget at the specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the accordion.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     */
	    Accordion.prototype.insertWidget = function (index, widget) {
	        var collapse = this._wrapWidget(widget);
	        collapse.collapsed = true;
	        _super.prototype.insertWidget.call(this, index, collapse);
	        this._selection.adjustSelectionForInsert(index, collapse);
	    };
	    Accordion.prototype.removeWidget = function (widget) {
	        var index = this.indexOf(widget);
	        if (index >= 0) {
	            var collapse = this.collapseWidgets[index];
	            widget.parent = null;
	            collapse.dispose();
	            this._selection.adjustSelectionForRemove(index, null);
	        }
	    };
	    Accordion.prototype._wrapWidget = function (widget) {
	        var collapse = new Collapse({ widget: widget });
	        collapse.addClass(ACCORDION_CHILD_CLASS);
	        collapse.collapseChanged.connect(this._onCollapseChange, this);
	        return collapse;
	    };
	    Accordion.prototype._onCollapseChange = function (sender) {
	        if (!sender.collapsed) {
	            this._selection.value = sender;
	        }
	        else if (this._selection.value === sender && sender.collapsed) {
	            this._selection.value = null;
	        }
	    };
	    Accordion.prototype._onSelectionChanged = function (sender, change) {
	        // Collapse previous widget, open current widget
	        var pv = change.previousValue;
	        var cv = change.currentValue;
	        if (pv) {
	            pv.collapsed = true;
	            pv.removeClass(ACCORDION_CHILD_ACTIVE_CLASS);
	        }
	        if (cv) {
	            cv.collapsed = false;
	            cv.addClass(ACCORDION_CHILD_ACTIVE_CLASS);
	        }
	    };
	    return Accordion;
	}(widgets_1.Panel));
	exports.Accordion = Accordion;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/accordion.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/currentselection.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/currentselection.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A variety of convenience methods for maintaining a current selection
	 */
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.1.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@1.2.1/lib/index.js');
	var Selection = (function () {
	    function Selection(sequence, options) {
	        if (options === void 0) { options = {}; }
	        this._array = null;
	        this._value = null;
	        this._previousValue = null;
	        this._selectionChanged = new signaling_1.Signal(this);
	        this._array = sequence;
	        this._insertBehavior = options.insertBehavior || 'select-item-if-needed';
	        this._removeBehavior = options.removeBehavior || 'select-item-after';
	    }
	    Object.defineProperty(Selection.prototype, "selectionChanged", {
	        /**
	         * A signal emitted when the current item is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected item is changed either
	         * through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current item
	         * changes due to other items being inserted, removed, or moved, but the
	         * current item remains the same. It is only emitted when the actual current
	         * item is changed.
	         */
	        get: function () {
	            return this._selectionChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Adjust for setting an item.
	     *
	     * This should be called *after* the set.
	     *
	     * @param index - The index set.
	     * @param oldValue - The old value at the index.
	     */
	    Selection.prototype.adjustSelectionForSet = function (index) {
	        // We just need to send a signal if the currentValue changed.
	        // Get the current index and value.
	        var pi = this.index;
	        var pv = this.value;
	        // Exit early if this doesn't affect the selection
	        if (index !== pi) {
	            return;
	        }
	        this._updateSelectedValue();
	        var cv = this.value;
	        // The previous item is now null, since it is no longer in the array.
	        this._previousValue = null;
	        // Send signal if there was a change
	        if (pv !== cv) {
	            // Emit the current changed signal.
	            this._selectionChanged.emit({
	                previousIndex: pi, previousValue: pv,
	                currentIndex: pi, currentValue: cv
	            });
	        }
	    };
	    Object.defineProperty(Selection.prototype, "value", {
	        /**
	         * Get the currently selected item.
	         *
	         * #### Notes
	         * This will be `null` if no item is selected.
	         */
	        get: function () {
	            return this._value;
	        },
	        /**
	         * Set the currently selected item.
	         *
	         * #### Notes
	         * If the item does not exist in the vector, the currentValue will be set to
	         * `null`. This selects the first entry equal to the desired item.
	         */
	        set: function (value) {
	            if (value === null) {
	                this.index = -1;
	            }
	            else {
	                this.index = algorithm_1.ArrayExt.firstIndexOf(this._array, value);
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Selection.prototype, "index", {
	        /**
	         * Get the index of the currently selected item.
	         *
	         * #### Notes
	         * This will be `-1` if no item is selected.
	         */
	        get: function () {
	            return this._index;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * @param index - The index to select.
	         *
	         * #### Notes
	         * If the value is out of range, the index will be set to `-1`, which
	         * indicates no item is selected.
	         */
	        set: function (index) {
	            // Coerce the value to an index.
	            var i = Math.floor(index);
	            if (i < 0 || i >= this._array.length) {
	                i = -1;
	            }
	            // Bail early if the index will not change.
	            if (this._index === i) {
	                return;
	            }
	            // Look up the previous index and item.
	            var pi = this._index;
	            var pv = this._value;
	            // Update the state
	            this._index = i;
	            this._updateSelectedValue();
	            this._previousValue = pv;
	            // Emit the current changed signal.
	            this._selectionChanged.emit({
	                previousIndex: pi, previousValue: pv,
	                currentIndex: i, currentValue: this._value
	            });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Selection.prototype, "insertBehavior", {
	        /**
	         * Get the selection behavior when inserting a tab.
	         */
	        get: function () {
	            return this._insertBehavior;
	        },
	        /**
	         * Set the selection behavior when inserting a tab.
	         */
	        set: function (value) {
	            this._insertBehavior = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Selection.prototype, "removeBehavior", {
	        /**
	         * Get the selection behavior when removing a tab.
	         */
	        get: function () {
	            return this._removeBehavior;
	        },
	        /**
	         * Set the selection behavior when removing a tab.
	         */
	        set: function (value) {
	            this._removeBehavior = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Adjust the current index for a tab insert operation.
	     *
	     * @param i - The new index of the inserted item.
	     * @param j - The inserted item.
	     *
	     * #### Notes
	     * This method accounts for the tab bar's insertion behavior when adjusting
	     * the current index and emitting the changed signal. This should be called
	     * after the insertion.
	     */
	    Selection.prototype.adjustSelectionForInsert = function (i, item) {
	        // Lookup commonly used variables.
	        var cv = this._value;
	        var ci = this._index;
	        var bh = this._insertBehavior;
	        // Handle the behavior where the new item is always selected,
	        // or the behavior where the new item is selected if needed.
	        if (bh === 'select-item' || (bh === 'select-item-if-needed' && ci === -1)) {
	            this._index = i;
	            this._value = item;
	            this._previousValue = cv;
	            this._selectionChanged.emit({
	                previousIndex: ci, previousValue: cv,
	                currentIndex: i, currentValue: item
	            });
	            return;
	        }
	        // Otherwise, silently adjust the current index if needed.
	        if (ci >= i) {
	            this._index++;
	        }
	    };
	    /**
	     * Adjust the current index for move operation.
	     *
	     * @param i - The previous index of the item.
	     * @param j - The new index of the item.
	     *
	     * #### Notes
	     * This method will not cause the actual current item to change. It silently
	     * adjusts the current index to account for the given move.
	     */
	    Selection.prototype.adjustSelectionForMove = function (i, j) {
	        if (this._index === i) {
	            this._index = j;
	        }
	        else if (this._index < i && this._index >= j) {
	            this._index++;
	        }
	        else if (this._index > i && this._index <= j) {
	            this._index--;
	        }
	    };
	    /**
	     * Clear the selection and history.
	     */
	    Selection.prototype.clearSelection = function () {
	        // Get the current index and item.
	        var pi = this._index;
	        var pv = this._value;
	        // Reset the current index and previous item.
	        this._index = -1;
	        this._value = null;
	        this._previousValue = null;
	        // If no item was selected, there's nothing else to do.
	        if (pi === -1) {
	            return;
	        }
	        // Emit the current changed signal.
	        this._selectionChanged.emit({
	            previousIndex: pi, previousValue: pv,
	            currentIndex: -1, currentValue: null
	        });
	    };
	    /**
	     * Adjust the current index for an item remove operation.
	     *
	     * @param i - The former index of the removed item.
	     * @param item - The removed item.
	     *
	     * #### Notes
	     * This method accounts for the remove behavior when adjusting the current
	     * index and emitting the changed signal. It should be called after the item
	     * is removed.
	     */
	    Selection.prototype.adjustSelectionForRemove = function (i, item) {
	        // Lookup commonly used variables.
	        var ci = this._index;
	        var bh = this._removeBehavior;
	        // Silently adjust the index if the current item is not removed.
	        if (ci !== i) {
	            if (ci > i) {
	                this._index--;
	            }
	            return;
	        }
	        // No item gets selected if the vector is empty.
	        if (this._array.length === 0) {
	            // Reset the current index and previous item.
	            this._index = -1;
	            this._value = null;
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: -1, currentValue: null
	            });
	            return;
	        }
	        // Handle behavior where the next sibling item is selected.
	        if (bh === 'select-item-after') {
	            this._index = Math.min(i, this._array.length - 1);
	            this._updateSelectedValue();
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: this._index, currentValue: this._value
	            });
	            return;
	        }
	        // Handle behavior where the previous sibling item is selected.
	        if (bh === 'select-item-before') {
	            this._index = Math.max(0, i - 1);
	            this._updateSelectedValue();
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: this._index, currentValue: this._value
	            });
	            return;
	        }
	        // Handle behavior where the previous history item is selected.
	        if (bh === 'select-previous-item') {
	            if (this._previousValue) {
	                this.value = this._previousValue;
	            }
	            else {
	                this._index = Math.min(i, this._array.length - 1);
	                this._updateSelectedValue();
	            }
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: this._index, currentValue: this.value
	            });
	            return;
	        }
	        // Otherwise, no item gets selected.
	        this._index = -1;
	        this._value = null;
	        this._previousValue = null;
	        this._selectionChanged.emit({
	            previousIndex: i, previousValue: item,
	            currentIndex: -1, currentValue: null
	        });
	    };
	    /**
	     * Set the current value based on the current index.
	     */
	    Selection.prototype._updateSelectedValue = function () {
	        var i = this._index;
	        this._value = i !== -1 ? this._array[i] : null;
	    };
	    return Selection;
	}());
	exports.Selection = Selection;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/lib/phosphor/currentselection.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/package.json **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.6/package.json', function (module, exports, __jupyter_require__) {
	module.exports = {
		"_args": [
			[
				{
					"raw": "jupyter-js-widgets@3.0.0-alpha.6",
					"scope": null,
					"escapedName": "jupyter-js-widgets",
					"name": "jupyter-js-widgets",
					"rawSpec": "3.0.0-alpha.6",
					"spec": "3.0.0-alpha.6",
					"type": "version"
				},
				"/Users/haichit/programs/3d/nglview/js"
			]
		],
		"_from": "jupyter-js-widgets@3.0.0-alpha.6",
		"_id": "jupyter-js-widgets@3.0.0-alpha.6",
		"_inCache": true,
		"_location": "/jupyter-js-widgets",
		"_nodeVersion": "7.10.0",
		"_npmOperationalInternal": {
			"host": "packages-12-west.internal.npmjs.com",
			"tmp": "tmp/jupyter-js-widgets-3.0.0-alpha.6.tgz_1495144202876_0.16500782896764576"
		},
		"_npmUser": {
			"name": "jasongrout",
			"email": "jason@jasongrout.org"
		},
		"_npmVersion": "4.2.0",
		"_phantomChildren": {
			"@phosphor/algorithm": "1.1.1",
			"@phosphor/coreutils": "1.1.1",
			"@phosphor/disposable": "1.1.1",
			"@phosphor/messaging": "1.2.1",
			"@phosphor/signaling": "1.2.1",
			"@types/minimist": "1.2.0",
			"@types/text-encoding": "0.0.30",
			"minimist": "1.2.0",
			"moment": "2.18.1",
			"path-posix": "1.0.0",
			"url-parse": "1.1.9"
		},
		"_requested": {
			"raw": "jupyter-js-widgets@3.0.0-alpha.6",
			"scope": null,
			"escapedName": "jupyter-js-widgets",
			"name": "jupyter-js-widgets",
			"rawSpec": "3.0.0-alpha.6",
			"spec": "3.0.0-alpha.6",
			"type": "version"
		},
		"_requiredBy": [
			"/"
		],
		"_resolved": "https://registry.npmjs.org/jupyter-js-widgets/-/jupyter-js-widgets-3.0.0-alpha.6.tgz",
		"_shasum": "a55523fa17907f76994885b38af03cdc4c878b27",
		"_shrinkwrap": null,
		"_spec": "jupyter-js-widgets@3.0.0-alpha.6",
		"_where": "/Users/haichit/programs/3d/nglview/js",
		"author": {
			"name": "Project Jupyter"
		},
		"bugs": {
			"url": "https://github.com/jupyter-widgets/ipywidgets/issues"
		},
		"dependencies": {
			"@jupyterlab/services": "^0.44.0",
			"@phosphor/algorithm": "^1.1.0",
			"@phosphor/domutils": "^1.1.0",
			"@phosphor/messaging": "^1.2.0",
			"@phosphor/widgets": "^1.2.0",
			"@types/backbone": "^1.3.33",
			"@types/semver": "^5.3.30",
			"ajv": "^4.9.0",
			"backbone": "1.2.0",
			"base64-js": "1.2.0",
			"d3-format": "^0.5.1",
			"font-awesome": "^4.5.0",
			"jquery": "^3.1.1",
			"jquery-ui": "^1.12.1",
			"jupyter-widgets-schema": "^0.3.0-beta.2",
			"lolex": "^1.4.0",
			"scriptjs": "^2.5.8",
			"semver": "^5.1.0",
			"underscore": "^1.8.3"
		},
		"description": "Jupyter interactive widgets",
		"devDependencies": {
			"@types/expect.js": "^0.3.29",
			"@types/mathjax": "0.0.31",
			"@types/mocha": "^2.2.41",
			"@types/requirejs": "^2.1.28",
			"chai": "^4.0.0-canary.2",
			"cpx": "^1.5.0",
			"css-loader": "^0.23.1",
			"es6-promise": "^3.1.2",
			"expect.js": "^0.3.1",
			"file-loader": "^0.8.5",
			"istanbul-instrumenter-loader": "^2.0.0",
			"json-loader": "^0.5.4",
			"karma": "^1.6.0",
			"karma-chrome-launcher": "^2.0.0",
			"karma-coverage": "^1.0.0",
			"karma-firefox-launcher": "^1.0.1",
			"karma-ie-launcher": "^1.0.0",
			"karma-mocha": "^1.3.0",
			"karma-mocha-reporter": "^2.2.3",
			"karma-webpack": "^2.0.3",
			"mocha": "^3.3.0",
			"npm-run-all": "^1.5.1",
			"postcss-cli": "^2.6.0",
			"postcss-cssnext": "^2.8.0",
			"postcss-import": "^8.1.2",
			"postcss-loader": "^1.3.2",
			"rimraf": "^2.4.1",
			"sinon": "^2.1.0",
			"spawn-sync": "^1.0.14",
			"style-loader": "^0.13.1",
			"typescript": "~2.3.1",
			"url-loader": "^0.5.7",
			"webpack": "^1.12.11"
		},
		"directories": {},
		"dist": {
			"shasum": "a55523fa17907f76994885b38af03cdc4c878b27",
			"tarball": "https://registry.npmjs.org/jupyter-js-widgets/-/jupyter-js-widgets-3.0.0-alpha.6.tgz"
		},
		"files": [
			"lib/**/*.d.ts",
			"lib/**/*.js",
			"css/*.css",
			"dist/"
		],
		"homepage": "https://github.com/jupyter-widgets/ipywidgets#readme",
		"license": "BSD-3-Clause",
		"main": "lib/index.js",
		"maintainers": [
			{
				"name": "sylvaincorlay",
				"email": "sylvain.corlay@gmail.com"
			}
		],
		"name": "jupyter-js-widgets",
		"optionalDependencies": {},
		"readme": "Jupyter JS Widgets\n==================\n\nInteractive widgets for the Jupyter notebook.\n\nThis packages contains the implementation of the core Jupyter interactive\nwidgets.\n\nThe reference Python backend, `ipywidgets` is available\n[here](https://github.com/jupyter-widgets/ipywidgets), with more examples.\n\nPackage Install\n---------------\n\n**Prerequisites**\n- [node](http://nodejs.org/)\n\nRun the following command **at the root of this repository**.\n\n```bash\nnpm install --save jupyter-js-widgets\n```\n",
		"readmeFilename": "README.md",
		"repository": {
			"type": "git",
			"url": "git+https://github.com/jupyter-widgets/ipywidgets.git"
		},
		"scripts": {
			"build": "npm run build:src && npm run build:src-embed && npm run build:css && webpack",
			"build:css": "postcss --use postcss-import --use postcss-cssnext -o css/widgets.built.css css/widgets.css",
			"build:src": "tsc --project src",
			"build:src-embed": "tsc --project src-embed",
			"build:test": "tsc --project test/src && webpack --config test/webpack.conf.js",
			"clean": "npm run clean:src && npm run clean:embed",
			"clean:embed": "rimraf lib-embed",
			"clean:src": "rimraf lib",
			"postinstall": "npm dedupe",
			"prepublish": "npm run build",
			"test": "npm run test:unit && npm run test:examples",
			"test:coverage": "npm run build:test && webpack --config test/webpack-cov.conf.js && karma start test/karma-cov.conf.js",
			"test:example:web2": "cd examples/web2 && npm install && npm run test:default",
			"test:example:web3": "cd examples/web3 && npm install && npm run test:default",
			"test:example:web4": "cd examples/web4 && npm install && npm run test:default",
			"test:example:web5": "cd examples/web5 && npm install && npm run test:default",
			"test:examples": "npm run test:examples:chrome && npm run test:examples:firefox",
			"test:examples:chrome": "npm-run-all \"test:example:*\"",
			"test:examples:firefox": "npm-run-all \"test:example:* -- -- --browsers Firefox\"",
			"test:unit": "npm run test:unit:firefox && npm run test:unit:chrome",
			"test:unit:chrome": "npm run test:unit:default -- --browsers=Chrome",
			"test:unit:default": "npm run build:test && karma start test/karma.conf.js --log-level debug",
			"test:unit:firefox": "npm run test:unit:default -- --browsers=Firefox",
			"test:unit:ie": "npm run test:unit:default -- --browsers=IE"
		},
		"typings": "lib/index.d.ts",
		"version": "3.0.0-alpha.6"
	};
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.6/package.json **/


/** START DEFINE BLOCK for ngl@0.10.3/dist/ngl.js **/
jupyter.define('ngl@0.10.3/dist/ngl.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(setImmediate) {!function(t,e){ true?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.NGL=t.NGL||{})}(this,function(t){"use strict";function e(){}function i(t,e){return function(){t.apply(e,arguments)}}function r(t){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof t)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],u(t,this)}function n(t,e){for(;3===t._state;)t=t._value;if(0===t._state)return void t._deferreds.push(e);t._handled=!0,mu(function(){var i=1===t._state?e.onFulfilled:e.onRejected;if(null===i)return void(1===t._state?o:a)(e.promise,t._value);var r;try{r=i(t._value)}catch(t){return void a(e.promise,t)}o(e.promise,r)})}function o(t,e){try{if(e===t)throw new TypeError("A promise cannot be resolved with itself.");if(e&&("object"==typeof e||"function"==typeof e)){var n=e.then;if(e instanceof r)return t._state=3,t._value=e,void s(t);if("function"==typeof n)return void u(i(n,e),t)}t._state=1,t._value=e,s(t)}catch(e){a(t,e)}}function a(t,e){t._state=2,t._value=e,s(t)}function s(t){2===t._state&&0===t._deferreds.length&&mu(function(){t._handled||gu(t._value)});for(var e=0,i=t._deferreds.length;e<i;e++)n(t,t._deferreds[e]);t._deferreds=null}function c(t,e,i){this.onFulfilled="function"==typeof t?t:null,this.onRejected="function"==typeof e?e:null,this.promise=i}function u(t,e){var i=!1;try{t(function(t){i||(i=!0,o(e,t))},function(t){i||(i=!0,a(e,t))})}catch(t){if(i)return;i=!0,a(e,t)}}function h(){}function l(t,e){this.x=t||0,this.y=e||0}function p(t,e,i,r,n,o,a,s,c,u){Object.defineProperty(this,"id",{value:_l++}),this.uuid=xl.generateUUID(),this.name="",this.image=void 0!==t?t:p.DEFAULT_IMAGE,this.mipmaps=[],this.mapping=void 0!==e?e:p.DEFAULT_MAPPING,this.wrapS=void 0!==i?i:Ah,this.wrapT=void 0!==r?r:Ah,this.magFilter=void 0!==n?n:Ch,this.minFilter=void 0!==o?o:Lh,this.anisotropy=void 0!==c?c:1,this.format=void 0!==a?a:Wh,this.type=void 0!==s?s:Rh,this.offset=new l(0,0),this.repeat=new l(1,1),this.generateMipmaps=!0,this.premultiplyAlpha=!1,this.flipY=!0,this.unpackAlignment=4,this.encoding=void 0!==u?u:ll,this.version=0,this.onUpdate=null}function d(t,e,i,r){this.x=t||0,this.y=e||0,this.z=i||0,this.w=void 0!==r?r:1}function f(t,e,i){this.uuid=xl.generateUUID(),this.width=t,this.height=e,this.scissor=new d(0,0,t,e),this.scissorTest=!1,this.viewport=new d(0,0,t,e),void 0===(i=i||{}).minFilter&&(i.minFilter=Ch),this.texture=new p(void 0,void 0,i.wrapS,i.wrapT,i.magFilter,i.minFilter,i.format,i.type,i.anisotropy,i.encoding),this.depthBuffer=void 0===i.depthBuffer||i.depthBuffer,this.stencilBuffer=void 0===i.stencilBuffer||i.stencilBuffer,this.depthTexture=void 0!==i.depthTexture?i.depthTexture:null}function m(t,e,i,r){this._x=t||0,this._y=e||0,this._z=i||0,this._w=void 0!==r?r:1}function g(t,e,i){this.x=t||0,this.y=e||0,this.z=i||0}function v(){this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],arguments.length>0&&console.error("THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.")}function y(t,e,i,r,n,o,a,s,c,u,h,l){p.call(this,null,o,a,s,c,u,r,n,h,l),this.image={data:t,width:e,height:i},this.magFilter=void 0!==c?c:Ph,this.minFilter=void 0!==u?u:Ph,this.generateMipmaps=!1,this.flipY=!1,this.unpackAlignment=1}function b(t,e,i,r,n,o,a,s,c,u){t=void 0!==t?t:[],e=void 0!==e?e:gh,p.call(this,t,e,i,r,n,o,a,s,c,u),this.flipY=!1}function x(){this.seq=[],this.map={}}function _(t,e,i){var r=t[0];if(r<=0||r>0)return t;var n=e*i,o=Al[n];if(void 0===o&&(o=new Float32Array(n),Al[n]=o),0!==e){r.toArray(o,0);for(var a=1,s=0;a!==e;++a)s+=i,t[a].toArray(o,s)}return o}function w(t,e){var i=Ml[e];void 0===i&&(i=new Int32Array(e),Ml[e]=i);for(var r=0;r!==e;++r)i[r]=t.allocTextureUnit();return i}function S(t,e){t.uniform1f(this.addr,e)}function A(t,e){t.uniform1i(this.addr,e)}function M(t,e){void 0===e.x?t.uniform2fv(this.addr,e):t.uniform2f(this.addr,e.x,e.y)}function P(t,e){void 0!==e.x?t.uniform3f(this.addr,e.x,e.y,e.z):void 0!==e.r?t.uniform3f(this.addr,e.r,e.g,e.b):t.uniform3fv(this.addr,e)}function T(t,e){void 0===e.x?t.uniform4fv(this.addr,e):t.uniform4f(this.addr,e.x,e.y,e.z,e.w)}function E(t,e){t.uniformMatrix2fv(this.addr,!1,e.elements||e)}function C(t,e){void 0===e.elements?t.uniformMatrix3fv(this.addr,!1,e):(Tl.set(e.elements),t.uniformMatrix3fv(this.addr,!1,Tl))}function I(t,e){void 0===e.elements?t.uniformMatrix4fv(this.addr,!1,e):(Pl.set(e.elements),t.uniformMatrix4fv(this.addr,!1,Pl))}function L(t,e,i){var r=i.allocTextureUnit();t.uniform1i(this.addr,r),i.setTexture2D(e||wl,r)}function R(t,e,i){var r=i.allocTextureUnit();t.uniform1i(this.addr,r),i.setTextureCube(e||Sl,r)}function O(t,e){t.uniform2iv(this.addr,e)}function D(t,e){t.uniform3iv(this.addr,e)}function N(t,e){t.uniform4iv(this.addr,e)}function k(t){switch(t){case 5126:return S;case 35664:return M;case 35665:return P;case 35666:return T;case 35674:return E;case 35675:return C;case 35676:return I;case 35678:return L;case 35680:return R;case 5124:case 35670:return A;case 35667:case 35671:return O;case 35668:case 35672:return D;case 35669:case 35673:return N}}function B(t,e){t.uniform1fv(this.addr,e)}function F(t,e){t.uniform1iv(this.addr,e)}function z(t,e){t.uniform2fv(this.addr,_(e,this.size,2))}function U(t,e){t.uniform3fv(this.addr,_(e,this.size,3))}function j(t,e){t.uniform4fv(this.addr,_(e,this.size,4))}function G(t,e){t.uniformMatrix2fv(this.addr,!1,_(e,this.size,4))}function V(t,e){t.uniformMatrix3fv(this.addr,!1,_(e,this.size,9))}function $(t,e){t.uniformMatrix4fv(this.addr,!1,_(e,this.size,16))}function H(t,e,i){var r=e.length,n=w(i,r);t.uniform1iv(this.addr,n);for(var o=0;o!==r;++o)i.setTexture2D(e[o]||wl,n[o])}function W(t,e,i){var r=e.length,n=w(i,r);t.uniform1iv(this.addr,n);for(var o=0;o!==r;++o)i.setTextureCube(e[o]||Sl,n[o])}function X(t){switch(t){case 5126:return B;case 35664:return z;case 35665:return U;case 35666:return j;case 35674:return G;case 35675:return V;case 35676:return $;case 35678:return H;case 35680:return W;case 5124:case 35670:return F;case 35667:case 35671:return O;case 35668:case 35672:return D;case 35669:case 35673:return N}}function q(t,e,i){this.id=t,this.addr=i,this.setValue=k(e.type)}function Y(t,e,i){this.id=t,this.addr=i,this.size=e.size,this.setValue=X(e.type)}function Z(t){this.id=t,x.call(this)}function K(t,e){t.seq.push(e),t.map[e.id]=e}function Q(t,e,i){var r=t.name,n=r.length;for(El.lastIndex=0;;){var o=El.exec(r),a=El.lastIndex,s=o[1],c="]"===o[2],u=o[3];if(c&&(s|=0),void 0===u||"["===u&&a+2===n){K(i,void 0===u?new q(s,t,e):new Y(s,t,e));break}var h=i.map[s];void 0===h&&K(i,h=new Z(s)),i=h}}function J(t,e,i){var r=this;x.call(this),this.renderer=i;for(var n=t.getProgramParameter(e,t.ACTIVE_UNIFORMS),o=0;o<n;++o){var a=t.getActiveUniform(e,o),s=a.name;Q(a,t.getUniformLocation(e,s),r)}}function tt(t,e,i){return void 0===e&&void 0===i?this.set(t):this.setRGB(t,e,i)}function et(t,e){this.min=void 0!==t?t:new l(1/0,1/0),this.max=void 0!==e?e:new l(-1/0,-1/0)}function it(t,e){function i(){var t=new Float32Array([-1,-1,0,0,1,-1,1,0,1,1,1,1,-1,1,0,1]),e=new Uint16Array([0,1,2,0,2,3]);n=d.createBuffer(),o=d.createBuffer(),d.bindBuffer(d.ARRAY_BUFFER,n),d.bufferData(d.ARRAY_BUFFER,t,d.STATIC_DRAW),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,o),d.bufferData(d.ELEMENT_ARRAY_BUFFER,e,d.STATIC_DRAW),h=d.createTexture(),p=d.createTexture(),f.bindTexture(d.TEXTURE_2D,h),d.texImage2D(d.TEXTURE_2D,0,d.RGB,16,16,0,d.RGB,d.UNSIGNED_BYTE,null),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_S,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_T,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MAG_FILTER,d.NEAREST),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MIN_FILTER,d.NEAREST),f.bindTexture(d.TEXTURE_2D,p),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,16,16,0,d.RGBA,d.UNSIGNED_BYTE,null),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_S,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_T,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MAG_FILTER,d.NEAREST),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MIN_FILTER,d.NEAREST),a={vertexShader:["uniform lowp int renderType;","uniform vec3 screenPosition;","uniform vec2 scale;","uniform float rotation;","uniform sampler2D occlusionMap;","attribute vec2 position;","attribute vec2 uv;","varying vec2 vUV;","varying float vVisibility;","void main() {","vUV = uv;","vec2 pos = position;","if ( renderType == 2 ) {","vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );","visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );","visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );","visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );","visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );","visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );","visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );","visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );","visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );","vVisibility =        visibility.r / 9.0;","vVisibility *= 1.0 - visibility.g / 9.0;","vVisibility *=       visibility.b / 9.0;","vVisibility *= 1.0 - visibility.a / 9.0;","pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;","pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;","}","gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );","}"].join("\n"),fragmentShader:["uniform lowp int renderType;","uniform sampler2D map;","uniform float opacity;","uniform vec3 color;","varying vec2 vUV;","varying float vVisibility;","void main() {","if ( renderType == 0 ) {","gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );","} else if ( renderType == 1 ) {","gl_FragColor = texture2D( map, vUV );","} else {","vec4 texture = texture2D( map, vUV );","texture.a *= opacity * vVisibility;","gl_FragColor = texture;","gl_FragColor.rgb *= color;","}","}"].join("\n")},s=r(a),c={vertex:d.getAttribLocation(s,"position"),uv:d.getAttribLocation(s,"uv")},u={renderType:d.getUniformLocation(s,"renderType"),map:d.getUniformLocation(s,"map"),occlusionMap:d.getUniformLocation(s,"occlusionMap"),opacity:d.getUniformLocation(s,"opacity"),color:d.getUniformLocation(s,"color"),scale:d.getUniformLocation(s,"scale"),rotation:d.getUniformLocation(s,"rotation"),screenPosition:d.getUniformLocation(s,"screenPosition")}}function r(e){var i=d.createProgram(),r=d.createShader(d.FRAGMENT_SHADER),n=d.createShader(d.VERTEX_SHADER),o="precision "+t.getPrecision()+" float;\n";return d.shaderSource(r,o+e.fragmentShader),d.shaderSource(n,o+e.vertexShader),d.compileShader(r),d.compileShader(n),d.attachShader(i,r),d.attachShader(i,n),d.linkProgram(i),i}var n,o,a,s,c,u,h,p,d=t.context,f=t.state;this.render=function(r,a,m){if(0!==e.length){var v=new g,y=m.w/m.z,b=.5*m.z,x=.5*m.w,_=16/m.w,w=new l(_*y,_),S=new g(1,1,0),A=new l(1,1),M=new et;M.min.set(m.x,m.y),M.max.set(m.x+(m.z-16),m.y+(m.w-16)),void 0===s&&i(),d.useProgram(s),f.initAttributes(),f.enableAttribute(c.vertex),f.enableAttribute(c.uv),f.disableUnusedAttributes(),d.uniform1i(u.occlusionMap,0),d.uniform1i(u.map,1),d.bindBuffer(d.ARRAY_BUFFER,n),d.vertexAttribPointer(c.vertex,2,d.FLOAT,!1,16,0),d.vertexAttribPointer(c.uv,2,d.FLOAT,!1,16,8),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,o),f.disable(d.CULL_FACE),f.buffers.depth.setMask(!1);for(var P=0,T=e.length;P<T;P++){_=16/m.w,w.set(_*y,_);var E=e[P];if(v.set(E.matrixWorld.elements[12],E.matrixWorld.elements[13],E.matrixWorld.elements[14]),v.applyMatrix4(a.matrixWorldInverse),v.applyMatrix4(a.projectionMatrix),S.copy(v),A.x=m.x+S.x*b+b-8,A.y=m.y+S.y*x+x-8,!0===M.containsPoint(A)){f.activeTexture(d.TEXTURE0),f.bindTexture(d.TEXTURE_2D,null),f.activeTexture(d.TEXTURE1),f.bindTexture(d.TEXTURE_2D,h),d.copyTexImage2D(d.TEXTURE_2D,0,d.RGB,A.x,A.y,16,16,0),d.uniform1i(u.renderType,0),d.uniform2f(u.scale,w.x,w.y),d.uniform3f(u.screenPosition,S.x,S.y,S.z),f.disable(d.BLEND),f.enable(d.DEPTH_TEST),d.drawElements(d.TRIANGLES,6,d.UNSIGNED_SHORT,0),f.activeTexture(d.TEXTURE0),f.bindTexture(d.TEXTURE_2D,p),d.copyTexImage2D(d.TEXTURE_2D,0,d.RGBA,A.x,A.y,16,16,0),d.uniform1i(u.renderType,1),f.disable(d.DEPTH_TEST),f.activeTexture(d.TEXTURE1),f.bindTexture(d.TEXTURE_2D,h),d.drawElements(d.TRIANGLES,6,d.UNSIGNED_SHORT,0),E.positionScreen.copy(S),E.customUpdateCallback?E.customUpdateCallback(E):E.updateLensFlares(),d.uniform1i(u.renderType,2),f.enable(d.BLEND);for(var C=0,I=E.lensFlares.length;C<I;C++){var L=E.lensFlares[C];L.opacity>.001&&L.scale>.001&&(S.x=L.x,S.y=L.y,S.z=L.z,_=L.size*L.scale/m.w,w.x=_*y,w.y=_,d.uniform3f(u.screenPosition,S.x,S.y,S.z),d.uniform2f(u.scale,w.x,w.y),d.uniform1f(u.rotation,L.rotation),d.uniform1f(u.opacity,L.opacity),d.uniform3f(u.color,L.color.r,L.color.g,L.color.b),f.setBlending(L.blending,L.blendEquation,L.blendSrc,L.blendDst),t.setTexture2D(L.texture,1),d.drawElements(d.TRIANGLES,6,d.UNSIGNED_SHORT,0))}}}f.enable(d.CULL_FACE),f.enable(d.DEPTH_TEST),f.buffers.depth.setMask(!0),t.resetGLState()}}}function rt(t,e){function i(){var t=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),e=new Uint16Array([0,1,2,0,2,3]);o=l.createBuffer(),a=l.createBuffer(),l.bindBuffer(l.ARRAY_BUFFER,o),l.bufferData(l.ARRAY_BUFFER,t,l.STATIC_DRAW),l.bindBuffer(l.ELEMENT_ARRAY_BUFFER,a),l.bufferData(l.ELEMENT_ARRAY_BUFFER,e,l.STATIC_DRAW),s=r(),c={position:l.getAttribLocation(s,"position"),uv:l.getAttribLocation(s,"uv")},u={uvOffset:l.getUniformLocation(s,"uvOffset"),uvScale:l.getUniformLocation(s,"uvScale"),rotation:l.getUniformLocation(s,"rotation"),scale:l.getUniformLocation(s,"scale"),color:l.getUniformLocation(s,"color"),map:l.getUniformLocation(s,"map"),opacity:l.getUniformLocation(s,"opacity"),modelViewMatrix:l.getUniformLocation(s,"modelViewMatrix"),projectionMatrix:l.getUniformLocation(s,"projectionMatrix"),fogType:l.getUniformLocation(s,"fogType"),fogDensity:l.getUniformLocation(s,"fogDensity"),fogNear:l.getUniformLocation(s,"fogNear"),fogFar:l.getUniformLocation(s,"fogFar"),fogColor:l.getUniformLocation(s,"fogColor"),alphaTest:l.getUniformLocation(s,"alphaTest")};var i=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");i.width=8,i.height=8;var n=i.getContext("2d");n.fillStyle="white",n.fillRect(0,0,8,8),(h=new p(i)).needsUpdate=!0}function r(){var e=l.createProgram(),i=l.createShader(l.VERTEX_SHADER),r=l.createShader(l.FRAGMENT_SHADER);return l.shaderSource(i,["precision "+t.getPrecision()+" float;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform float rotation;","uniform vec2 scale;","uniform vec2 uvOffset;","uniform vec2 uvScale;","attribute vec2 position;","attribute vec2 uv;","varying vec2 vUV;","void main() {","vUV = uvOffset + uv * uvScale;","vec2 alignedPosition = position * scale;","vec2 rotatedPosition;","rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;","rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;","vec4 finalPosition;","finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );","finalPosition.xy += rotatedPosition;","finalPosition = projectionMatrix * finalPosition;","gl_Position = finalPosition;","}"].join("\n")),l.shaderSource(r,["precision "+t.getPrecision()+" float;","uniform vec3 color;","uniform sampler2D map;","uniform float opacity;","uniform int fogType;","uniform vec3 fogColor;","uniform float fogDensity;","uniform float fogNear;","uniform float fogFar;","uniform float alphaTest;","varying vec2 vUV;","void main() {","vec4 texture = texture2D( map, vUV );","if ( texture.a < alphaTest ) discard;","gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );","if ( fogType > 0 ) {","float depth = gl_FragCoord.z / gl_FragCoord.w;","float fogFactor = 0.0;","if ( fogType == 1 ) {","fogFactor = smoothstep( fogNear, fogFar, depth );","} else {","const float LOG2 = 1.442695;","fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );","fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );","}","gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );","}","}"].join("\n")),l.compileShader(i),l.compileShader(r),l.attachShader(e,i),l.attachShader(e,r),l.linkProgram(e),e}function n(t,e){return t.renderOrder!==e.renderOrder?t.renderOrder-e.renderOrder:t.z!==e.z?e.z-t.z:e.id-t.id}var o,a,s,c,u,h,l=t.context,d=t.state,f=new g,v=new m,y=new g;this.render=function(r,p){if(0!==e.length){void 0===s&&i(),l.useProgram(s),d.initAttributes(),d.enableAttribute(c.position),d.enableAttribute(c.uv),d.disableUnusedAttributes(),d.disable(l.CULL_FACE),d.enable(l.BLEND),l.bindBuffer(l.ARRAY_BUFFER,o),l.vertexAttribPointer(c.position,2,l.FLOAT,!1,16,0),l.vertexAttribPointer(c.uv,2,l.FLOAT,!1,16,8),l.bindBuffer(l.ELEMENT_ARRAY_BUFFER,a),l.uniformMatrix4fv(u.projectionMatrix,!1,p.projectionMatrix.elements),d.activeTexture(l.TEXTURE0),l.uniform1i(u.map,0);var m=0,g=0,b=r.fog;b?(l.uniform3f(u.fogColor,b.color.r,b.color.g,b.color.b),b.isFog?(l.uniform1f(u.fogNear,b.near),l.uniform1f(u.fogFar,b.far),l.uniform1i(u.fogType,1),m=1,g=1):b.isFogExp2&&(l.uniform1f(u.fogDensity,b.density),l.uniform1i(u.fogType,2),m=2,g=2)):(l.uniform1i(u.fogType,0),m=0,g=0);for(var x=0,_=e.length;x<_;x++)(S=e[x]).modelViewMatrix.multiplyMatrices(p.matrixWorldInverse,S.matrixWorld),S.z=-S.modelViewMatrix.elements[14];e.sort(n);for(var w=[],x=0,_=e.length;x<_;x++){var S=e[x],A=S.material;if(!1!==A.visible){l.uniform1f(u.alphaTest,A.alphaTest),l.uniformMatrix4fv(u.modelViewMatrix,!1,S.modelViewMatrix.elements),S.matrixWorld.decompose(f,v,y),w[0]=y.x,w[1]=y.y;var M=0;r.fog&&A.fog&&(M=g),m!==M&&(l.uniform1i(u.fogType,M),m=M),null!==A.map?(l.uniform2f(u.uvOffset,A.map.offset.x,A.map.offset.y),l.uniform2f(u.uvScale,A.map.repeat.x,A.map.repeat.y)):(l.uniform2f(u.uvOffset,0,0),l.uniform2f(u.uvScale,1,1)),l.uniform1f(u.opacity,A.opacity),l.uniform3f(u.color,A.color.r,A.color.g,A.color.b),l.uniform1f(u.rotation,A.rotation),l.uniform2fv(u.scale,w),d.setBlending(A.blending,A.blendEquation,A.blendSrc,A.blendDst),d.buffers.depth.setTest(A.depthTest),d.buffers.depth.setMask(A.depthWrite),A.map?t.setTexture2D(A.map,0):t.setTexture2D(h,0),l.drawElements(l.TRIANGLES,6,l.UNSIGNED_SHORT,0)}}d.enable(l.CULL_FACE),t.resetGLState()}}}function nt(){Object.defineProperty(this,"id",{value:Dl++}),this.uuid=xl.generateUUID(),this.name="",this.type="Material",this.fog=!0,this.lights=!0,this.blending=Ou,this.side=Au,this.shading=Eu,this.vertexColors=Cu,this.opacity=1,this.transparent=!1,this.blendSrc=Xu,this.blendDst=qu,this.blendEquation=Fu,this.blendSrcAlpha=null,this.blendDstAlpha=null,this.blendEquationAlpha=null,this.depthFunc=rh,this.depthTest=!0,this.depthWrite=!0,this.clippingPlanes=null,this.clipIntersection=!1,this.clipShadows=!1,this.colorWrite=!0,this.precision=null,this.polygonOffset=!1,this.polygonOffsetFactor=0,this.polygonOffsetUnits=0,this.dithering=!1,this.alphaTest=0,this.premultipliedAlpha=!1,this.overdraw=0,this.visible=!0,this.needsUpdate=!0}function ot(t){nt.call(this),this.type="ShaderMaterial",this.defines={},this.uniforms={},this.vertexShader="void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",this.fragmentShader="void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}",this.linewidth=1,this.wireframe=!1,this.wireframeLinewidth=1,this.fog=!1,this.lights=!1,this.clipping=!1,this.skinning=!1,this.morphTargets=!1,this.morphNormals=!1,this.extensions={derivatives:!1,fragDepth:!1,drawBuffers:!1,shaderTextureLOD:!1},this.defaultAttributeValues={color:[1,1,1],uv:[0,0],uv2:[0,0]},this.index0AttributeName=void 0,void 0!==t&&(void 0!==t.attributes&&console.error("THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead."),this.setValues(t))}function at(t){nt.call(this),this.type="MeshDepthMaterial",this.depthPacking=yl,this.skinning=!1,this.morphTargets=!1,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.fog=!1,this.lights=!1,this.setValues(t)}function st(t,e){this.min=void 0!==t?t:new g(1/0,1/0,1/0),this.max=void 0!==e?e:new g(-1/0,-1/0,-1/0)}function ct(t,e){this.center=void 0!==t?t:new g,this.radius=void 0!==e?e:0}function ut(){this.elements=[1,0,0,0,1,0,0,0,1],arguments.length>0&&console.error("THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.")}function ht(t,e){this.normal=void 0!==t?t:new g(1,0,0),this.constant=void 0!==e?e:0}function lt(t,e,i,r,n,o){this.planes=[void 0!==t?t:new ht,void 0!==e?e:new ht,void 0!==i?i:new ht,void 0!==r?r:new ht,void 0!==n?n:new ht,void 0!==o?o:new ht]}function pt(t,e,i,r){function n(e,i,r,n){var o=e.geometry,a=null,s=S,c=e.customDepthMaterial;if(r&&(s=A,c=e.customDistanceMaterial),c)a=c;else{var u=!1;i.morphTargets&&(o&&o.isBufferGeometry?u=o.morphAttributes&&o.morphAttributes.position&&o.morphAttributes.position.length>0:o&&o.isGeometry&&(u=o.morphTargets&&o.morphTargets.length>0)),e.isSkinnedMesh&&!1===i.skinning&&console.warn("THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:",e);var h=e.isSkinnedMesh&&i.skinning,l=0;u&&(l|=x),h&&(l|=_),a=s[l]}if(t.localClippingEnabled&&!0===i.clipShadows&&0!==i.clippingPlanes.length){var p=a.uuid,d=i.uuid,f=M[p];void 0===f&&(f={},M[p]=f);var m=f[d];void 0===m&&(m=a.clone(),f[d]=m),a=m}a.visible=i.visible,a.wireframe=i.wireframe;var g=i.side;return B.renderSingleSided&&g==Pu&&(g=Au),B.renderReverseSided&&(g===Au?g=Mu:g===Mu&&(g=Au)),a.side=g,a.clipShadows=i.clipShadows,a.clippingPlanes=i.clippingPlanes,a.wireframeLinewidth=i.wireframeLinewidth,a.linewidth=i.linewidth,r&&void 0!==a.uniforms.lightPos&&a.uniforms.lightPos.value.copy(n),a}function o(e,r,a,s){if(!1!==e.visible){if(e.layers.test(r.layers)&&(e.isMesh||e.isLine||e.isPoints)&&e.castShadow&&(!e.frustumCulled||c.intersectsObject(e))){e.modelViewMatrix.multiplyMatrices(a.matrixWorldInverse,e.matrixWorld);var u=i.update(e),h=e.material;if(Array.isArray(h))for(var l=u.groups,p=0,d=l.length;p<d;p++){var f=l[p],m=h[f.materialIndex];if(m&&m.visible){g=n(e,m,s,b);t.renderBufferDirect(a,null,u,g,e,f)}}else if(h.visible){var g=n(e,h,s,b);t.renderBufferDirect(a,null,u,g,e,null)}}for(var v=e.children,y=0,x=v.length;y<x;y++)o(v[y],r,a,s)}}var a=t.context,s=t.state,c=new lt,u=new v,h=e.shadows,p=new l,m=new l(r.maxTextureSize,r.maxTextureSize),y=new g,b=new g,x=1,_=2,w=1+(x|_),S=new Array(w),A=new Array(w),M={},P=[new g(1,0,0),new g(-1,0,0),new g(0,0,1),new g(0,0,-1),new g(0,1,0),new g(0,-1,0)],T=[new g(0,1,0),new g(0,1,0),new g(0,1,0),new g(0,1,0),new g(0,0,1),new g(0,0,-1)],E=[new d,new d,new d,new d,new d,new d],C=new at;C.depthPacking=bl,C.clipping=!0;for(var I=Ol.distanceRGBA,L=Ll.clone(I.uniforms),R=0;R!==w;++R){var O=0!=(R&x),D=0!=(R&_),N=C.clone();N.morphTargets=O,N.skinning=D,S[R]=N;var k=new ot({defines:{USE_SHADOWMAP:""},uniforms:L,vertexShader:I.vertexShader,fragmentShader:I.fragmentShader,morphTargets:O,skinning:D,clipping:!0});A[R]=k}var B=this;this.enabled=!1,this.autoUpdate=!0,this.needsUpdate=!1,this.type=wu,this.renderReverseSided=!0,this.renderSingleSided=!0,this.render=function(e,i){if(!1!==B.enabled&&(!1!==B.autoUpdate||!1!==B.needsUpdate)&&0!==h.length){s.disable(a.BLEND),s.buffers.color.setClear(1,1,1,1),s.buffers.depth.setTest(!0),s.setScissorTest(!1);for(var r,n,l=0,d=h.length;l<d;l++){var g=h[l],v=g.shadow;if(void 0!==v){var x=v.camera,_=v.matrix;if(b.setFromMatrixPosition(g.matrixWorld),x.position.copy(b),p.copy(v.mapSize),p.min(m),g&&g.isPointLight){r=6,n=!0;var w=p.x,S=p.y;E[0].set(2*w,S,w,S),E[1].set(0,S,w,S),E[2].set(3*w,S,w,S),E[3].set(w,S,w,S),E[4].set(3*w,0,w,S),E[5].set(w,0,w,S),p.x*=4,p.y*=2,_.makeTranslation(-b.x,-b.y,-b.z)}else r=1,n=!1,y.setFromMatrixPosition(g.target.matrixWorld),x.lookAt(y),x.updateMatrixWorld(),x.matrixWorldInverse.getInverse(x.matrixWorld),_.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),_.multiply(x.projectionMatrix),_.multiply(x.matrixWorldInverse);if(null===v.map){var A={minFilter:Ph,magFilter:Ph,format:Wh};v.map=new f(p.x,p.y,A),v.map.texture.name=g.name+".shadowMap",x.updateProjectionMatrix()}v.isSpotLightShadow&&v.update(g);var M=v.map;t.setRenderTarget(M),t.clear();for(var C=0;C<r;C++){if(n){y.copy(x.position),y.add(P[C]),x.up.copy(T[C]),x.lookAt(y),x.updateMatrixWorld(),x.matrixWorldInverse.getInverse(x.matrixWorld);var I=E[C];s.viewport(I)}u.multiplyMatrices(x.projectionMatrix,x.matrixWorldInverse),c.setFromMatrix(u),o(e,i,x,n)}}else console.warn("THREE.WebGLShadowMap:",g,"has no shadow.")}var L=t.getClearColor(),R=t.getClearAlpha();t.setClearColor(L,R),B.needsUpdate=!1}}}function dt(t,e){this.origin=void 0!==t?t:new g,this.direction=void 0!==e?e:new g}function ft(t,e,i,r){this._x=t||0,this._y=e||0,this._z=i||0,this._order=r||ft.DefaultOrder}function mt(){this.mask=1}function gt(){function t(){n.setFromEuler(r,!1)}function e(){r.setFromQuaternion(n,void 0,!1)}Object.defineProperty(this,"id",{value:Nl++}),this.uuid=xl.generateUUID(),this.name="",this.type="Object3D",this.parent=null,this.children=[],this.up=gt.DefaultUp.clone();var i=new g,r=new ft,n=new m,o=new g(1,1,1);r.onChange(t),n.onChange(e),Object.defineProperties(this,{position:{enumerable:!0,value:i},rotation:{enumerable:!0,value:r},quaternion:{enumerable:!0,value:n},scale:{enumerable:!0,value:o},modelViewMatrix:{value:new v},normalMatrix:{value:new ut}}),this.matrix=new v,this.matrixWorld=new v,this.matrixAutoUpdate=gt.DefaultMatrixAutoUpdate,this.matrixWorldNeedsUpdate=!1,this.layers=new mt,this.visible=!0,this.castShadow=!1,this.receiveShadow=!1,this.frustumCulled=!0,this.renderOrder=0,this.userData={},this.onBeforeRender=function(){},this.onAfterRender=function(){}}function vt(t,e){this.start=void 0!==t?t:new g,this.end=void 0!==e?e:new g}function yt(t,e,i){this.a=void 0!==t?t:new g,this.b=void 0!==e?e:new g,this.c=void 0!==i?i:new g}function bt(t,e,i,r,n,o){this.a=t,this.b=e,this.c=i,this.normal=r&&r.isVector3?r:new g,this.vertexNormals=Array.isArray(r)?r:[],this.color=n&&n.isColor?n:new tt,this.vertexColors=Array.isArray(n)?n:[],this.materialIndex=void 0!==o?o:0}function xt(t){nt.call(this),this.type="MeshBasicMaterial",this.color=new tt(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=ch,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.skinning=!1,this.morphTargets=!1,this.lights=!1,this.setValues(t)}function _t(t,e,i){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.uuid=xl.generateUUID(),this.array=t,this.itemSize=e,this.count=void 0!==t?t.length/e:0,this.normalized=!0===i,this.dynamic=!1,this.updateRange={offset:0,count:-1},this.onUploadCallback=function(){},this.version=0}function wt(t,e){_t.call(this,new Uint16Array(t),e)}function St(t,e){_t.call(this,new Uint32Array(t),e)}function At(t,e){_t.call(this,new Float32Array(t),e)}function Mt(){this.indices=[],this.vertices=[],this.normals=[],this.colors=[],this.uvs=[],this.uvs2=[],this.groups=[],this.morphTargets={},this.skinWeights=[],this.skinIndices=[],this.boundingBox=null,this.boundingSphere=null,this.verticesNeedUpdate=!1,this.normalsNeedUpdate=!1,this.colorsNeedUpdate=!1,this.uvsNeedUpdate=!1,this.groupsNeedUpdate=!1}function Pt(t){if(0===t.length)return-1/0;for(var e=t[0],i=1,r=t.length;i<r;++i)t[i]>e&&(e=t[i]);return e}function Tt(){return kl++}function Et(){Object.defineProperty(this,"id",{value:Tt()}),this.uuid=xl.generateUUID(),this.name="",this.type="Geometry",this.vertices=[],this.colors=[],this.faces=[],this.faceVertexUvs=[[]],this.morphTargets=[],this.morphNormals=[],this.skinWeights=[],this.skinIndices=[],this.lineDistances=[],this.boundingBox=null,this.boundingSphere=null,this.elementsNeedUpdate=!1,this.verticesNeedUpdate=!1,this.uvsNeedUpdate=!1,this.normalsNeedUpdate=!1,this.colorsNeedUpdate=!1,this.lineDistancesNeedUpdate=!1,this.groupsNeedUpdate=!1}function Ct(){Object.defineProperty(this,"id",{value:Tt()}),this.uuid=xl.generateUUID(),this.name="",this.type="BufferGeometry",this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null,this.drawRange={start:0,count:1/0}}function It(t,e){gt.call(this),this.type="Mesh",this.geometry=void 0!==t?t:new Ct,this.material=void 0!==e?e:new xt({color:16777215*Math.random()}),this.drawMode=cl,this.updateMorphTargets()}function Lt(t,e,i,r,n,o){Et.call(this),this.type="BoxGeometry",this.parameters={width:t,height:e,depth:i,widthSegments:r,heightSegments:n,depthSegments:o},this.fromBufferGeometry(new Rt(t,e,i,r,n,o)),this.mergeVertices()}function Rt(t,e,i,r,n,o){function a(t,e,i,r,n,o,a,f,m,v,y){var b,x,_=o/m,w=a/v,S=o/2,A=a/2,M=f/2,P=m+1,T=v+1,E=0,C=0,I=new g;for(x=0;x<T;x++){var L=x*w-A;for(b=0;b<P;b++){var R=b*_-S;I[t]=R*r,I[e]=L*n,I[i]=M,u.push(I.x,I.y,I.z),I[t]=0,I[e]=0,I[i]=f>0?1:-1,h.push(I.x,I.y,I.z),l.push(b/m),l.push(1-x/v),E+=1}}for(x=0;x<v;x++)for(b=0;b<m;b++){var O=p+b+P*x,D=p+b+P*(x+1),N=p+(b+1)+P*(x+1),k=p+(b+1)+P*x;c.push(O,D,k),c.push(D,N,k),C+=6}s.addGroup(d,C,y),d+=C,p+=E}Ct.call(this),this.type="BoxBufferGeometry",this.parameters={width:t,height:e,depth:i,widthSegments:r,heightSegments:n,depthSegments:o};var s=this;r=Math.floor(r)||1,n=Math.floor(n)||1;var c=[],u=[],h=[],l=[],p=0,d=0;a("z","y","x",-1,-1,i,e,t,o=Math.floor(o)||1,n,0),a("z","y","x",1,-1,i,e,-t,o,n,1),a("x","z","y",1,1,t,i,e,r,o,2),a("x","z","y",1,-1,t,i,-e,r,o,3),a("x","y","z",1,-1,t,e,i,r,n,4),a("x","y","z",-1,-1,t,e,-i,r,n,5),this.setIndex(c),this.addAttribute("position",new At(u,3)),this.addAttribute("normal",new At(h,3)),this.addAttribute("uv",new At(l,2))}function Ot(t,e,i,r){Et.call(this),this.type="PlaneGeometry",this.parameters={width:t,height:e,widthSegments:i,heightSegments:r},this.fromBufferGeometry(new Dt(t,e,i,r)),this.mergeVertices()}function Dt(t,e,i,r){Ct.call(this),this.type="PlaneBufferGeometry",this.parameters={width:t,height:e,widthSegments:i,heightSegments:r};var n,o,a=t/2,s=e/2,c=Math.floor(i)||1,u=Math.floor(r)||1,h=c+1,l=u+1,p=t/c,d=e/u,f=[],m=[],g=[],v=[];for(o=0;o<l;o++){var y=o*d-s;for(n=0;n<h;n++){var b=n*p-a;m.push(b,-y,0),g.push(0,0,1),v.push(n/c),v.push(1-o/u)}}for(o=0;o<u;o++)for(n=0;n<c;n++){var x=n+h*o,_=n+h*(o+1),w=n+1+h*(o+1),S=n+1+h*o;f.push(x,_,S),f.push(_,w,S)}this.setIndex(f),this.addAttribute("position",new At(m,3)),this.addAttribute("normal",new At(g,3)),this.addAttribute("uv",new At(v,2))}function Nt(){gt.call(this),this.type="Camera",this.matrixWorldInverse=new v,this.projectionMatrix=new v}function kt(t,e,i,r){Nt.call(this),this.type="PerspectiveCamera",this.fov=void 0!==t?t:50,this.zoom=1,this.near=void 0!==i?i:.1,this.far=void 0!==r?r:2e3,this.focus=10,this.aspect=void 0!==e?e:1,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}function Bt(t,e,i,r,n,o){Nt.call(this),this.type="OrthographicCamera",this.zoom=1,this.view=null,this.left=t,this.right=e,this.top=i,this.bottom=r,this.near=void 0!==n?n:.1,this.far=void 0!==o?o:2e3,this.updateProjectionMatrix()}function Ft(t){function e(e,i){var r=e.array,n=e.dynamic?t.DYNAMIC_DRAW:t.STATIC_DRAW,o=t.createBuffer();t.bindBuffer(i,o),t.bufferData(i,r,n),e.onUploadCallback();var a=t.FLOAT;return r instanceof Float32Array?a=t.FLOAT:r instanceof Float64Array?console.warn("Unsupported data buffer format: Float64Array"):r instanceof Uint16Array?a=t.UNSIGNED_SHORT:r instanceof Int16Array?a=t.SHORT:r instanceof Uint32Array?a=t.UNSIGNED_INT:r instanceof Int32Array?a=t.INT:r instanceof Int8Array?a=t.BYTE:r instanceof Uint8Array&&(a=t.UNSIGNED_BYTE),{buffer:o,type:a,bytesPerElement:r.BYTES_PER_ELEMENT,version:e.version}}function i(e,i,r){var n=i.array,o=i.updateRange;t.bindBuffer(r,e),!1===i.dynamic?t.bufferData(r,n,t.STATIC_DRAW):-1===o.count?t.bufferSubData(r,0,n):0===o.count?console.error("THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually."):(t.bufferSubData(r,o.offset*n.BYTES_PER_ELEMENT,n.subarray(o.offset,o.offset+o.count)),o.count=0)}function r(t){return t.isInterleavedBufferAttribute&&(t=t.data),a[t.uuid]}function n(e){var i=a[e.uuid];i&&(t.deleteBuffer(i.buffer),delete a[e.uuid])}function o(t,r){t.isInterleavedBufferAttribute&&(t=t.data);var n=a[t.uuid];void 0===n?a[t.uuid]=e(t,r):n.version<t.version&&(i(n.buffer,t,r),n.version=t.version)}var a={};return{get:r,remove:n,update:o}}function zt(t,e){return t.renderOrder!==e.renderOrder?t.renderOrder-e.renderOrder:t.program&&e.program&&t.program!==e.program?t.program.id-e.program.id:t.material.id!==e.material.id?t.material.id-e.material.id:t.z!==e.z?t.z-e.z:t.id-e.id}function Ut(t,e){return t.renderOrder!==e.renderOrder?t.renderOrder-e.renderOrder:t.z!==e.z?e.z-t.z:t.id-e.id}function jt(){function t(){o=-1,s=-1}function e(t,e,i,r,c){var u,h;i.transparent?(u=a,h=++s):(u=n,h=++o);var l=u[h];l?(l.id=t.id,l.object=t,l.geometry=e,l.material=i,l.program=i.program,l.renderOrder=t.renderOrder,l.z=r,l.group=c):(l={id:t.id,object:t,geometry:e,material:i,program:i.program,renderOrder:t.renderOrder,z:r,group:c},u.push(l))}function i(){n.length=o+1,a.length=s+1}function r(){n.sort(zt),a.sort(Ut)}var n=[],o=-1,a=[],s=-1;return{opaque:n,transparent:a,init:t,push:e,finish:i,sort:r}}function Gt(){function t(t,e){var r=t.id+","+e.id,n=i[r];return void 0===n&&(n=new jt,i[r]=n),n}function e(){i={}}var i={};return{get:t,dispose:e}}function Vt(t,e,i){function r(t){s=t}function n(i){i.array instanceof Uint32Array&&e.get("OES_element_index_uint")?(c=t.UNSIGNED_INT,u=4):i.array instanceof Uint16Array?(c=t.UNSIGNED_SHORT,u=2):(c=t.UNSIGNED_BYTE,u=1)}function o(e,r){t.drawElements(s,r,c,e*u),i.calls++,i.vertices+=r,s===t.TRIANGLES&&(i.faces+=r/3)}function a(r,n,o){var a=e.get("ANGLE_instanced_arrays");if(null===a)return void console.error("THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");a.drawElementsInstancedANGLE(s,o,c,n*u,r.maxInstancedCount),i.calls++,i.vertices+=o*r.maxInstancedCount,s===t.TRIANGLES&&(i.faces+=r.maxInstancedCount*o/3)}var s,c,u;this.setMode=r,this.setIndex=n,this.render=o,this.renderInstances=a}function $t(t,e,i){function r(t){a=t}function n(e,r){t.drawArrays(a,e,r),i.calls++,i.vertices+=r,a===t.TRIANGLES&&(i.faces+=r/3)}function o(r,n,o){var s=e.get("ANGLE_instanced_arrays");if(null===s)return void console.error("THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");var c=r.attributes.position;c.isInterleavedBufferAttribute?(o=c.data.count,s.drawArraysInstancedANGLE(a,0,o,r.maxInstancedCount)):s.drawArraysInstancedANGLE(a,n,o,r.maxInstancedCount),i.calls++,i.vertices+=o*r.maxInstancedCount,a===t.TRIANGLES&&(i.faces+=r.maxInstancedCount*o/3)}var a;this.setMode=r,this.render=n,this.renderInstances=o}function Ht(t,e,i){function r(t){var n=t.target,o=s[n.id];null!==o.index&&e.remove(o.index);for(var a in o.attributes)e.remove(o.attributes[a]);n.removeEventListener("dispose",r),delete s[n.id];var u=c[n.id];u&&(e.remove(u),delete c[n.id]),(u=c[o.id])&&(e.remove(u),delete c[o.id]),i.geometries--}function n(t,e){var n=s[e.id];return n||(e.addEventListener("dispose",r),e.isBufferGeometry?n=e:e.isGeometry&&(void 0===e._bufferGeometry&&(e._bufferGeometry=(new Ct).setFromObject(t)),n=e._bufferGeometry),s[e.id]=n,i.geometries++,n)}function o(i){var r=i.index,n=i.attributes;null!==r&&e.update(r,t.ELEMENT_ARRAY_BUFFER);for(var o in n)e.update(n[o],t.ARRAY_BUFFER);var a=i.morphAttributes;for(var o in a)for(var s=a[o],c=0,u=s.length;c<u;c++)e.update(s[c],t.ARRAY_BUFFER)}function a(i){var r=c[i.id];if(r)return r;var n=[],o=i.index,a=i.attributes;if(null!==o)for(var s=0,u=(d=o.array).length;s<u;s+=3){var h=d[s+0],l=d[s+1],p=d[s+2];n.push(h,l,l,p,p,h)}else for(var d=a.position.array,s=0,u=d.length/3-1;s<u;s+=3){var h=s+0,l=s+1,p=s+2;n.push(h,l,l,p,p,h)}return r=new(Pt(n)>65535?St:wt)(n,1),e.update(r,t.ELEMENT_ARRAY_BUFFER),c[i.id]=r,r}var s={},c={};return{get:n,update:o,getWireframeAttribute:a}}function Wt(){var t={};return{get:function(e){if(void 0!==t[e.id])return t[e.id];var i;switch(e.type){case"DirectionalLight":i={direction:new g,color:new tt,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new l};break;case"SpotLight":i={position:new g,direction:new g,color:new tt,distance:0,coneCos:0,penumbraCos:0,decay:0,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new l};break;case"PointLight":i={position:new g,color:new tt,distance:0,decay:0,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new l};break;case"HemisphereLight":i={direction:new g,skyColor:new tt,groundColor:new tt};break;case"RectAreaLight":i={color:new tt,position:new g,halfWidth:new g,halfHeight:new g}}return t[e.id]=i,i}}}function Xt(t,e,i){function r(t){var r=i.frame,n=t.geometry,a=e.get(t,n);return o[a.id]!==r&&(n.isGeometry&&a.updateFromObject(t),e.update(a),o[a.id]=r),a}function n(){o={}}var o={};return{update:r,clear:n}}function qt(t){for(var e=t.split("\n"),i=0;i<e.length;i++)e[i]=i+1+": "+e[i];return e.join("\n")}function Yt(t,e,i){var r=t.createShader(e);return t.shaderSource(r,i),t.compileShader(r),!1===t.getShaderParameter(r,t.COMPILE_STATUS)&&console.error("THREE.WebGLShader: Shader couldn't compile."),""!==t.getShaderInfoLog(r)&&console.warn("THREE.WebGLShader: gl.getShaderInfoLog()",e===t.VERTEX_SHADER?"vertex":"fragment",t.getShaderInfoLog(r),qt(i)),r}function Zt(t){switch(t){case ll:return["Linear","( value )"];case pl:return["sRGB","( value )"];case fl:return["RGBE","( value )"];case ml:return["RGBM","( value, 7.0 )"];case gl:return["RGBM","( value, 16.0 )"];case vl:return["RGBD","( value, 256.0 )"];case dl:return["Gamma","( value, float( GAMMA_FACTOR ) )"];default:throw new Error("unsupported encoding: "+t)}}function Kt(t,e){var i=Zt(e);return"vec4 "+t+"( vec4 value ) { return "+i[0]+"ToLinear"+i[1]+"; }"}function Qt(t,e){var i=Zt(e);return"vec4 "+t+"( vec4 value ) { return LinearTo"+i[0]+i[1]+"; }"}function Jt(t,e){var i;switch(e){case ph:i="Linear";break;case dh:i="Reinhard";break;case fh:i="Uncharted2";break;case mh:i="OptimizedCineon";break;default:throw new Error("unsupported toneMapping: "+e)}return"vec3 "+t+"( vec3 color ) { return "+i+"ToneMapping( color ); }"}function te(t,e,i){return[(t=t||{}).derivatives||e.envMapCubeUV||e.bumpMap||e.normalMap||e.flatShading?"#extension GL_OES_standard_derivatives : enable":"",(t.fragDepth||e.logarithmicDepthBuffer)&&i.get("EXT_frag_depth")?"#extension GL_EXT_frag_depth : enable":"",t.drawBuffers&&i.get("WEBGL_draw_buffers")?"#extension GL_EXT_draw_buffers : require":"",(t.shaderTextureLOD||e.envMap)&&i.get("EXT_shader_texture_lod")?"#extension GL_EXT_shader_texture_lod : enable":""].filter(re).join("\n")}function ee(t){var e=[];for(var i in t){var r=t[i];!1!==r&&e.push("#define "+i+" "+r)}return e.join("\n")}function ie(t,e,i){for(var r={},n=t.getProgramParameter(e,t.ACTIVE_ATTRIBUTES),o=0;o<n;o++){var a=t.getActiveAttrib(e,o).name;r[a]=t.getAttribLocation(e,a)}return r}function re(t){return""!==t}function ne(t,e){return t.replace(/NUM_DIR_LIGHTS/g,e.numDirLights).replace(/NUM_SPOT_LIGHTS/g,e.numSpotLights).replace(/NUM_RECT_AREA_LIGHTS/g,e.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,e.numPointLights).replace(/NUM_HEMI_LIGHTS/g,e.numHemiLights)}function oe(t){function e(t,e){var i=Rl[e];if(void 0===i)throw new Error("Can not resolve #include <"+e+">");return oe(i)}return t.replace(/^[ \t]*#include +<([\w\d.]+)>/gm,e)}function ae(t){function e(t,e,i,r){for(var n="",o=parseInt(e);o<parseInt(i);o++)n+=r.replace(/\[ i \]/g,"[ "+o+" ]");return n}return t.replace(/for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g,e)}function se(t,e,i,r){var n=t.context,o=i.extensions,a=i.defines,s=i.__webglShader.vertexShader,c=i.__webglShader.fragmentShader,u="SHADOWMAP_TYPE_BASIC";r.shadowMapType===wu?u="SHADOWMAP_TYPE_PCF":r.shadowMapType===Su&&(u="SHADOWMAP_TYPE_PCF_SOFT");var h="ENVMAP_TYPE_CUBE",l="ENVMAP_MODE_REFLECTION",p="ENVMAP_BLENDING_MULTIPLY";if(r.envMap){switch(i.envMap.mapping){case gh:case vh:h="ENVMAP_TYPE_CUBE";break;case _h:case wh:h="ENVMAP_TYPE_CUBE_UV";break;case yh:case bh:h="ENVMAP_TYPE_EQUIREC";break;case xh:h="ENVMAP_TYPE_SPHERE"}switch(i.envMap.mapping){case vh:case bh:l="ENVMAP_MODE_REFRACTION"}switch(i.combine){case ch:p="ENVMAP_BLENDING_MULTIPLY";break;case uh:p="ENVMAP_BLENDING_MIX";break;case hh:p="ENVMAP_BLENDING_ADD"}}var d,f,m=t.gammaFactor>0?t.gammaFactor:1,g=te(o,r,t.extensions),v=ee(a),y=n.createProgram();i.isRawShaderMaterial?(d=[v,"\n"].filter(re).join("\n"),f=[g,v,"\n"].filter(re).join("\n")):(d=["precision "+r.precision+" float;","precision "+r.precision+" int;","#define SHADER_NAME "+i.__webglShader.name,v,r.supportsVertexTextures?"#define VERTEX_TEXTURES":"","#define GAMMA_FACTOR "+m,"#define MAX_BONES "+r.maxBones,r.useFog&&r.fog?"#define USE_FOG":"",r.useFog&&r.fogExp?"#define FOG_EXP2":"",r.map?"#define USE_MAP":"",r.envMap?"#define USE_ENVMAP":"",r.envMap?"#define "+l:"",r.lightMap?"#define USE_LIGHTMAP":"",r.aoMap?"#define USE_AOMAP":"",r.emissiveMap?"#define USE_EMISSIVEMAP":"",r.bumpMap?"#define USE_BUMPMAP":"",r.normalMap?"#define USE_NORMALMAP":"",r.displacementMap&&r.supportsVertexTextures?"#define USE_DISPLACEMENTMAP":"",r.specularMap?"#define USE_SPECULARMAP":"",r.roughnessMap?"#define USE_ROUGHNESSMAP":"",r.metalnessMap?"#define USE_METALNESSMAP":"",r.alphaMap?"#define USE_ALPHAMAP":"",r.vertexColors?"#define USE_COLOR":"",r.flatShading?"#define FLAT_SHADED":"",r.skinning?"#define USE_SKINNING":"",r.useVertexTexture?"#define BONE_TEXTURE":"",r.morphTargets?"#define USE_MORPHTARGETS":"",r.morphNormals&&!1===r.flatShading?"#define USE_MORPHNORMALS":"",r.doubleSided?"#define DOUBLE_SIDED":"",r.flipSided?"#define FLIP_SIDED":"","#define NUM_CLIPPING_PLANES "+r.numClippingPlanes,r.shadowMapEnabled?"#define USE_SHADOWMAP":"",r.shadowMapEnabled?"#define "+u:"",r.sizeAttenuation?"#define USE_SIZEATTENUATION":"",r.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",r.logarithmicDepthBuffer&&t.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_COLOR","\tattribute vec3 color;","#endif","#ifdef USE_MORPHTARGETS","\tattribute vec3 morphTarget0;","\tattribute vec3 morphTarget1;","\tattribute vec3 morphTarget2;","\tattribute vec3 morphTarget3;","\t#ifdef USE_MORPHNORMALS","\t\tattribute vec3 morphNormal0;","\t\tattribute vec3 morphNormal1;","\t\tattribute vec3 morphNormal2;","\t\tattribute vec3 morphNormal3;","\t#else","\t\tattribute vec3 morphTarget4;","\t\tattribute vec3 morphTarget5;","\t\tattribute vec3 morphTarget6;","\t\tattribute vec3 morphTarget7;","\t#endif","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(re).join("\n"),f=[g,"precision "+r.precision+" float;","precision "+r.precision+" int;","#define SHADER_NAME "+i.__webglShader.name,v,r.alphaTest?"#define ALPHATEST "+r.alphaTest:"","#define GAMMA_FACTOR "+m,r.useFog&&r.fog?"#define USE_FOG":"",r.useFog&&r.fogExp?"#define FOG_EXP2":"",r.map?"#define USE_MAP":"",r.envMap?"#define USE_ENVMAP":"",r.envMap?"#define "+h:"",r.envMap?"#define "+l:"",r.envMap?"#define "+p:"",r.lightMap?"#define USE_LIGHTMAP":"",r.aoMap?"#define USE_AOMAP":"",r.emissiveMap?"#define USE_EMISSIVEMAP":"",r.bumpMap?"#define USE_BUMPMAP":"",r.normalMap?"#define USE_NORMALMAP":"",r.specularMap?"#define USE_SPECULARMAP":"",r.roughnessMap?"#define USE_ROUGHNESSMAP":"",r.metalnessMap?"#define USE_METALNESSMAP":"",r.alphaMap?"#define USE_ALPHAMAP":"",r.vertexColors?"#define USE_COLOR":"",r.gradientMap?"#define USE_GRADIENTMAP":"",r.flatShading?"#define FLAT_SHADED":"",r.doubleSided?"#define DOUBLE_SIDED":"",r.flipSided?"#define FLIP_SIDED":"","#define NUM_CLIPPING_PLANES "+r.numClippingPlanes,"#define UNION_CLIPPING_PLANES "+(r.numClippingPlanes-r.numClipIntersection),r.shadowMapEnabled?"#define USE_SHADOWMAP":"",r.shadowMapEnabled?"#define "+u:"",r.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",r.physicallyCorrectLights?"#define PHYSICALLY_CORRECT_LIGHTS":"",r.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",r.logarithmicDepthBuffer&&t.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"",r.envMap&&t.extensions.get("EXT_shader_texture_lod")?"#define TEXTURE_LOD_EXT":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;",r.toneMapping!==lh?"#define TONE_MAPPING":"",r.toneMapping!==lh?Rl.tonemapping_pars_fragment:"",r.toneMapping!==lh?Jt("toneMapping",r.toneMapping):"",r.dithering?"#define DITHERING":"",r.outputEncoding||r.mapEncoding||r.envMapEncoding||r.emissiveMapEncoding?Rl.encodings_pars_fragment:"",r.mapEncoding?Kt("mapTexelToLinear",r.mapEncoding):"",r.envMapEncoding?Kt("envMapTexelToLinear",r.envMapEncoding):"",r.emissiveMapEncoding?Kt("emissiveMapTexelToLinear",r.emissiveMapEncoding):"",r.outputEncoding?Qt("linearToOutputTexel",r.outputEncoding):"",r.depthPacking?"#define DEPTH_PACKING "+i.depthPacking:"","\n"].filter(re).join("\n")),s=ne(s=oe(s,r),r),c=ne(c=oe(c,r),r),i.isShaderMaterial||(s=ae(s),c=ae(c));var b=d+s,x=f+c,_=Yt(n,n.VERTEX_SHADER,b),w=Yt(n,n.FRAGMENT_SHADER,x);n.attachShader(y,_),n.attachShader(y,w),void 0!==i.index0AttributeName?n.bindAttribLocation(y,0,i.index0AttributeName):!0===r.morphTargets&&n.bindAttribLocation(y,0,"position"),n.linkProgram(y);var S=n.getProgramInfoLog(y),A=n.getShaderInfoLog(_),M=n.getShaderInfoLog(w),P=!0,T=!0;!1===n.getProgramParameter(y,n.LINK_STATUS)?(P=!1,console.error("THREE.WebGLProgram: shader error: ",n.getError(),"gl.VALIDATE_STATUS",n.getProgramParameter(y,n.VALIDATE_STATUS),"gl.getProgramInfoLog",S,A,M)):""!==S?console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",S):""!==A&&""!==M||(T=!1),T&&(this.diagnostics={runnable:P,material:i,programLog:S,vertexShader:{log:A,prefix:d},fragmentShader:{log:M,prefix:f}}),n.deleteShader(_),n.deleteShader(w);var E;this.getUniforms=function(){return void 0===E&&(E=new J(n,y,t)),E};var C;return this.getAttributes=function(){return void 0===C&&(C=ie(n,y)),C},this.destroy=function(){n.deleteProgram(y),this.program=void 0},Object.defineProperties(this,{uniforms:{get:function(){return console.warn("THREE.WebGLProgram: .uniforms is now .getUniforms()."),this.getUniforms()}},attributes:{get:function(){return console.warn("THREE.WebGLProgram: .attributes is now .getAttributes()."),this.getAttributes()}}}),this.id=Bl++,this.code=e,this.usedTimes=1,this.program=y,this.vertexShader=_,this.fragmentShader=w,this}function ce(t,e){function i(t){var i=t.skeleton.bones;if(e.floatVertexTextures)return 1024;var r=e.maxVertexUniforms,n=Math.floor((r-20)/4),o=Math.min(n,i.length);return o<i.length?(console.warn("THREE.WebGLRenderer: Skeleton has "+i.length+" bones. This GPU supports "+o+"."),0):o}function r(t,e){var i;return t?t.isTexture?i=t.encoding:t.isWebGLRenderTarget&&(console.warn("THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead."),i=t.texture.encoding):i=ll,i===ll&&e&&(i=dl),i}var n=[],o={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshToonMaterial:"phong",MeshStandardMaterial:"physical",MeshPhysicalMaterial:"physical",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points"},a=["precision","supportsVertexTextures","map","mapEncoding","envMap","envMapMode","envMapEncoding","lightMap","aoMap","emissiveMap","emissiveMapEncoding","bumpMap","normalMap","displacementMap","specularMap","roughnessMap","metalnessMap","gradientMap","alphaMap","combine","vertexColors","fog","useFog","fogExp","flatShading","sizeAttenuation","logarithmicDepthBuffer","skinning","maxBones","useVertexTexture","morphTargets","morphNormals","maxMorphTargets","maxMorphNormals","premultipliedAlpha","numDirLights","numPointLights","numSpotLights","numHemiLights","numRectAreaLights","shadowMapEnabled","shadowMapType","toneMapping","physicallyCorrectLights","alphaTest","doubleSided","flipSided","numClippingPlanes","numClipIntersection","depthPacking","dithering"];this.getParameters=function(n,a,s,c,u,h){var l=o[n.type],p=h.isSkinnedMesh?i(h):0,d=t.getPrecision();null!==n.precision&&(d=e.getMaxPrecision(n.precision))!==n.precision&&console.warn("THREE.WebGLProgram.getParameters:",n.precision,"not supported, using",d,"instead.");var f=t.getRenderTarget();return{shaderID:l,precision:d,supportsVertexTextures:e.vertexTextures,outputEncoding:r(f?f.texture:null,t.gammaOutput),map:!!n.map,mapEncoding:r(n.map,t.gammaInput),envMap:!!n.envMap,envMapMode:n.envMap&&n.envMap.mapping,envMapEncoding:r(n.envMap,t.gammaInput),envMapCubeUV:!!n.envMap&&(n.envMap.mapping===_h||n.envMap.mapping===wh),lightMap:!!n.lightMap,aoMap:!!n.aoMap,emissiveMap:!!n.emissiveMap,emissiveMapEncoding:r(n.emissiveMap,t.gammaInput),bumpMap:!!n.bumpMap,normalMap:!!n.normalMap,displacementMap:!!n.displacementMap,roughnessMap:!!n.roughnessMap,metalnessMap:!!n.metalnessMap,specularMap:!!n.specularMap,alphaMap:!!n.alphaMap,gradientMap:!!n.gradientMap,combine:n.combine,vertexColors:n.vertexColors,fog:!!s,useFog:n.fog,fogExp:s&&s.isFogExp2,flatShading:n.shading===Tu,sizeAttenuation:n.sizeAttenuation,logarithmicDepthBuffer:e.logarithmicDepthBuffer,skinning:n.skinning&&p>0,maxBones:p,useVertexTexture:e.floatVertexTextures,morphTargets:n.morphTargets,morphNormals:n.morphNormals,maxMorphTargets:t.maxMorphTargets,maxMorphNormals:t.maxMorphNormals,numDirLights:a.directional.length,numPointLights:a.point.length,numSpotLights:a.spot.length,numRectAreaLights:a.rectArea.length,numHemiLights:a.hemi.length,numClippingPlanes:c,numClipIntersection:u,dithering:n.dithering,shadowMapEnabled:t.shadowMap.enabled&&h.receiveShadow&&a.shadows.length>0,shadowMapType:t.shadowMap.type,toneMapping:t.toneMapping,physicallyCorrectLights:t.physicallyCorrectLights,premultipliedAlpha:n.premultipliedAlpha,alphaTest:n.alphaTest,doubleSided:n.side===Pu,flipSided:n.side===Mu,depthPacking:void 0!==n.depthPacking&&n.depthPacking}},this.getProgramCode=function(t,e){var i=[];if(e.shaderID?i.push(e.shaderID):(i.push(t.fragmentShader),i.push(t.vertexShader)),void 0!==t.defines)for(var r in t.defines)i.push(r),i.push(t.defines[r]);for(var n=0;n<a.length;n++)i.push(e[a[n]]);return i.join()},this.acquireProgram=function(e,i,r){for(var o,a=0,s=n.length;a<s;a++){var c=n[a];if(c.code===r){++(o=c).usedTimes;break}}return void 0===o&&(o=new se(t,r,e,i),n.push(o)),o},this.releaseProgram=function(t){if(0==--t.usedTimes){var e=n.indexOf(t);n[e]=n[n.length-1],n.pop(),t.destroy()}},this.programs=n}function ue(t,e,i,r,n,o,a){function s(t,e){if(t.width>e||t.height>e){var i=e/Math.max(t.width,t.height),r=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");return r.width=Math.floor(t.width*i),r.height=Math.floor(t.height*i),r.getContext("2d").drawImage(t,0,0,t.width,t.height,0,0,r.width,r.height),console.warn("THREE.WebGLRenderer: image is too big ("+t.width+"x"+t.height+"). Resized to "+r.width+"x"+r.height,t),r}return t}function c(t){return xl.isPowerOfTwo(t.width)&&xl.isPowerOfTwo(t.height)}function u(t){if(t instanceof HTMLImageElement||t instanceof HTMLCanvasElement){var e=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");return e.width=xl.nearestPowerOfTwo(t.width),e.height=xl.nearestPowerOfTwo(t.height),e.getContext("2d").drawImage(t,0,0,e.width,e.height),console.warn("THREE.WebGLRenderer: image is not power of two ("+t.width+"x"+t.height+"). Resized to "+e.width+"x"+e.height,t),e}return t}function h(t){return t.wrapS!==Ah||t.wrapT!==Ah||t.minFilter!==Ph&&t.minFilter!==Ch}function l(e){return e===Ph||e===Th||e===Eh?t.NEAREST:t.LINEAR}function p(t){var e=t.target;e.removeEventListener("dispose",p),f(e),a.textures--}function d(t){var e=t.target;e.removeEventListener("dispose",d),m(e),a.textures--}function f(e){var i=r.get(e);if(e.image&&i.__image__webglTextureCube)t.deleteTexture(i.__image__webglTextureCube);else{if(void 0===i.__webglInit)return;t.deleteTexture(i.__webglTexture)}r.remove(e)}function m(e){var i=r.get(e),n=r.get(e.texture);if(e){if(void 0!==n.__webglTexture&&t.deleteTexture(n.__webglTexture),e.depthTexture&&e.depthTexture.dispose(),e.isWebGLRenderTargetCube)for(var o=0;o<6;o++)t.deleteFramebuffer(i.__webglFramebuffer[o]),i.__webglDepthbuffer&&t.deleteRenderbuffer(i.__webglDepthbuffer[o]);else t.deleteFramebuffer(i.__webglFramebuffer),i.__webglDepthbuffer&&t.deleteRenderbuffer(i.__webglDepthbuffer);r.remove(e.texture),r.remove(e)}}function g(e,n){var o=r.get(e);if(e.version>0&&o.__version!==e.version){var a=e.image;if(void 0===a)console.warn("THREE.WebGLRenderer: Texture marked for update but image is undefined",e);else{if(!1!==a.complete)return void x(o,e,n);console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete",e)}}i.activeTexture(t.TEXTURE0+n),i.bindTexture(t.TEXTURE_2D,o.__webglTexture)}function v(e,u){var h=r.get(e);if(6===e.image.length)if(e.version>0&&h.__version!==e.version){h.__image__webglTextureCube||(e.addEventListener("dispose",p),h.__image__webglTextureCube=t.createTexture(),a.textures++),i.activeTexture(t.TEXTURE0+u),i.bindTexture(t.TEXTURE_CUBE_MAP,h.__image__webglTextureCube),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,e.flipY);for(var l=e&&e.isCompressedTexture,d=e.image[0]&&e.image[0].isDataTexture,f=[],m=0;m<6;m++)f[m]=l||d?d?e.image[m].image:e.image[m]:s(e.image[m],n.maxCubemapSize);var g=c(f[0]),v=o(e.format),y=o(e.type);b(t.TEXTURE_CUBE_MAP,e,g);for(m=0;m<6;m++)if(l)for(var x,_=f[m].mipmaps,w=0,S=_.length;w<S;w++)x=_[w],e.format!==Wh&&e.format!==Hh?i.getCompressedTextureFormats().indexOf(v)>-1?i.compressedTexImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+m,w,v,x.width,x.height,0,x.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()"):i.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+m,w,v,x.width,x.height,0,v,y,x.data);else d?i.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+m,0,v,f[m].width,f[m].height,0,v,y,f[m].data):i.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+m,0,v,v,y,f[m]);e.generateMipmaps&&g&&t.generateMipmap(t.TEXTURE_CUBE_MAP),h.__version=e.version,e.onUpdate&&e.onUpdate(e)}else i.activeTexture(t.TEXTURE0+u),i.bindTexture(t.TEXTURE_CUBE_MAP,h.__image__webglTextureCube)}function y(e,n){i.activeTexture(t.TEXTURE0+n),i.bindTexture(t.TEXTURE_CUBE_MAP,r.get(e).__webglTexture)}function b(i,a,s){var c;if(s?(t.texParameteri(i,t.TEXTURE_WRAP_S,o(a.wrapS)),t.texParameteri(i,t.TEXTURE_WRAP_T,o(a.wrapT)),t.texParameteri(i,t.TEXTURE_MAG_FILTER,o(a.magFilter)),t.texParameteri(i,t.TEXTURE_MIN_FILTER,o(a.minFilter))):(t.texParameteri(i,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(i,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),a.wrapS===Ah&&a.wrapT===Ah||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.",a),t.texParameteri(i,t.TEXTURE_MAG_FILTER,l(a.magFilter)),t.texParameteri(i,t.TEXTURE_MIN_FILTER,l(a.minFilter)),a.minFilter!==Ph&&a.minFilter!==Ch&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.",a)),c=e.get("EXT_texture_filter_anisotropic")){if(a.type===Fh&&null===e.get("OES_texture_float_linear"))return;if(a.type===zh&&null===e.get("OES_texture_half_float_linear"))return;(a.anisotropy>1||r.get(a).__currentAnisotropy)&&(t.texParameterf(i,c.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(a.anisotropy,n.getMaxAnisotropy())),r.get(a).__currentAnisotropy=a.anisotropy)}}function x(e,r,l){void 0===e.__webglInit&&(e.__webglInit=!0,r.addEventListener("dispose",p),e.__webglTexture=t.createTexture(),a.textures++),i.activeTexture(t.TEXTURE0+l),i.bindTexture(t.TEXTURE_2D,e.__webglTexture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,r.flipY),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,r.premultiplyAlpha),t.pixelStorei(t.UNPACK_ALIGNMENT,r.unpackAlignment);var d=s(r.image,n.maxTextureSize);h(r)&&!1===c(d)&&(d=u(d));var f=c(d),m=o(r.format),g=o(r.type);b(t.TEXTURE_2D,r,f);var v,y=r.mipmaps;if(r.isDepthTexture){var x=t.DEPTH_COMPONENT;if(r.type===Fh){if(!T)throw new Error("Float Depth Texture only supported in WebGL2.0");x=t.DEPTH_COMPONENT32F}else T&&(x=t.DEPTH_COMPONENT16);r.format===Yh&&x===t.DEPTH_COMPONENT&&r.type!==Nh&&r.type!==Bh&&(console.warn("THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture."),r.type=Nh,g=o(r.type)),r.format===Zh&&(x=t.DEPTH_STENCIL,r.type!==Vh&&(console.warn("THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture."),r.type=Vh,g=o(r.type))),i.texImage2D(t.TEXTURE_2D,0,x,d.width,d.height,0,m,g,null)}else if(r.isDataTexture)if(y.length>0&&f){for(var _=0,w=y.length;_<w;_++)v=y[_],i.texImage2D(t.TEXTURE_2D,_,m,v.width,v.height,0,m,g,v.data);r.generateMipmaps=!1}else i.texImage2D(t.TEXTURE_2D,0,m,d.width,d.height,0,m,g,d.data);else if(r.isCompressedTexture)for(var _=0,w=y.length;_<w;_++)v=y[_],r.format!==Wh&&r.format!==Hh?i.getCompressedTextureFormats().indexOf(m)>-1?i.compressedTexImage2D(t.TEXTURE_2D,_,m,v.width,v.height,0,v.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):i.texImage2D(t.TEXTURE_2D,_,m,v.width,v.height,0,m,g,v.data);else if(y.length>0&&f){for(var _=0,w=y.length;_<w;_++)v=y[_],i.texImage2D(t.TEXTURE_2D,_,m,m,g,v);r.generateMipmaps=!1}else i.texImage2D(t.TEXTURE_2D,0,m,m,g,d);r.generateMipmaps&&f&&t.generateMipmap(t.TEXTURE_2D),e.__version=r.version,r.onUpdate&&r.onUpdate(r)}function _(e,n,a,s){var c=o(n.texture.format),u=o(n.texture.type);i.texImage2D(s,0,c,n.width,n.height,0,c,u,null),t.bindFramebuffer(t.FRAMEBUFFER,e),t.framebufferTexture2D(t.FRAMEBUFFER,a,s,r.get(n.texture).__webglTexture,0),t.bindFramebuffer(t.FRAMEBUFFER,null)}function w(e,i){t.bindRenderbuffer(t.RENDERBUFFER,e),i.depthBuffer&&!i.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_COMPONENT16,i.width,i.height),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,e)):i.depthBuffer&&i.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_STENCIL,i.width,i.height),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,e)):t.renderbufferStorage(t.RENDERBUFFER,t.RGBA4,i.width,i.height),t.bindRenderbuffer(t.RENDERBUFFER,null)}function S(e,i){if(i&&i.isWebGLRenderTargetCube)throw new Error("Depth Texture with cube render targets is not supported!");if(t.bindFramebuffer(t.FRAMEBUFFER,e),!i.depthTexture||!i.depthTexture.isDepthTexture)throw new Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");r.get(i.depthTexture).__webglTexture&&i.depthTexture.image.width===i.width&&i.depthTexture.image.height===i.height||(i.depthTexture.image.width=i.width,i.depthTexture.image.height=i.height,i.depthTexture.needsUpdate=!0),g(i.depthTexture,0);var n=r.get(i.depthTexture).__webglTexture;if(i.depthTexture.format===Yh)t.framebufferTexture2D(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.TEXTURE_2D,n,0);else{if(i.depthTexture.format!==Zh)throw new Error("Unknown depthTexture format");t.framebufferTexture2D(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.TEXTURE_2D,n,0)}}function A(e){var i=r.get(e),n=!0===e.isWebGLRenderTargetCube;if(e.depthTexture){if(n)throw new Error("target.depthTexture not supported in Cube render targets");S(i.__webglFramebuffer,e)}else if(n){i.__webglDepthbuffer=[];for(var o=0;o<6;o++)t.bindFramebuffer(t.FRAMEBUFFER,i.__webglFramebuffer[o]),i.__webglDepthbuffer[o]=t.createRenderbuffer(),w(i.__webglDepthbuffer[o],e)}else t.bindFramebuffer(t.FRAMEBUFFER,i.__webglFramebuffer),i.__webglDepthbuffer=t.createRenderbuffer(),w(i.__webglDepthbuffer,e);t.bindFramebuffer(t.FRAMEBUFFER,null)}function M(e){var n=r.get(e),o=r.get(e.texture);e.addEventListener("dispose",d),o.__webglTexture=t.createTexture(),a.textures++;var s=!0===e.isWebGLRenderTargetCube,u=c(e);if(s){n.__webglFramebuffer=[];for(h=0;h<6;h++)n.__webglFramebuffer[h]=t.createFramebuffer()}else n.__webglFramebuffer=t.createFramebuffer();if(s){i.bindTexture(t.TEXTURE_CUBE_MAP,o.__webglTexture),b(t.TEXTURE_CUBE_MAP,e.texture,u);for(var h=0;h<6;h++)_(n.__webglFramebuffer[h],e,t.COLOR_ATTACHMENT0,t.TEXTURE_CUBE_MAP_POSITIVE_X+h);e.texture.generateMipmaps&&u&&t.generateMipmap(t.TEXTURE_CUBE_MAP),i.bindTexture(t.TEXTURE_CUBE_MAP,null)}else i.bindTexture(t.TEXTURE_2D,o.__webglTexture),b(t.TEXTURE_2D,e.texture,u),_(n.__webglFramebuffer,e,t.COLOR_ATTACHMENT0,t.TEXTURE_2D),e.texture.generateMipmaps&&u&&t.generateMipmap(t.TEXTURE_2D),i.bindTexture(t.TEXTURE_2D,null);e.depthBuffer&&A(e)}function P(e){var n=e.texture;if(n.generateMipmaps&&c(e)&&n.minFilter!==Ph&&n.minFilter!==Ch){var o=e&&e.isWebGLRenderTargetCube?t.TEXTURE_CUBE_MAP:t.TEXTURE_2D,a=r.get(n).__webglTexture;i.bindTexture(o,a),t.generateMipmap(o),i.bindTexture(o,null)}}var T="undefined"!=typeof WebGL2RenderingContext&&t instanceof WebGL2RenderingContext;this.setTexture2D=g,this.setTextureCube=v,this.setTextureCubeDynamic=y,this.setupRenderTarget=M,this.updateRenderTargetMipmap=P}function he(){function t(t){var e=t.uuid,i=r[e];return void 0===i&&(i={},r[e]=i),i}function e(t){delete r[t.uuid]}function i(){r={}}var r={};return{get:t,remove:e,clear:i}}function le(t,e,i){function r(){var e=!1,i=new d,r=null,n=new d;return{setMask:function(i){r===i||e||(t.colorMask(i,i,i,i),r=i)},setLocked:function(t){e=t},setClear:function(e,r,o,a,s){!0===s&&(e*=a,r*=a,o*=a),i.set(e,r,o,a),!1===n.equals(i)&&(t.clearColor(e,r,o,a),n.copy(i))},reset:function(){e=!1,r=null,n.set(0,0,0,1)}}}function n(){var e=!1,i=null,r=null,n=null;return{setTest:function(e){e?p(t.DEPTH_TEST):f(t.DEPTH_TEST)},setMask:function(r){i===r||e||(t.depthMask(r),i=r)},setFunc:function(e){if(r!==e){if(e)switch(e){case th:t.depthFunc(t.NEVER);break;case eh:t.depthFunc(t.ALWAYS);break;case ih:t.depthFunc(t.LESS);break;case rh:t.depthFunc(t.LEQUAL);break;case nh:t.depthFunc(t.EQUAL);break;case oh:t.depthFunc(t.GEQUAL);break;case ah:t.depthFunc(t.GREATER);break;case sh:t.depthFunc(t.NOTEQUAL);break;default:t.depthFunc(t.LEQUAL)}else t.depthFunc(t.LEQUAL);r=e}},setLocked:function(t){e=t},setClear:function(e){n!==e&&(t.clearDepth(e),n=e)},reset:function(){e=!1,i=null,r=null,n=null}}}function o(){var e=!1,i=null,r=null,n=null,o=null,a=null,s=null,c=null,u=null;return{setTest:function(e){e?p(t.STENCIL_TEST):f(t.STENCIL_TEST)},setMask:function(r){i===r||e||(t.stencilMask(r),i=r)},setFunc:function(e,i,a){r===e&&n===i&&o===a||(t.stencilFunc(e,i,a),r=e,n=i,o=a)},setOp:function(e,i,r){a===e&&s===i&&c===r||(t.stencilOp(e,i,r),a=e,s=i,c=r)},setLocked:function(t){e=t},setClear:function(e){u!==e&&(t.clearStencil(e),u=e)},reset:function(){e=!1,i=null,r=null,n=null,o=null,a=null,s=null,c=null,u=null}}}function a(e,i,r){var n=new Uint8Array(4),o=t.createTexture();t.bindTexture(e,o),t.texParameteri(e,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(e,t.TEXTURE_MAG_FILTER,t.NEAREST);for(var a=0;a<r;a++)t.texImage2D(i+a,0,t.RGBA,1,1,0,t.RGBA,t.UNSIGNED_BYTE,n);return o}function s(){L.setClear(0,0,0,1),R.setClear(1),O.setClear(0),p(t.DEPTH_TEST),R.setFunc(rh),y(!1),b(bu),p(t.CULL_FACE),p(t.BLEND),g(Ou)}function c(){for(var t=0,e=N.length;t<e;t++)N[t]=0}function u(i){N[i]=1,0===k[i]&&(t.enableVertexAttribArray(i),k[i]=1),0!==B[i]&&(e.get("ANGLE_instanced_arrays").vertexAttribDivisorANGLE(i,0),B[i]=0)}function h(i,r){N[i]=1,0===k[i]&&(t.enableVertexAttribArray(i),k[i]=1),B[i]!==r&&(e.get("ANGLE_instanced_arrays").vertexAttribDivisorANGLE(i,r),B[i]=r)}function l(){for(var e=0,i=k.length;e!==i;++e)k[e]!==N[e]&&(t.disableVertexAttribArray(e),k[e]=0)}function p(e){!0!==F[e]&&(t.enable(e),F[e]=!0)}function f(e){!1!==F[e]&&(t.disable(e),F[e]=!1)}function m(){if(null===z&&(z=[],e.get("WEBGL_compressed_texture_pvrtc")||e.get("WEBGL_compressed_texture_s3tc")||e.get("WEBGL_compressed_texture_etc1")))for(var i=t.getParameter(t.COMPRESSED_TEXTURE_FORMATS),r=0;r<i.length;r++)z.push(i[r]);return z}function g(e,r,n,o,a,s,c,u){e!==Ru?p(t.BLEND):f(t.BLEND),e===U&&u===X||(e===Du?u?(t.blendEquationSeparate(t.FUNC_ADD,t.FUNC_ADD),t.blendFuncSeparate(t.ONE,t.ONE,t.ONE,t.ONE)):(t.blendEquation(t.FUNC_ADD),t.blendFunc(t.SRC_ALPHA,t.ONE)):e===Nu?u?(t.blendEquationSeparate(t.FUNC_ADD,t.FUNC_ADD),t.blendFuncSeparate(t.ZERO,t.ZERO,t.ONE_MINUS_SRC_COLOR,t.ONE_MINUS_SRC_ALPHA)):(t.blendEquation(t.FUNC_ADD),t.blendFunc(t.ZERO,t.ONE_MINUS_SRC_COLOR)):e===ku?u?(t.blendEquationSeparate(t.FUNC_ADD,t.FUNC_ADD),t.blendFuncSeparate(t.ZERO,t.SRC_COLOR,t.ZERO,t.SRC_ALPHA)):(t.blendEquation(t.FUNC_ADD),t.blendFunc(t.ZERO,t.SRC_COLOR)):u?(t.blendEquationSeparate(t.FUNC_ADD,t.FUNC_ADD),t.blendFuncSeparate(t.ONE,t.ONE_MINUS_SRC_ALPHA,t.ONE,t.ONE_MINUS_SRC_ALPHA)):(t.blendEquationSeparate(t.FUNC_ADD,t.FUNC_ADD),t.blendFuncSeparate(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA,t.ONE,t.ONE_MINUS_SRC_ALPHA)),U=e,X=u),e===Bu?(a=a||r,s=s||n,c=c||o,r===j&&a===$||(t.blendEquationSeparate(i(r),i(a)),j=r,$=a),n===G&&o===V&&s===H&&c===W||(t.blendFuncSeparate(i(n),i(o),i(s),i(c)),G=n,V=o,H=s,W=c)):(j=null,G=null,V=null,$=null,H=null,W=null)}function v(e){e.side===Pu?f(t.CULL_FACE):p(t.CULL_FACE),y(e.side===Mu),!0===e.transparent?g(e.blending,e.blendEquation,e.blendSrc,e.blendDst,e.blendEquationAlpha,e.blendSrcAlpha,e.blendDstAlpha,e.premultipliedAlpha):g(Ru),R.setFunc(e.depthFunc),R.setTest(e.depthTest),R.setMask(e.depthWrite),L.setMask(e.colorWrite),_(e.polygonOffset,e.polygonOffsetFactor,e.polygonOffsetUnits)}function y(e){q!==e&&(e?t.frontFace(t.CW):t.frontFace(t.CCW),q=e)}function b(e){e!==yu?(p(t.CULL_FACE),e!==Y&&(e===bu?t.cullFace(t.BACK):e===xu?t.cullFace(t.FRONT):t.cullFace(t.FRONT_AND_BACK))):f(t.CULL_FACE),Y=e}function x(e){e!==Z&&(it&&t.lineWidth(e),Z=e)}function _(e,i,r){e?(p(t.POLYGON_OFFSET_FILL),K===i&&Q===r||(t.polygonOffset(i,r),K=i,Q=r)):f(t.POLYGON_OFFSET_FILL)}function w(){return J}function S(e){J=e,e?p(t.SCISSOR_TEST):f(t.SCISSOR_TEST)}function A(e){void 0===e&&(e=t.TEXTURE0+tt-1),rt!==e&&(t.activeTexture(e),rt=e)}function M(e,i){null===rt&&A();var r=nt[rt];void 0===r&&(r={type:void 0,texture:void 0},nt[rt]=r),r.type===e&&r.texture===i||(t.bindTexture(e,i||st[e]),r.type=e,r.texture=i)}function P(){try{t.compressedTexImage2D.apply(t,arguments)}catch(t){console.error(t)}}function T(){try{t.texImage2D.apply(t,arguments)}catch(t){console.error(t)}}function E(e){!1===ot.equals(e)&&(t.scissor(e.x,e.y,e.z,e.w),ot.copy(e))}function C(e){!1===at.equals(e)&&(t.viewport(e.x,e.y,e.z,e.w),at.copy(e))}function I(){for(var e=0;e<k.length;e++)1===k[e]&&(t.disableVertexAttribArray(e),k[e]=0);F={},z=null,rt=null,nt={},U=null,q=null,Y=null,L.reset(),R.reset(),O.reset()}var L=new r,R=new n,O=new o,D=t.getParameter(t.MAX_VERTEX_ATTRIBS),N=new Uint8Array(D),k=new Uint8Array(D),B=new Uint8Array(D),F={},z=null,U=null,j=null,G=null,V=null,$=null,H=null,W=null,X=!1,q=null,Y=null,Z=null,K=null,Q=null,J=null,tt=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),et=parseFloat(/^WebGL\ ([0-9])/.exec(t.getParameter(t.VERSION))[1]),it=parseFloat(et)>=1,rt=null,nt={},ot=new d,at=new d,st={};return st[t.TEXTURE_2D]=a(t.TEXTURE_2D,t.TEXTURE_2D,1),st[t.TEXTURE_CUBE_MAP]=a(t.TEXTURE_CUBE_MAP,t.TEXTURE_CUBE_MAP_POSITIVE_X,6),{buffers:{color:L,depth:R,stencil:O},init:s,initAttributes:c,enableAttribute:u,enableAttributeAndDivisor:h,disableUnusedAttributes:l,enable:p,disable:f,getCompressedTextureFormats:m,setBlending:g,setMaterial:v,setFlipSided:y,setCullFace:b,setLineWidth:x,setPolygonOffset:_,getScissorTest:w,setScissorTest:S,activeTexture:A,bindTexture:M,compressedTexImage2D:P,texImage2D:T,scissor:E,viewport:C,reset:I}}function pe(t,e,i){function r(){if(void 0!==o)return o;var i=e.get("EXT_texture_filter_anisotropic");return o=null!==i?t.getParameter(i.MAX_TEXTURE_MAX_ANISOTROPY_EXT):0}function n(e){if("highp"===e){if(t.getShaderPrecisionFormat(t.VERTEX_SHADER,t.HIGH_FLOAT).precision>0&&t.getShaderPrecisionFormat(t.FRAGMENT_SHADER,t.HIGH_FLOAT).precision>0)return"highp";e="mediump"}return"mediump"===e&&t.getShaderPrecisionFormat(t.VERTEX_SHADER,t.MEDIUM_FLOAT).precision>0&&t.getShaderPrecisionFormat(t.FRAGMENT_SHADER,t.MEDIUM_FLOAT).precision>0?"mediump":"lowp"}var o,a=void 0!==i.precision?i.precision:"highp",s=n(a);s!==a&&(console.warn("THREE.WebGLRenderer:",a,"not supported, using",s,"instead."),a=s);var c=!0===i.logarithmicDepthBuffer&&!!e.get("EXT_frag_depth"),u=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),h=t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),l=t.getParameter(t.MAX_TEXTURE_SIZE),p=t.getParameter(t.MAX_CUBE_MAP_TEXTURE_SIZE),d=t.getParameter(t.MAX_VERTEX_ATTRIBS),f=t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),m=t.getParameter(t.MAX_VARYING_VECTORS),g=t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),v=h>0,y=!!e.get("OES_texture_float");return{getMaxAnisotropy:r,getMaxPrecision:n,precision:a,logarithmicDepthBuffer:c,maxTextures:u,maxVertexTextures:h,maxTextureSize:l,maxCubemapSize:p,maxAttributes:d,maxVertexUniforms:f,maxVaryings:m,maxFragmentUniforms:g,vertexTextures:v,floatFragmentTextures:y,floatVertexTextures:v&&y}}function de(t){var e={};return{get:function(i){if(void 0!==e[i])return e[i];var r;switch(i){case"WEBGL_depth_texture":r=t.getExtension("WEBGL_depth_texture")||t.getExtension("MOZ_WEBGL_depth_texture")||t.getExtension("WEBKIT_WEBGL_depth_texture");break;case"EXT_texture_filter_anisotropic":r=t.getExtension("EXT_texture_filter_anisotropic")||t.getExtension("MOZ_EXT_texture_filter_anisotropic")||t.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case"WEBGL_compressed_texture_s3tc":r=t.getExtension("WEBGL_compressed_texture_s3tc")||t.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||t.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc");break;case"WEBGL_compressed_texture_pvrtc":r=t.getExtension("WEBGL_compressed_texture_pvrtc")||t.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;case"WEBGL_compressed_texture_etc1":r=t.getExtension("WEBGL_compressed_texture_etc1");break;default:r=t.getExtension(i)}return null===r&&console.warn("THREE.WebGLRenderer: "+i+" extension not supported."),e[i]=r,r}}}function fe(){function t(){u.value!==r&&(u.value=r,u.needsUpdate=n>0),i.numPlanes=n,i.numIntersection=0}function e(t,e,r,n){var o=null!==t?t.length:0,a=null;if(0!==o){if(a=u.value,!0!==n||null===a){var h=r+4*o,l=e.matrixWorldInverse;c.getNormalMatrix(l),(null===a||a.length<h)&&(a=new Float32Array(h));for(var p=0,d=r;p!==o;++p,d+=4)s.copy(t[p]).applyMatrix4(l,c),s.normal.toArray(a,d),a[d+3]=s.constant}u.value=a,u.needsUpdate=!0}return i.numPlanes=o,a}var i=this,r=null,n=0,o=!1,a=!1,s=new ht,c=new ut,u={value:null,needsUpdate:!1};this.uniform=u,this.numPlanes=0,this.numIntersection=0,this.init=function(t,i,a){var s=0!==t.length||i||0!==n||o;return o=i,r=e(t,a,0),n=t.length,s},this.beginShadows=function(){a=!0,e(null)},this.endShadows=function(){a=!1,t()},this.setState=function(i,s,c,h,l,p){if(!o||null===i||0===i.length||a&&!c)a?e(null):t();else{var d=a?0:n,f=4*d,m=l.clippingState||null;u.value=m,m=e(i,h,f,p);for(var g=0;g!==f;++g)m[g]=r[g];l.clippingState=m,this.numIntersection=s?this.numPlanes:0,this.numPlanes+=d}}}function me(t){function e(){return null===K?vt:1}function i(){Zt.init(),Zt.scissor(st.copy(yt).multiplyScalar(vt)),Zt.viewport(ut.copy(_t).multiplyScalar(vt)),Zt.buffers.color.setClear(dt.r,dt.g,dt.b,ft,G)}function r(){Z=null,at=null,nt="",et=-1,Zt.reset()}function n(t){t.preventDefault(),r(),i(),Kt.clear(),ee.clear()}function o(t){var e=t.target;e.removeEventListener("dispose",o),a(e)}function a(t){s(t),Kt.remove(t)}function s(t){var e=Kt.get(t).program;t.program=void 0,void 0!==e&&ie.releaseProgram(e)}function c(t,e,i){t.render(function(t){Y.renderBufferImmediate(t,e,i)})}function u(t,e){return Math.abs(e[0])-Math.abs(t[0])}function h(t,e,i,r){if(i&&i.isInstancedBufferGeometry&&null===qt.get("ANGLE_instanced_arrays"))return void console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");void 0===r&&(r=0),Zt.initAttributes();var n=i.attributes,o=e.getAttributes(),a=t.defaultAttributeValues;for(var s in o){var c=o[s];if(c>=0){var u=n[s];if(void 0!==u){var h=u.normalized,l=u.itemSize,p=Jt.get(u),d=p.buffer,f=p.type,m=p.bytesPerElement;if(u.isInterleavedBufferAttribute){var g=u.data,v=g.stride,y=u.offset;g&&g.isInstancedInterleavedBuffer?(Zt.enableAttributeAndDivisor(c,g.meshPerAttribute),void 0===i.maxInstancedCount&&(i.maxInstancedCount=g.meshPerAttribute*g.count)):Zt.enableAttribute(c),Ut.bindBuffer(Ut.ARRAY_BUFFER,d),Ut.vertexAttribPointer(c,l,f,h,v*m,(r*v+y)*m)}else u.isInstancedBufferAttribute?(Zt.enableAttributeAndDivisor(c,u.meshPerAttribute),void 0===i.maxInstancedCount&&(i.maxInstancedCount=u.meshPerAttribute*u.count)):Zt.enableAttribute(c),Ut.bindBuffer(Ut.ARRAY_BUFFER,d),Ut.vertexAttribPointer(c,l,f,h,0,r*l*m)}else if(void 0!==a){var b=a[s];if(void 0!==b)switch(b.length){case 2:Ut.vertexAttrib2fv(c,b);break;case 3:Ut.vertexAttrib3fv(c,b);break;case 4:Ut.vertexAttrib4fv(c,b);break;default:Ut.vertexAttrib1fv(c,b)}}}}Zt.disableUnusedAttributes()}function l(t,e,i){if(t.visible){if(t.layers.test(e.layers))if(t.isLight)$.push(t);else if(t.isSprite)t.frustumCulled&&!wt.intersectsSprite(t)||X.push(t);else if(t.isLensFlare)q.push(t);else if(t.isImmediateRenderObject)i&&Tt.setFromMatrixPosition(t.matrixWorld).applyMatrix4(Pt),H.push(t,null,t.material,Tt.z,null);else if((t.isMesh||t.isLine||t.isPoints)&&(t.isSkinnedMesh&&t.skeleton.update(),!t.frustumCulled||wt.intersectsObject(t))){i&&Tt.setFromMatrixPosition(t.matrixWorld).applyMatrix4(Pt);var r=ee.update(t),n=t.material;if(Array.isArray(n))for(var o=r.groups,a=0,s=o.length;a<s;a++){var c=o[a],u=n[c.materialIndex];u&&u.visible&&H.push(t,r,u,Tt.z,c)}else n.visible&&H.push(t,r,n,Tt.z,null)}for(var h=t.children,a=0,s=h.length;a<s;a++)l(h[a],e,i)}}function p(t,e,i,r){for(var n=0,o=t.length;n<o;n++){var a=t[n],s=a.object,c=a.geometry,u=void 0===r?a.material:r,h=a.group;if(s.onBeforeRender(Y,e,i,c,u,h),i.isArrayCamera&&i.enabled)for(var l=i.cameras,p=0,d=l.length;p<d;p++){var m=l[p],g=m.bounds;Y.setViewport(g.x*mt*vt,g.y*gt*vt,g.z*mt*vt,g.w*gt*vt),Y.setScissor(g.x*mt*vt,g.y*gt*vt,g.z*mt*vt,g.w*gt*vt),Y.setScissorTest(!0),f(s,e,m,c,u,h)}else f(s,e,i,c,u,h);s.onAfterRender(Y,e,i,c,u,h)}}function f(t,e,i,r,n,o){if(t.modelViewMatrix.multiplyMatrices(i.matrixWorldInverse,t.matrixWorld),t.normalMatrix.getNormalMatrix(t.modelViewMatrix),t.isImmediateRenderObject){Zt.setMaterial(n);var a=b(i,e.fog,n,t);nt="",c(t,a,n)}else Y.renderBufferDirect(i,e.fog,r,n,t,o)}function m(t,e,i){var r=Kt.get(t),n=ie.getParameters(t,Ot,e,St.numPlanes,St.numIntersection,i),a=ie.getProgramCode(t,n),c=r.program,u=!0;if(void 0===c)t.addEventListener("dispose",o);else if(c.code!==a)s(t);else{if(void 0!==n.shaderID)return;u=!1}if(u){if(n.shaderID){var h=Ol[n.shaderID];r.__webglShader={name:t.type,uniforms:Ll.clone(h.uniforms),vertexShader:h.vertexShader,fragmentShader:h.fragmentShader}}else r.__webglShader={name:t.type,uniforms:t.uniforms,vertexShader:t.vertexShader,fragmentShader:t.fragmentShader};t.__webglShader=r.__webglShader,c=ie.acquireProgram(t,n,a),r.program=c,t.program=c}var l=c.getAttributes();if(t.morphTargets){t.numSupportedMorphTargets=0;for(p=0;p<Y.maxMorphTargets;p++)l["morphTarget"+p]>=0&&t.numSupportedMorphTargets++}if(t.morphNormals){t.numSupportedMorphNormals=0;for(var p=0;p<Y.maxMorphNormals;p++)l["morphNormal"+p]>=0&&t.numSupportedMorphNormals++}var d=r.__webglShader.uniforms;(t.isShaderMaterial||t.isRawShaderMaterial)&&!0!==t.clipping||(r.numClippingPlanes=St.numPlanes,r.numIntersection=St.numIntersection,d.clippingPlanes=St.uniform),r.fog=e,r.lightsHash=Ot.hash,t.lights&&(d.ambientLightColor.value=Ot.ambient,d.directionalLights.value=Ot.directional,d.spotLights.value=Ot.spot,d.rectAreaLights.value=Ot.rectArea,d.pointLights.value=Ot.point,d.hemisphereLights.value=Ot.hemi,d.directionalShadowMap.value=Ot.directionalShadowMap,d.directionalShadowMatrix.value=Ot.directionalShadowMatrix,d.spotShadowMap.value=Ot.spotShadowMap,d.spotShadowMatrix.value=Ot.spotShadowMatrix,d.pointShadowMap.value=Ot.pointShadowMap,d.pointShadowMatrix.value=Ot.pointShadowMatrix);var f=r.program.getUniforms(),m=J.seqWithValue(f.seq,d);r.uniformsList=m}function b(t,e,i,r){ht=0;var n=Kt.get(i);if(At&&(Mt||t!==at)){var o=t===at&&i.id===et;St.setState(i.clippingPlanes,i.clipIntersection,i.clipShadows,t,n,o)}!1===i.needsUpdate&&(void 0===n.program?i.needsUpdate=!0:i.fog&&n.fog!==e?i.needsUpdate=!0:i.lights&&n.lightsHash!==Ot.hash?i.needsUpdate=!0:void 0===n.numClippingPlanes||n.numClippingPlanes===St.numPlanes&&n.numIntersection===St.numIntersection||(i.needsUpdate=!0)),i.needsUpdate&&(m(i,e,r),i.needsUpdate=!1);var a=!1,s=!1,c=!1,u=n.program,h=u.getUniforms(),l=n.__webglShader.uniforms;if(u.id!==Z&&(Ut.useProgram(u.program),Z=u.id,a=!0,s=!0,c=!0),i.id!==et&&(et=i.id,s=!0),a||t!==at){if(h.setValue(Ut,"projectionMatrix",t.projectionMatrix),Yt.logarithmicDepthBuffer&&h.setValue(Ut,"logDepthBufFC",2/(Math.log(t.far+1)/Math.LN2)),t!==at&&(at=t,s=!0,c=!0),i.isShaderMaterial||i.isMeshPhongMaterial||i.isMeshStandardMaterial||i.envMap){var p=h.map.cameraPosition;void 0!==p&&p.setValue(Ut,Tt.setFromMatrixPosition(t.matrixWorld))}(i.isMeshPhongMaterial||i.isMeshLambertMaterial||i.isMeshBasicMaterial||i.isMeshStandardMaterial||i.isShaderMaterial||i.skinning)&&h.setValue(Ut,"viewMatrix",t.matrixWorldInverse),h.setValue(Ut,"toneMappingExposure",Y.toneMappingExposure),h.setValue(Ut,"toneMappingWhitePoint",Y.toneMappingWhitePoint)}if(i.skinning){h.setOptional(Ut,r,"bindMatrix"),h.setOptional(Ut,r,"bindMatrixInverse");var d=r.skeleton;if(d){var f=d.bones;if(Yt.floatVertexTextures){if(void 0===d.boneTexture){var g=Math.sqrt(4*f.length);g=xl.nextPowerOfTwo(Math.ceil(g)),g=Math.max(g,4);var v=new Float32Array(g*g*4);v.set(d.boneMatrices);var b=new y(v,g,g,Wh,Fh);d.boneMatrices=v,d.boneTexture=b,d.boneTextureSize=g}h.setValue(Ut,"boneTexture",d.boneTexture),h.setValue(Ut,"boneTextureSize",d.boneTextureSize)}else h.setOptional(Ut,d,"boneMatrices")}}return s&&(i.lights&&L(l,c),e&&i.fog&&A(l,e),(i.isMeshBasicMaterial||i.isMeshLambertMaterial||i.isMeshPhongMaterial||i.isMeshStandardMaterial||i.isMeshNormalMaterial||i.isMeshDepthMaterial)&&x(l,i),i.isLineBasicMaterial?_(l,i):i.isLineDashedMaterial?(_(l,i),w(l,i)):i.isPointsMaterial?S(l,i):i.isMeshLambertMaterial?M(l,i):i.isMeshToonMaterial?T(l,i):i.isMeshPhongMaterial?P(l,i):i.isMeshPhysicalMaterial?C(l,i):i.isMeshStandardMaterial?E(l,i):i.isMeshDepthMaterial?i.displacementMap&&(l.displacementMap.value=i.displacementMap,l.displacementScale.value=i.displacementScale,l.displacementBias.value=i.displacementBias):i.isMeshNormalMaterial&&I(l,i),void 0!==l.ltcMat&&(l.ltcMat.value=Il.LTC_MAT_TEXTURE),void 0!==l.ltcMag&&(l.ltcMag.value=Il.LTC_MAG_TEXTURE),J.upload(Ut,n.uniformsList,l,Y)),h.setValue(Ut,"modelViewMatrix",r.modelViewMatrix),h.setValue(Ut,"normalMatrix",r.normalMatrix),h.setValue(Ut,"modelMatrix",r.matrixWorld),u}function x(t,e){t.opacity.value=e.opacity,t.diffuse.value=e.color,e.emissive&&t.emissive.value.copy(e.emissive).multiplyScalar(e.emissiveIntensity),t.map.value=e.map,t.specularMap.value=e.specularMap,t.alphaMap.value=e.alphaMap,e.lightMap&&(t.lightMap.value=e.lightMap,t.lightMapIntensity.value=e.lightMapIntensity),e.aoMap&&(t.aoMap.value=e.aoMap,t.aoMapIntensity.value=e.aoMapIntensity);var i;if(e.map?i=e.map:e.specularMap?i=e.specularMap:e.displacementMap?i=e.displacementMap:e.normalMap?i=e.normalMap:e.bumpMap?i=e.bumpMap:e.roughnessMap?i=e.roughnessMap:e.metalnessMap?i=e.metalnessMap:e.alphaMap?i=e.alphaMap:e.emissiveMap&&(i=e.emissiveMap),void 0!==i){i.isWebGLRenderTarget&&(i=i.texture);var r=i.offset,n=i.repeat;t.offsetRepeat.value.set(r.x,r.y,n.x,n.y)}t.envMap.value=e.envMap,t.flipEnvMap.value=e.envMap&&e.envMap.isCubeTexture?-1:1,t.reflectivity.value=e.reflectivity,t.refractionRatio.value=e.refractionRatio}function _(t,e){t.diffuse.value=e.color,t.opacity.value=e.opacity}function w(t,e){t.dashSize.value=e.dashSize,t.totalSize.value=e.dashSize+e.gapSize,t.scale.value=e.scale}function S(t,e){if(t.diffuse.value=e.color,t.opacity.value=e.opacity,t.size.value=e.size*vt,t.scale.value=.5*gt,t.map.value=e.map,null!==e.map){var i=e.map.offset,r=e.map.repeat;t.offsetRepeat.value.set(i.x,i.y,r.x,r.y)}}function A(t,e){t.fogColor.value=e.color,e.isFog?(t.fogNear.value=e.near,t.fogFar.value=e.far):e.isFogExp2&&(t.fogDensity.value=e.density)}function M(t,e){e.emissiveMap&&(t.emissiveMap.value=e.emissiveMap)}function P(t,e){t.specular.value=e.specular,t.shininess.value=Math.max(e.shininess,1e-4),e.emissiveMap&&(t.emissiveMap.value=e.emissiveMap),e.bumpMap&&(t.bumpMap.value=e.bumpMap,t.bumpScale.value=e.bumpScale),e.normalMap&&(t.normalMap.value=e.normalMap,t.normalScale.value.copy(e.normalScale)),e.displacementMap&&(t.displacementMap.value=e.displacementMap,t.displacementScale.value=e.displacementScale,t.displacementBias.value=e.displacementBias)}function T(t,e){P(t,e),e.gradientMap&&(t.gradientMap.value=e.gradientMap)}function E(t,e){t.roughness.value=e.roughness,t.metalness.value=e.metalness,e.roughnessMap&&(t.roughnessMap.value=e.roughnessMap),e.metalnessMap&&(t.metalnessMap.value=e.metalnessMap),e.emissiveMap&&(t.emissiveMap.value=e.emissiveMap),e.bumpMap&&(t.bumpMap.value=e.bumpMap,t.bumpScale.value=e.bumpScale),e.normalMap&&(t.normalMap.value=e.normalMap,t.normalScale.value.copy(e.normalScale)),e.displacementMap&&(t.displacementMap.value=e.displacementMap,t.displacementScale.value=e.displacementScale,t.displacementBias.value=e.displacementBias),e.envMap&&(t.envMapIntensity.value=e.envMapIntensity)}function C(t,e){t.clearCoat.value=e.clearCoat,t.clearCoatRoughness.value=e.clearCoatRoughness,E(t,e)}function I(t,e){e.bumpMap&&(t.bumpMap.value=e.bumpMap,t.bumpScale.value=e.bumpScale),e.normalMap&&(t.normalMap.value=e.normalMap,t.normalScale.value.copy(e.normalScale)),e.displacementMap&&(t.displacementMap.value=e.displacementMap,t.displacementScale.value=e.displacementScale,t.displacementBias.value=e.displacementBias)}function L(t,e){t.ambientLightColor.needsUpdate=e,t.directionalLights.needsUpdate=e,t.pointLights.needsUpdate=e,t.spotLights.needsUpdate=e,t.rectAreaLights.needsUpdate=e,t.hemisphereLights.needsUpdate=e}function R(t){for(var e=0,i=0,r=t.length;i<r;i++){var n=t[i];n.castShadow&&(Ot.shadows[e]=n,e++)}Ot.shadows.length=e}function O(t,e){var i,r,n,o,a,s,c,u,h=0,l=0,p=0,d=e.matrixWorldInverse,f=0,m=0,g=0,v=0,y=0;for(i=0,r=t.length;i<r;i++)if(n=t[i],a=n.color,s=n.intensity,c=n.distance,u=n.shadow&&n.shadow.map?n.shadow.map.texture:null,n.isAmbientLight)h+=a.r*s,l+=a.g*s,p+=a.b*s;else if(n.isDirectionalLight)(b=re.get(n)).color.copy(n.color).multiplyScalar(n.intensity),b.direction.setFromMatrixPosition(n.matrixWorld),Tt.setFromMatrixPosition(n.target.matrixWorld),b.direction.sub(Tt),b.direction.transformDirection(d),b.shadow=n.castShadow,n.castShadow&&(o=n.shadow,b.shadowBias=o.bias,b.shadowRadius=o.radius,b.shadowMapSize=o.mapSize),Ot.directionalShadowMap[f]=u,Ot.directionalShadowMatrix[f]=n.shadow.matrix,Ot.directional[f]=b,f++;else if(n.isSpotLight)(b=re.get(n)).position.setFromMatrixPosition(n.matrixWorld),b.position.applyMatrix4(d),b.color.copy(a).multiplyScalar(s),b.distance=c,b.direction.setFromMatrixPosition(n.matrixWorld),Tt.setFromMatrixPosition(n.target.matrixWorld),b.direction.sub(Tt),b.direction.transformDirection(d),b.coneCos=Math.cos(n.angle),b.penumbraCos=Math.cos(n.angle*(1-n.penumbra)),b.decay=0===n.distance?0:n.decay,b.shadow=n.castShadow,n.castShadow&&(o=n.shadow,b.shadowBias=o.bias,b.shadowRadius=o.radius,b.shadowMapSize=o.mapSize),Ot.spotShadowMap[g]=u,Ot.spotShadowMatrix[g]=n.shadow.matrix,Ot.spot[g]=b,g++;else if(n.isRectAreaLight)(b=re.get(n)).color.copy(a).multiplyScalar(s/(n.width*n.height)),b.position.setFromMatrixPosition(n.matrixWorld),b.position.applyMatrix4(d),Lt.identity(),Et.copy(n.matrixWorld),Et.premultiply(d),Lt.extractRotation(Et),b.halfWidth.set(.5*n.width,0,0),b.halfHeight.set(0,.5*n.height,0),b.halfWidth.applyMatrix4(Lt),b.halfHeight.applyMatrix4(Lt),Ot.rectArea[v]=b,v++;else if(n.isPointLight)(b=re.get(n)).position.setFromMatrixPosition(n.matrixWorld),b.position.applyMatrix4(d),b.color.copy(n.color).multiplyScalar(n.intensity),b.distance=n.distance,b.decay=0===n.distance?0:n.decay,b.shadow=n.castShadow,n.castShadow&&(o=n.shadow,b.shadowBias=o.bias,b.shadowRadius=o.radius,b.shadowMapSize=o.mapSize),Ot.pointShadowMap[m]=u,Ot.pointShadowMatrix[m]=n.shadow.matrix,Ot.point[m]=b,m++;else if(n.isHemisphereLight){var b=re.get(n);b.direction.setFromMatrixPosition(n.matrixWorld),b.direction.transformDirection(d),b.direction.normalize(),b.skyColor.copy(n.color).multiplyScalar(s),b.groundColor.copy(n.groundColor).multiplyScalar(s),Ot.hemi[y]=b,y++}Ot.ambient[0]=h,Ot.ambient[1]=l,Ot.ambient[2]=p,Ot.directional.length=f,Ot.spot.length=g,Ot.rectArea.length=v,Ot.point.length=m,Ot.hemi.length=y,Ot.hash=f+","+m+","+g+","+v+","+y+","+Ot.shadows.length}function D(){var t=ht;return t>=Yt.maxTextures&&console.warn("WebGLRenderer: trying to use "+t+" texture units while this GPU supports only "+Yt.maxTextures),ht+=1,t}function N(t){var e;if(t===Sh)return Ut.REPEAT;if(t===Ah)return Ut.CLAMP_TO_EDGE;if(t===Mh)return Ut.MIRRORED_REPEAT;if(t===Ph)return Ut.NEAREST;if(t===Th)return Ut.NEAREST_MIPMAP_NEAREST;if(t===Eh)return Ut.NEAREST_MIPMAP_LINEAR;if(t===Ch)return Ut.LINEAR;if(t===Ih)return Ut.LINEAR_MIPMAP_NEAREST;if(t===Lh)return Ut.LINEAR_MIPMAP_LINEAR;if(t===Rh)return Ut.UNSIGNED_BYTE;if(t===Uh)return Ut.UNSIGNED_SHORT_4_4_4_4;if(t===jh)return Ut.UNSIGNED_SHORT_5_5_5_1;if(t===Gh)return Ut.UNSIGNED_SHORT_5_6_5;if(t===Oh)return Ut.BYTE;if(t===Dh)return Ut.SHORT;if(t===Nh)return Ut.UNSIGNED_SHORT;if(t===kh)return Ut.INT;if(t===Bh)return Ut.UNSIGNED_INT;if(t===Fh)return Ut.FLOAT;if(t===zh&&null!==(e=qt.get("OES_texture_half_float")))return e.HALF_FLOAT_OES;if(t===$h)return Ut.ALPHA;if(t===Hh)return Ut.RGB;if(t===Wh)return Ut.RGBA;if(t===Xh)return Ut.LUMINANCE;if(t===qh)return Ut.LUMINANCE_ALPHA;if(t===Yh)return Ut.DEPTH_COMPONENT;if(t===Zh)return Ut.DEPTH_STENCIL;if(t===Fu)return Ut.FUNC_ADD;if(t===zu)return Ut.FUNC_SUBTRACT;if(t===Uu)return Ut.FUNC_REVERSE_SUBTRACT;if(t===Vu)return Ut.ZERO;if(t===$u)return Ut.ONE;if(t===Hu)return Ut.SRC_COLOR;if(t===Wu)return Ut.ONE_MINUS_SRC_COLOR;if(t===Xu)return Ut.SRC_ALPHA;if(t===qu)return Ut.ONE_MINUS_SRC_ALPHA;if(t===Yu)return Ut.DST_ALPHA;if(t===Zu)return Ut.ONE_MINUS_DST_ALPHA;if(t===Ku)return Ut.DST_COLOR;if(t===Qu)return Ut.ONE_MINUS_DST_COLOR;if(t===Ju)return Ut.SRC_ALPHA_SATURATE;if((t===Kh||t===Qh||t===Jh||t===tl)&&null!==(e=qt.get("WEBGL_compressed_texture_s3tc"))){if(t===Kh)return e.COMPRESSED_RGB_S3TC_DXT1_EXT;if(t===Qh)return e.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(t===Jh)return e.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(t===tl)return e.COMPRESSED_RGBA_S3TC_DXT5_EXT}if((t===el||t===il||t===rl||t===nl)&&null!==(e=qt.get("WEBGL_compressed_texture_pvrtc"))){if(t===el)return e.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(t===il)return e.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(t===rl)return e.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(t===nl)return e.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(t===ol&&null!==(e=qt.get("WEBGL_compressed_texture_etc1")))return e.COMPRESSED_RGB_ETC1_WEBGL;if((t===ju||t===Gu)&&null!==(e=qt.get("EXT_blend_minmax"))){if(t===ju)return e.MIN_EXT;if(t===Gu)return e.MAX_EXT}return t===Vh&&null!==(e=qt.get("WEBGL_depth_texture"))?e.UNSIGNED_INT_24_8_WEBGL:0}console.log("THREE.WebGLRenderer",vu);var k=void 0!==(t=t||{}).canvas?t.canvas:document.createElementNS("http://www.w3.org/1999/xhtml","canvas"),B=void 0!==t.context?t.context:null,F=void 0!==t.alpha&&t.alpha,z=void 0===t.depth||t.depth,U=void 0===t.stencil||t.stencil,j=void 0!==t.antialias&&t.antialias,G=void 0===t.premultipliedAlpha||t.premultipliedAlpha,V=void 0!==t.preserveDrawingBuffer&&t.preserveDrawingBuffer,$=[],H=null,W=new Float32Array(8),X=[],q=[];this.domElement=k,this.context=null,this.autoClear=!0,this.autoClearColor=!0,this.autoClearDepth=!0,this.autoClearStencil=!0,this.sortObjects=!0,this.clippingPlanes=[],this.localClippingEnabled=!1,this.gammaFactor=2,this.gammaInput=!1,this.gammaOutput=!1,this.physicallyCorrectLights=!1,this.toneMapping=ph,this.toneMappingExposure=1,this.toneMappingWhitePoint=1,this.maxMorphTargets=8,this.maxMorphNormals=4;var Y=this,Z=null,K=null,Q=null,et=-1,nt="",at=null,st=new d,ct=null,ut=new d,ht=0,dt=new tt(0),ft=0,mt=k.width,gt=k.height,vt=1,yt=new d(0,0,mt,gt),bt=!1,_t=new d(0,0,mt,gt),wt=new lt,St=new fe,At=!1,Mt=!1,Pt=new v,Tt=new g,Et=new v,Lt=new v,Ot={hash:"",ambient:[0,0,0],directional:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotShadowMap:[],spotShadowMatrix:[],rectArea:[],point:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],shadows:[]},Nt={geometries:0,textures:0},zt={frame:0,calls:0,vertices:0,faces:0,points:0};this.info={render:zt,memory:Nt,programs:null};var Ut;try{var jt={alpha:F,depth:z,stencil:U,antialias:j,premultipliedAlpha:G,preserveDrawingBuffer:V};if(null===(Ut=B||k.getContext("webgl",jt)||k.getContext("experimental-webgl",jt)))throw null!==k.getContext("webgl")?"Error creating WebGL context with your selected attributes.":"Error creating WebGL context.";void 0===Ut.getShaderPrecisionFormat&&(Ut.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}}),k.addEventListener("webglcontextlost",n,!1)}catch(t){console.error("THREE.WebGLRenderer: "+t)}var qt=new de(Ut);qt.get("WEBGL_depth_texture"),qt.get("OES_texture_float"),qt.get("OES_texture_float_linear"),qt.get("OES_texture_half_float"),qt.get("OES_texture_half_float_linear"),qt.get("OES_standard_derivatives"),qt.get("ANGLE_instanced_arrays"),qt.get("OES_element_index_uint")&&(Ct.MaxIndex=4294967296);var Yt=new pe(Ut,qt,t),Zt=new le(Ut,qt,N),Kt=new he,Qt=new ue(Ut,qt,Zt,Kt,Yt,N,Nt),Jt=new Ft(Ut),te=new Ht(Ut,Jt,Nt),ee=new Xt(Ut,te,zt),ie=new ce(this,Yt),re=new Wt,ne=new Gt;this.info.programs=ie.programs;var oe,ae,se,me,ge=new $t(Ut,qt,zt),ve=new Vt(Ut,qt,zt);i(),this.context=Ut,this.capabilities=Yt,this.extensions=qt,this.properties=Kt,this.state=Zt;var ye=new pt(this,Ot,ee,Yt);this.shadowMap=ye;var be=new rt(this,X),xe=new it(this,q);this.getContext=function(){return Ut},this.getContextAttributes=function(){return Ut.getContextAttributes()},this.forceContextLoss=function(){var t=qt.get("WEBGL_lose_context");t&&t.loseContext()},this.getMaxAnisotropy=function(){return Yt.getMaxAnisotropy()},this.getPrecision=function(){return Yt.precision},this.getPixelRatio=function(){return vt},this.setPixelRatio=function(t){void 0!==t&&(vt=t,this.setSize(_t.z,_t.w,!1))},this.getSize=function(){return{width:mt,height:gt}},this.setSize=function(t,e,i){mt=t,gt=e,k.width=t*vt,k.height=e*vt,!1!==i&&(k.style.width=t+"px",k.style.height=e+"px"),this.setViewport(0,0,t,e)},this.setViewport=function(t,e,i,r){Zt.viewport(_t.set(t,e,i,r))},this.setScissor=function(t,e,i,r){Zt.scissor(yt.set(t,e,i,r))},this.setScissorTest=function(t){Zt.setScissorTest(bt=t)},this.getClearColor=function(){return dt},this.setClearColor=function(t,e){dt.set(t),ft=void 0!==e?e:1,Zt.buffers.color.setClear(dt.r,dt.g,dt.b,ft,G)},this.getClearAlpha=function(){return ft},this.setClearAlpha=function(t){ft=t,Zt.buffers.color.setClear(dt.r,dt.g,dt.b,ft,G)},this.clear=function(t,e,i){var r=0;(void 0===t||t)&&(r|=Ut.COLOR_BUFFER_BIT),(void 0===e||e)&&(r|=Ut.DEPTH_BUFFER_BIT),(void 0===i||i)&&(r|=Ut.STENCIL_BUFFER_BIT),Ut.clear(r)},this.clearColor=function(){this.clear(!0,!1,!1)},this.clearDepth=function(){this.clear(!1,!0,!1)},this.clearStencil=function(){this.clear(!1,!1,!0)},this.clearTarget=function(t,e,i,r){this.setRenderTarget(t),this.clear(e,i,r)},this.resetGLState=r,this.dispose=function(){k.removeEventListener("webglcontextlost",n,!1),ne.dispose()},this.renderBufferImmediate=function(t,e,i){Zt.initAttributes();var r=Kt.get(t);t.hasPositions&&!r.position&&(r.position=Ut.createBuffer()),t.hasNormals&&!r.normal&&(r.normal=Ut.createBuffer()),t.hasUvs&&!r.uv&&(r.uv=Ut.createBuffer()),t.hasColors&&!r.color&&(r.color=Ut.createBuffer());var n=e.getAttributes();if(t.hasPositions&&(Ut.bindBuffer(Ut.ARRAY_BUFFER,r.position),Ut.bufferData(Ut.ARRAY_BUFFER,t.positionArray,Ut.DYNAMIC_DRAW),Zt.enableAttribute(n.position),Ut.vertexAttribPointer(n.position,3,Ut.FLOAT,!1,0,0)),t.hasNormals){if(Ut.bindBuffer(Ut.ARRAY_BUFFER,r.normal),!i.isMeshPhongMaterial&&!i.isMeshStandardMaterial&&!i.isMeshNormalMaterial&&i.shading===Tu)for(var o=0,a=3*t.count;o<a;o+=9){var s=t.normalArray,c=(s[o+0]+s[o+3]+s[o+6])/3,u=(s[o+1]+s[o+4]+s[o+7])/3,h=(s[o+2]+s[o+5]+s[o+8])/3;s[o+0]=c,s[o+1]=u,s[o+2]=h,s[o+3]=c,s[o+4]=u,s[o+5]=h,s[o+6]=c,s[o+7]=u,s[o+8]=h}Ut.bufferData(Ut.ARRAY_BUFFER,t.normalArray,Ut.DYNAMIC_DRAW),Zt.enableAttribute(n.normal),Ut.vertexAttribPointer(n.normal,3,Ut.FLOAT,!1,0,0)}t.hasUvs&&i.map&&(Ut.bindBuffer(Ut.ARRAY_BUFFER,r.uv),Ut.bufferData(Ut.ARRAY_BUFFER,t.uvArray,Ut.DYNAMIC_DRAW),Zt.enableAttribute(n.uv),Ut.vertexAttribPointer(Jt.uv,2,Ut.FLOAT,!1,0,0)),t.hasColors&&i.vertexColors!==Cu&&(Ut.bindBuffer(Ut.ARRAY_BUFFER,r.color),Ut.bufferData(Ut.ARRAY_BUFFER,t.colorArray,Ut.DYNAMIC_DRAW),Zt.enableAttribute(n.color),Ut.vertexAttribPointer(n.color,3,Ut.FLOAT,!1,0,0)),Zt.disableUnusedAttributes(),Ut.drawArrays(Ut.TRIANGLES,0,t.count),t.count=0},this.renderBufferDirect=function(t,i,r,n,o,a){Zt.setMaterial(n);var s=b(t,i,n,o),c=r.id+"_"+s.id+"_"+(!0===n.wireframe),l=!1;c!==nt&&(nt=c,l=!0);var p=o.morphTargetInfluences;if(void 0!==p){for(var d=[],f=0,m=p.length;f<m;f++){v=p[f];d.push([v,f])}d.sort(u),d.length>8&&(d.length=8);for(var g=r.morphAttributes,f=0,m=d.length;f<m;f++){var v=d[f];if(W[f]=v[0],0!==v[0]){x=v[1];!0===n.morphTargets&&g.position&&r.addAttribute("morphTarget"+f,g.position[x]),!0===n.morphNormals&&g.normal&&r.addAttribute("morphNormal"+f,g.normal[x])}else!0===n.morphTargets&&r.removeAttribute("morphTarget"+f),!0===n.morphNormals&&r.removeAttribute("morphNormal"+f)}for(var f=d.length,y=W.length;f<y;f++)W[f]=0;s.getUniforms().setValue(Ut,"morphTargetInfluences",W),l=!0}var x=r.index,_=r.attributes.position,w=1;!0===n.wireframe&&(x=te.getWireframeAttribute(r),w=2);var S=ge;null!==x&&(S=ve).setIndex(x),l&&(h(n,s,r),null!==x&&Ut.bindBuffer(Ut.ELEMENT_ARRAY_BUFFER,Jt.get(x).buffer));var A=0;null!==x?A=x.count:void 0!==_&&(A=_.count);var M=r.drawRange.start*w,P=r.drawRange.count*w,T=null!==a?a.start*w:0,E=null!==a?a.count*w:1/0,C=Math.max(M,T),I=Math.min(A,M+P,T+E)-1,L=Math.max(0,I-C+1);if(0!==L){if(o.isMesh)if(!0===n.wireframe)Zt.setLineWidth(n.wireframeLinewidth*e()),S.setMode(Ut.LINES);else switch(o.drawMode){case cl:S.setMode(Ut.TRIANGLES);break;case ul:S.setMode(Ut.TRIANGLE_STRIP);break;case hl:S.setMode(Ut.TRIANGLE_FAN)}else if(o.isLine){var R=n.linewidth;void 0===R&&(R=1),Zt.setLineWidth(R*e()),o.isLineSegments?S.setMode(Ut.LINES):o.isLineLoop?S.setMode(Ut.LINE_LOOP):S.setMode(Ut.LINE_STRIP)}else o.isPoints&&S.setMode(Ut.POINTS);r&&r.isInstancedBufferGeometry?r.maxInstancedCount>0&&S.renderInstances(r,C,L):S.render(C,L)}},this.compile=function(t,e){$=[],t.traverse(function(t){t.isLight&&$.push(t)}),O($,e),t.traverse(function(e){if(e.material)if(Array.isArray(e.material))for(var i=0;i<e.material.length;i++)m(e.material[i],t.fog,e);else m(e.material,t.fog,e)})},this.render=function(t,e,i,r){if(void 0!==e&&!0!==e.isCamera)return void console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");nt="",et=-1,at=null,!0===t.autoUpdate&&t.updateMatrixWorld(),e.onBeforeRender(Y),null===e.parent&&e.updateMatrixWorld(),e.matrixWorldInverse.getInverse(e.matrixWorld),Pt.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),wt.setFromMatrix(Pt),$.length=0,X.length=0,q.length=0,Mt=this.localClippingEnabled,At=St.init(this.clippingPlanes,Mt,e),(H=ne.get(t,e)).init(),l(t,e,Y.sortObjects),H.finish(),!0===Y.sortObjects&&H.sort(),At&&St.beginShadows(),R($),ye.render(t,e),O($,e),At&&St.endShadows(),zt.frame++,zt.calls=0,zt.vertices=0,zt.faces=0,zt.points=0,void 0===i&&(i=null),this.setRenderTarget(i);var n=t.background;null===n?Zt.buffers.color.setClear(dt.r,dt.g,dt.b,ft,G):n&&n.isColor&&(Zt.buffers.color.setClear(n.r,n.g,n.b,1,G),r=!0),(this.autoClear||r)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil),n&&n.isCubeTexture?(void 0===se&&(se=new kt,me=new It(new Rt(5,5,5),new ot({uniforms:Ol.cube.uniforms,vertexShader:Ol.cube.vertexShader,fragmentShader:Ol.cube.fragmentShader,side:Mu,depthTest:!1,depthWrite:!1,fog:!1}))),se.projectionMatrix.copy(e.projectionMatrix),se.matrixWorld.extractRotation(e.matrixWorld),se.matrixWorldInverse.getInverse(se.matrixWorld),me.material.uniforms.tCube.value=n,me.modelViewMatrix.multiplyMatrices(se.matrixWorldInverse,me.matrixWorld),ee.update(me),Y.renderBufferDirect(se,null,me.geometry,me.material,me,null)):n&&n.isTexture&&(void 0===oe&&(oe=new Bt(-1,1,1,-1,0,1),ae=new It(new Dt(2,2),new xt({depthTest:!1,depthWrite:!1,fog:!1}))),ae.material.map=n,ee.update(ae),Y.renderBufferDirect(oe,null,ae.geometry,ae.material,ae,null));var o=H.opaque,a=H.transparent;if(t.overrideMaterial){var s=t.overrideMaterial;o.length&&p(o,t,e,s),a.length&&p(a,t,e,s)}else o.length&&p(o,t,e),a.length&&p(a,t,e);be.render(t,e),xe.render(t,e,ut),i&&Qt.updateRenderTargetMipmap(i),Zt.buffers.depth.setTest(!0),Zt.buffers.depth.setMask(!0),Zt.buffers.color.setMask(!0),e.isArrayCamera&&e.enabled&&Y.setScissorTest(!1),e.onAfterRender(Y)},this.setFaceCulling=function(t,e){Zt.setCullFace(t),Zt.setFlipSided(e===_u)},this.allocTextureUnit=D,this.setTexture2D=function(){var t=!1;return function(e,i){e&&e.isWebGLRenderTarget&&(t||(console.warn("THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead."),t=!0),e=e.texture),Qt.setTexture2D(e,i)}}(),this.setTexture=function(){var t=!1;return function(e,i){t||(console.warn("THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead."),t=!0),Qt.setTexture2D(e,i)}}(),this.setTextureCube=function(){var t=!1;return function(e,i){e&&e.isWebGLRenderTargetCube&&(t||(console.warn("THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead."),t=!0),e=e.texture),e&&e.isCubeTexture||Array.isArray(e.image)&&6===e.image.length?Qt.setTextureCube(e,i):Qt.setTextureCubeDynamic(e,i)}}(),this.getRenderTarget=function(){return K},this.setRenderTarget=function(t){K=t,t&&void 0===Kt.get(t).__webglFramebuffer&&Qt.setupRenderTarget(t);var e,i=t&&t.isWebGLRenderTargetCube;if(t){var r=Kt.get(t);e=i?r.__webglFramebuffer[t.activeCubeFace]:r.__webglFramebuffer,st.copy(t.scissor),ct=t.scissorTest,ut.copy(t.viewport)}else e=null,st.copy(yt).multiplyScalar(vt),ct=bt,ut.copy(_t).multiplyScalar(vt);if(Q!==e&&(Ut.bindFramebuffer(Ut.FRAMEBUFFER,e),Q=e),Zt.scissor(st),Zt.setScissorTest(ct),Zt.viewport(ut),i){var n=Kt.get(t.texture);Ut.framebufferTexture2D(Ut.FRAMEBUFFER,Ut.COLOR_ATTACHMENT0,Ut.TEXTURE_CUBE_MAP_POSITIVE_X+t.activeCubeFace,n.__webglTexture,t.activeMipMapLevel)}},this.readRenderTargetPixels=function(t,e,i,r,n,o){if(!1===(t&&t.isWebGLRenderTarget))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");var a=Kt.get(t).__webglFramebuffer;if(a){var s=!1;a!==Q&&(Ut.bindFramebuffer(Ut.FRAMEBUFFER,a),s=!0);try{var c=t.texture,u=c.format,h=c.type;if(u!==Wh&&N(u)!==Ut.getParameter(Ut.IMPLEMENTATION_COLOR_READ_FORMAT))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");if(!(h===Rh||N(h)===Ut.getParameter(Ut.IMPLEMENTATION_COLOR_READ_TYPE)||h===Fh&&(qt.get("OES_texture_float")||qt.get("WEBGL_color_buffer_float"))||h===zh&&qt.get("EXT_color_buffer_half_float")))return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");Ut.checkFramebufferStatus(Ut.FRAMEBUFFER)===Ut.FRAMEBUFFER_COMPLETE?e>=0&&e<=t.width-r&&i>=0&&i<=t.height-n&&Ut.readPixels(e,i,r,n,N(u),N(h),o):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.")}finally{s&&Ut.bindFramebuffer(Ut.FRAMEBUFFER,Q)}}}}function ge(t,e){this.name="",this.color=new tt(t),this.density=void 0!==e?e:25e-5}function ve(t,e,i){this.name="",this.color=new tt(t),this.near=void 0!==e?e:1,this.far=void 0!==i?i:1e3}function ye(){gt.call(this),this.type="Scene",this.background=null,this.fog=null,this.overrideMaterial=null,this.autoUpdate=!0}function be(t,e,i,r,n){gt.call(this),this.lensFlares=[],this.positionScreen=new g,this.customUpdateCallback=void 0,void 0!==t&&this.add(t,e,i,r,n)}function xe(t){nt.call(this),this.type="SpriteMaterial",this.color=new tt(16777215),this.map=null,this.rotation=0,this.fog=!1,this.lights=!1,this.setValues(t)}function _e(t){gt.call(this),this.type="Sprite",this.material=void 0!==t?t:new xe}function we(){gt.call(this),this.type="LOD",Object.defineProperties(this,{levels:{enumerable:!0,value:[]}})}function Se(t,e){var i=this;if(t=t||[],this.bones=t.slice(0),this.boneMatrices=new Float32Array(16*this.bones.length),void 0===e)this.calculateInverses();else if(this.bones.length===e.length)this.boneInverses=e.slice(0);else{console.warn("THREE.Skeleton boneInverses is the wrong length."),this.boneInverses=[];for(var r=0,n=this.bones.length;r<n;r++)i.boneInverses.push(new v)}}function Ae(){gt.call(this),this.type="Bone"}function Me(t,e){It.call(this,t,e),this.type="SkinnedMesh",this.bindMode="attached",this.bindMatrix=new v,this.bindMatrixInverse=new v;var i=new Se(this.initBones());this.bind(i,this.matrixWorld),this.normalizeSkinWeights()}function Pe(t){nt.call(this),this.type="LineBasicMaterial",this.color=new tt(16777215),this.linewidth=1,this.linecap="round",this.linejoin="round",this.lights=!1,this.setValues(t)}function Te(t,e,i){if(1===i)return console.warn("THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead."),new Ee(t,e);gt.call(this),this.type="Line",this.geometry=void 0!==t?t:new Ct,this.material=void 0!==e?e:new Pe({color:16777215*Math.random()})}function Ee(t,e){Te.call(this,t,e),this.type="LineSegments"}function Ce(t,e){Te.call(this,t,e),this.type="LineLoop"}function Ie(t){nt.call(this),this.type="PointsMaterial",this.color=new tt(16777215),this.map=null,this.size=1,this.sizeAttenuation=!0,this.lights=!1,this.setValues(t)}function Le(t,e){gt.call(this),this.type="Points",this.geometry=void 0!==t?t:new Ct,this.material=void 0!==e?e:new Ie({color:16777215*Math.random()})}function Re(){gt.call(this),this.type="Group"}function Oe(t,e,i,r,n,o,a,s,c,u,h,l){p.call(this,null,o,a,s,c,u,r,n,h,l),this.image={width:e,height:i},this.mipmaps=t,this.flipY=!1,this.generateMipmaps=!1}function De(t,e,i,r,n,o,a,s,c){p.call(this,t,e,i,r,n,o,a,s,c),this.needsUpdate=!0}function Ne(t){Ct.call(this),this.type="WireframeGeometry";var e,i,r,n,o,a,s,c,u,h,l=[],p=[0,0],d={},f=["a","b","c"];if(t&&t.isGeometry){var m=t.faces;for(e=0,r=m.length;e<r;e++){var v=m[e];for(i=0;i<3;i++)s=v[f[i]],c=v[f[(i+1)%3]],p[0]=Math.min(s,c),p[1]=Math.max(s,c),void 0===d[u=p[0]+","+p[1]]&&(d[u]={index1:p[0],index2:p[1]})}for(u in d)a=d[u],h=t.vertices[a.index1],l.push(h.x,h.y,h.z),h=t.vertices[a.index2],l.push(h.x,h.y,h.z)}else if(t&&t.isBufferGeometry){var y,b,x,_,w,S,A;if(h=new g,null!==t.index){for(y=t.attributes.position,b=t.index,0===(x=t.groups).length&&(x=[{start:0,count:b.count,materialIndex:0}]),n=0,o=x.length;n<o;++n)for(e=w=(_=x[n]).start,r=w+_.count;e<r;e+=3)for(i=0;i<3;i++)s=b.getX(e+i),c=b.getX(e+(i+1)%3),p[0]=Math.min(s,c),p[1]=Math.max(s,c),void 0===d[u=p[0]+","+p[1]]&&(d[u]={index1:p[0],index2:p[1]});for(u in d)a=d[u],h.fromBufferAttribute(y,a.index1),l.push(h.x,h.y,h.z),h.fromBufferAttribute(y,a.index2),l.push(h.x,h.y,h.z)}else for(e=0,r=(y=t.attributes.position).count/3;e<r;e++)for(i=0;i<3;i++)S=3*e+i,h.fromBufferAttribute(y,S),l.push(h.x,h.y,h.z),A=3*e+(i+1)%3,h.fromBufferAttribute(y,A),l.push(h.x,h.y,h.z)}this.addAttribute("position",new At(l,3))}function ke(t,e,i){Et.call(this),this.type="ParametricGeometry",this.parameters={func:t,slices:e,stacks:i},this.fromBufferGeometry(new Be(t,e,i)),this.mergeVertices()}function Be(t,e,i){Ct.call(this),this.type="ParametricBufferGeometry",this.parameters={func:t,slices:e,stacks:i};var r,n,o=[],a=[],s=[],c=[],u=new g,h=new g,l=new g,p=new g,d=new g,f=e+1;for(r=0;r<=i;r++){var m=r/i;for(n=0;n<=e;n++){var v=n/e;h=t(v,m,h),a.push(h.x,h.y,h.z),v-1e-5>=0?(l=t(v-1e-5,m,l),p.subVectors(h,l)):(l=t(v+1e-5,m,l),p.subVectors(l,h)),m-1e-5>=0?(l=t(v,m-1e-5,l),d.subVectors(h,l)):(l=t(v,m+1e-5,l),d.subVectors(l,h)),u.crossVectors(p,d).normalize(),s.push(u.x,u.y,u.z),c.push(v,m)}}for(r=0;r<i;r++)for(n=0;n<e;n++){var y=r*f+n,b=r*f+n+1,x=(r+1)*f+n+1,_=(r+1)*f+n;o.push(y,b,_),o.push(b,x,_)}this.setIndex(o),this.addAttribute("position",new At(a,3)),this.addAttribute("normal",new At(s,3)),this.addAttribute("uv",new At(c,2))}function Fe(t,e,i,r){Et.call(this),this.type="PolyhedronGeometry",this.parameters={vertices:t,indices:e,radius:i,detail:r},this.fromBufferGeometry(new ze(t,e,i,r)),this.mergeVertices()}function ze(t,e,i,r){function n(t,e,i,r){var n,o,s=Math.pow(2,r),c=[];for(n=0;n<=s;n++){c[n]=[];var u=t.clone().lerp(i,n/s),h=e.clone().lerp(i,n/s),l=s-n;for(o=0;o<=l;o++)c[n][o]=0===o&&n===s?u:u.clone().lerp(h,o/l)}for(n=0;n<s;n++)for(o=0;o<2*(s-n)-1;o++){var p=Math.floor(o/2);o%2==0?(a(c[n][p+1]),a(c[n+1][p]),a(c[n][p])):(a(c[n][p+1]),a(c[n+1][p+1]),a(c[n+1][p]))}}function o(){for(var t=0;t<f.length;t+=6){var e=f[t+0],i=f[t+2],r=f[t+4],n=Math.max(e,i,r),o=Math.min(e,i,r);n>.9&&o<.1&&(e<.2&&(f[t+0]+=1),i<.2&&(f[t+2]+=1),r<.2&&(f[t+4]+=1))}}function a(t){d.push(t.x,t.y,t.z)}function s(e,i){var r=3*e;i.x=t[r+0],i.y=t[r+1],i.z=t[r+2]}function c(){for(var t=new g,e=new g,i=new g,r=new g,n=new l,o=new l,a=new l,s=0,c=0;s<d.length;s+=9,c+=6){t.set(d[s+0],d[s+1],d[s+2]),e.set(d[s+3],d[s+4],d[s+5]),i.set(d[s+6],d[s+7],d[s+8]),n.set(f[c+0],f[c+1]),o.set(f[c+2],f[c+3]),a.set(f[c+4],f[c+5]),r.copy(t).add(e).add(i).divideScalar(3);var p=h(r);u(n,c+0,t,p),u(o,c+2,e,p),u(a,c+4,i,p)}}function u(t,e,i,r){r<0&&1===t.x&&(f[e]=t.x-1),0===i.x&&0===i.z&&(f[e]=r/2/Math.PI+.5)}function h(t){return Math.atan2(t.z,-t.x)}function p(t){return Math.atan2(-t.y,Math.sqrt(t.x*t.x+t.z*t.z))}Ct.call(this),this.type="PolyhedronBufferGeometry",this.parameters={vertices:t,indices:e,radius:i,detail:r},i=i||1;var d=[],f=[];!function(t){for(var i=new g,r=new g,o=new g,a=0;a<e.length;a+=3)s(e[a+0],i),s(e[a+1],r),s(e[a+2],o),n(i,r,o,t)}(r=r||0),function(t){for(var e=new g,i=0;i<d.length;i+=3)e.x=d[i+0],e.y=d[i+1],e.z=d[i+2],e.normalize().multiplyScalar(t),d[i+0]=e.x,d[i+1]=e.y,d[i+2]=e.z}(i),function(){for(var t=new g,e=0;e<d.length;e+=3){t.x=d[e+0],t.y=d[e+1],t.z=d[e+2];var i=h(t)/2/Math.PI+.5,r=p(t)/Math.PI+.5;f.push(i,1-r)}c(),o()}(),this.addAttribute("position",new At(d,3)),this.addAttribute("normal",new At(d.slice(),3)),this.addAttribute("uv",new At(f,2)),this.normalizeNormals()}function Ue(t,e){Et.call(this),this.type="TetrahedronGeometry",this.parameters={radius:t,detail:e},this.fromBufferGeometry(new je(t,e)),this.mergeVertices()}function je(t,e){var i=[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],r=[2,1,0,0,3,2,1,3,0,2,3,1];ze.call(this,i,r,t,e),this.type="TetrahedronBufferGeometry",this.parameters={radius:t,detail:e}}function Ge(t,e){Et.call(this),this.type="OctahedronGeometry",this.parameters={radius:t,detail:e},this.fromBufferGeometry(new Ve(t,e)),this.mergeVertices()}function Ve(t,e){var i=[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],r=[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2];ze.call(this,i,r,t,e),this.type="OctahedronBufferGeometry",this.parameters={radius:t,detail:e}}function $e(t,e){Et.call(this),this.type="IcosahedronGeometry",this.parameters={radius:t,detail:e},this.fromBufferGeometry(new He(t,e)),this.mergeVertices()}function He(t,e){var i=(1+Math.sqrt(5))/2,r=[-1,i,0,1,i,0,-1,-i,0,1,-i,0,0,-1,i,0,1,i,0,-1,-i,0,1,-i,i,0,-1,i,0,1,-i,0,-1,-i,0,1],n=[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1];ze.call(this,r,n,t,e),this.type="IcosahedronBufferGeometry",this.parameters={radius:t,detail:e}}function We(t,e){Et.call(this),this.type="DodecahedronGeometry",this.parameters={radius:t,detail:e},this.fromBufferGeometry(new Xe(t,e)),this.mergeVertices()}function Xe(t,e){var i=(1+Math.sqrt(5))/2,r=1/i,n=[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-r,-i,0,-r,i,0,r,-i,0,r,i,-r,-i,0,-r,i,0,r,-i,0,r,i,0,-i,0,-r,i,0,-r,-i,0,r,i,0,r],o=[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9];ze.call(this,n,o,t,e),this.type="DodecahedronBufferGeometry",this.parameters={radius:t,detail:e}}function qe(t,e,i,r,n,o){Et.call(this),this.type="TubeGeometry",this.parameters={path:t,tubularSegments:e,radius:i,radialSegments:r,closed:n},void 0!==o&&console.warn("THREE.TubeGeometry: taper has been removed.");var a=new Ye(t,e,i,r,n);this.tangents=a.tangents,this.normals=a.normals,this.binormals=a.binormals,this.fromBufferGeometry(a),this.mergeVertices()}function Ye(t,e,i,r,n){function o(n){var o=t.getPointAt(n/e),a=c.normals[n],s=c.binormals[n];for(h=0;h<=r;h++){var u=h/r*Math.PI*2,l=Math.sin(u),f=-Math.cos(u);d.x=f*a.x+l*s.x,d.y=f*a.y+l*s.y,d.z=f*a.z+l*s.z,d.normalize(),v.push(d.x,d.y,d.z),p.x=o.x+i*d.x,p.y=o.y+i*d.y,p.z=o.z+i*d.z,m.push(p.x,p.y,p.z)}}function a(){for(h=1;h<=e;h++)for(u=1;u<=r;u++){var t=(r+1)*(h-1)+(u-1),i=(r+1)*h+(u-1),n=(r+1)*h+u,o=(r+1)*(h-1)+u;b.push(t,i,o),b.push(i,n,o)}}function s(){for(u=0;u<=e;u++)for(h=0;h<=r;h++)f.x=u/e,f.y=h/r,y.push(f.x,f.y)}Ct.call(this),this.type="TubeBufferGeometry",this.parameters={path:t,tubularSegments:e,radius:i,radialSegments:r,closed:n},e=e||64,i=i||1,r=r||8,n=n||!1;var c=t.computeFrenetFrames(e,n);this.tangents=c.tangents,this.normals=c.normals,this.binormals=c.binormals;var u,h,p=new g,d=new g,f=new l,m=[],v=[],y=[],b=[];!function(){for(u=0;u<e;u++)o(u);o(!1===n?e:0),s(),a()}(),this.setIndex(b),this.addAttribute("position",new At(m,3)),this.addAttribute("normal",new At(v,3)),this.addAttribute("uv",new At(y,2))}function Ze(t,e,i,r,n,o,a){Et.call(this),this.type="TorusKnotGeometry",this.parameters={radius:t,tube:e,tubularSegments:i,radialSegments:r,p:n,q:o},void 0!==a&&console.warn("THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead."),this.fromBufferGeometry(new Ke(t,e,i,r,n,o)),this.mergeVertices()}function Ke(t,e,i,r,n,o){function a(t,e,i,r,n){var o=Math.cos(t),a=Math.sin(t),s=i/e*t,c=Math.cos(s);n.x=r*(2+c)*.5*o,n.y=r*(2+c)*a*.5,n.z=r*Math.sin(s)*.5}Ct.call(this),this.type="TorusKnotBufferGeometry",this.parameters={radius:t,tube:e,tubularSegments:i,radialSegments:r,p:n,q:o},t=t||100,e=e||40,i=Math.floor(i)||64,r=Math.floor(r)||8,n=n||2,o=o||3;var s,c,u=[],h=[],l=[],p=[],d=new g,f=new g,m=new g,v=new g,y=new g,b=new g,x=new g;for(s=0;s<=i;++s){var _=s/i*n*Math.PI*2;for(a(_,n,o,t,m),a(_+.01,n,o,t,v),b.subVectors(v,m),x.addVectors(v,m),y.crossVectors(b,x),x.crossVectors(y,b),y.normalize(),x.normalize(),c=0;c<=r;++c){var w=c/r*Math.PI*2,S=-e*Math.cos(w),A=e*Math.sin(w);d.x=m.x+(S*x.x+A*y.x),d.y=m.y+(S*x.y+A*y.y),d.z=m.z+(S*x.z+A*y.z),h.push(d.x,d.y,d.z),f.subVectors(d,m).normalize(),l.push(f.x,f.y,f.z),p.push(s/i),p.push(c/r)}}for(c=1;c<=i;c++)for(s=1;s<=r;s++){var M=(r+1)*(c-1)+(s-1),P=(r+1)*c+(s-1),T=(r+1)*c+s,E=(r+1)*(c-1)+s;u.push(M,P,E),u.push(P,T,E)}this.setIndex(u),this.addAttribute("position",new At(h,3)),this.addAttribute("normal",new At(l,3)),this.addAttribute("uv",new At(p,2))}function Qe(t,e,i,r,n){Et.call(this),this.type="TorusGeometry",this.parameters={radius:t,tube:e,radialSegments:i,tubularSegments:r,arc:n},this.fromBufferGeometry(new Je(t,e,i,r,n)),this.mergeVertices()}function Je(t,e,i,r,n){Ct.call(this),this.type="TorusBufferGeometry",this.parameters={radius:t,tube:e,radialSegments:i,tubularSegments:r,arc:n},t=t||100,e=e||40,i=Math.floor(i)||8,r=Math.floor(r)||6,n=n||2*Math.PI;var o,a,s=[],c=[],u=[],h=[],l=new g,p=new g,d=new g;for(o=0;o<=i;o++)for(a=0;a<=r;a++){var f=a/r*n,m=o/i*Math.PI*2;p.x=(t+e*Math.cos(m))*Math.cos(f),p.y=(t+e*Math.cos(m))*Math.sin(f),p.z=e*Math.sin(m),c.push(p.x,p.y,p.z),l.x=t*Math.cos(f),l.y=t*Math.sin(f),d.subVectors(p,l).normalize(),u.push(d.x,d.y,d.z),h.push(a/r),h.push(o/i)}for(o=1;o<=i;o++)for(a=1;a<=r;a++){var v=(r+1)*o+a-1,y=(r+1)*(o-1)+a-1,b=(r+1)*(o-1)+a,x=(r+1)*o+a;s.push(v,y,x),s.push(y,b,x)}this.setIndex(s),this.addAttribute("position",new At(c,3)),this.addAttribute("normal",new At(u,3)),this.addAttribute("uv",new At(h,2))}function ti(t,e){Et.call(this),this.type="ExtrudeGeometry",this.parameters={shapes:t,options:e},this.fromBufferGeometry(new ei(t,e)),this.mergeVertices()}function ei(t,e){if(void 0===t)return void(t=[]);Ct.call(this),this.type="ExtrudeBufferGeometry",t=Array.isArray(t)?t:[t],this.addShapeList(t,e),this.computeVertexNormals()}function ii(t,e){Et.call(this),this.type="TextGeometry",this.parameters={text:t,parameters:e},this.fromBufferGeometry(new ri(t,e)),this.mergeVertices()}function ri(t,e){var i=(e=e||{}).font;if(!1===(i&&i.isFont))return console.error("THREE.TextGeometry: font parameter is not an instance of THREE.Font."),new Et;var r=i.generateShapes(t,e.size,e.curveSegments);e.amount=void 0!==e.height?e.height:50,void 0===e.bevelThickness&&(e.bevelThickness=10),void 0===e.bevelSize&&(e.bevelSize=8),void 0===e.bevelEnabled&&(e.bevelEnabled=!1),ei.call(this,r,e),this.type="TextBufferGeometry"}function ni(t,e,i,r,n,o,a){Et.call(this),this.type="SphereGeometry",this.parameters={radius:t,widthSegments:e,heightSegments:i,phiStart:r,phiLength:n,thetaStart:o,thetaLength:a},this.fromBufferGeometry(new oi(t,e,i,r,n,o,a)),this.mergeVertices()}function oi(t,e,i,r,n,o,a){Ct.call(this),this.type="SphereBufferGeometry",this.parameters={radius:t,widthSegments:e,heightSegments:i,phiStart:r,phiLength:n,thetaStart:o,thetaLength:a},t=t||50,e=Math.max(3,Math.floor(e)||8),i=Math.max(2,Math.floor(i)||6),r=void 0!==r?r:0,n=void 0!==n?n:2*Math.PI;var s,c,u=(o=void 0!==o?o:0)+(a=void 0!==a?a:Math.PI),h=0,l=[],p=new g,d=new g,f=[],m=[],v=[],y=[];for(c=0;c<=i;c++){var b=[],x=c/i;for(s=0;s<=e;s++){var _=s/e;p.x=-t*Math.cos(r+_*n)*Math.sin(o+x*a),p.y=t*Math.cos(o+x*a),p.z=t*Math.sin(r+_*n)*Math.sin(o+x*a),m.push(p.x,p.y,p.z),d.set(p.x,p.y,p.z).normalize(),v.push(d.x,d.y,d.z),y.push(_,1-x),b.push(h++)}l.push(b)}for(c=0;c<i;c++)for(s=0;s<e;s++){var w=l[c][s+1],S=l[c][s],A=l[c+1][s],M=l[c+1][s+1];(0!==c||o>0)&&f.push(w,S,M),(c!==i-1||u<Math.PI)&&f.push(S,A,M)}this.setIndex(f),this.addAttribute("position",new At(m,3)),this.addAttribute("normal",new At(v,3)),this.addAttribute("uv",new At(y,2))}function ai(t,e,i,r,n,o){Et.call(this),this.type="RingGeometry",this.parameters={innerRadius:t,outerRadius:e,thetaSegments:i,phiSegments:r,thetaStart:n,thetaLength:o},this.fromBufferGeometry(new si(t,e,i,r,n,o)),this.mergeVertices()}function si(t,e,i,r,n,o){Ct.call(this),this.type="RingBufferGeometry",this.parameters={innerRadius:t,outerRadius:e,thetaSegments:i,phiSegments:r,thetaStart:n,thetaLength:o},t=t||20,e=e||50,n=void 0!==n?n:0,o=void 0!==o?o:2*Math.PI,i=void 0!==i?Math.max(3,i):8;var a,s,c,u=[],h=[],p=[],d=[],f=t,m=(e-t)/(r=void 0!==r?Math.max(1,r):1),v=new g,y=new l;for(s=0;s<=r;s++){for(c=0;c<=i;c++)a=n+c/i*o,v.x=f*Math.cos(a),v.y=f*Math.sin(a),h.push(v.x,v.y,v.z),p.push(0,0,1),y.x=(v.x/e+1)/2,y.y=(v.y/e+1)/2,d.push(y.x,y.y);f+=m}for(s=0;s<r;s++){var b=s*(i+1);for(c=0;c<i;c++){var x=a=c+b,_=a+i+1,w=a+i+2,S=a+1;u.push(x,_,S),u.push(_,w,S)}}this.setIndex(u),this.addAttribute("position",new At(h,3)),this.addAttribute("normal",new At(p,3)),this.addAttribute("uv",new At(d,2))}function ci(t,e,i,r){Et.call(this),this.type="LatheGeometry",this.parameters={points:t,segments:e,phiStart:i,phiLength:r},this.fromBufferGeometry(new ui(t,e,i,r)),this.mergeVertices()}function ui(t,e,i,r){Ct.call(this),this.type="LatheBufferGeometry",this.parameters={points:t,segments:e,phiStart:i,phiLength:r},e=Math.floor(e)||12,i=i||0,r=r||2*Math.PI,r=xl.clamp(r,0,2*Math.PI);var n,o,a,s=[],c=[],u=[],h=1/e,p=new g,d=new l;for(o=0;o<=e;o++){var f=i+o*h*r,m=Math.sin(f),v=Math.cos(f);for(a=0;a<=t.length-1;a++)p.x=t[a].x*m,p.y=t[a].y,p.z=t[a].x*v,c.push(p.x,p.y,p.z),d.x=o/e,d.y=a/(t.length-1),u.push(d.x,d.y)}for(o=0;o<e;o++)for(a=0;a<t.length-1;a++){var y=n=a+o*t.length,b=n+t.length,x=n+t.length+1,_=n+1;s.push(y,b,_),s.push(b,x,_)}if(this.setIndex(s),this.addAttribute("position",new At(c,3)),this.addAttribute("uv",new At(u,2)),this.computeVertexNormals(),r===2*Math.PI){var w=this.attributes.normal.array,S=new g,A=new g,M=new g;for(n=e*t.length*3,o=0,a=0;o<t.length;o++,a+=3)S.x=w[a+0],S.y=w[a+1],S.z=w[a+2],A.x=w[n+a+0],A.y=w[n+a+1],A.z=w[n+a+2],M.addVectors(S,A).normalize(),w[a+0]=w[n+a+0]=M.x,w[a+1]=w[n+a+1]=M.y,w[a+2]=w[n+a+2]=M.z}}function hi(t,e){Et.call(this),this.type="ShapeGeometry","object"==typeof e&&(console.warn("THREE.ShapeGeometry: Options parameter has been removed."),e=e.curveSegments),this.parameters={shapes:t,curveSegments:e},this.fromBufferGeometry(new li(t,e)),this.mergeVertices()}function li(t,e){function i(t){var i,r,c,h=o.length/3,l=t.extractPoints(e),p=l.shape,d=l.holes;if(!1===Fl.isClockWise(p))for(p=p.reverse(),i=0,r=d.length;i<r;i++)c=d[i],!0===Fl.isClockWise(c)&&(d[i]=c.reverse());var f=Fl.triangulateShape(p,d);for(i=0,r=d.length;i<r;i++)c=d[i],p=p.concat(c);for(i=0,r=p.length;i<r;i++){var m=p[i];o.push(m.x,m.y,0),a.push(0,0,1),s.push(m.x,m.y)}for(i=0,r=f.length;i<r;i++){var g=f[i],v=g[0]+h,y=g[1]+h,b=g[2]+h;n.push(v,y,b),u+=3}}var r=this;Ct.call(this),this.type="ShapeBufferGeometry",this.parameters={shapes:t,curveSegments:e},e=e||12;var n=[],o=[],a=[],s=[],c=0,u=0;if(!1===Array.isArray(t))i(t);else for(var h=0;h<t.length;h++)i(t[h]),r.addGroup(c,u,h),c+=u,u=0;this.setIndex(n),this.addAttribute("position",new At(o,3)),this.addAttribute("normal",new At(a,3)),this.addAttribute("uv",new At(s,2))}function pi(t,e){Ct.call(this),this.type="EdgesGeometry",this.parameters={thresholdAngle:e},e=void 0!==e?e:1;var i,r,n,o,a=[],s=Math.cos(xl.DEG2RAD*e),c=[0,0],u={},h=["a","b","c"];t.isBufferGeometry?(o=new Et).fromBufferGeometry(t):o=t.clone(),o.mergeVertices(),o.computeFaceNormals();for(var l=o.vertices,p=o.faces,d=0,f=p.length;d<f;d++)for(var m=p[d],g=0;g<3;g++)i=m[h[g]],r=m[h[(g+1)%3]],c[0]=Math.min(i,r),c[1]=Math.max(i,r),void 0===u[n=c[0]+","+c[1]]?u[n]={index1:c[0],index2:c[1],face1:d,face2:void 0}:u[n].face2=d;for(n in u){var v=u[n];if(void 0===v.face2||p[v.face1].normal.dot(p[v.face2].normal)<=s){var y=l[v.index1];a.push(y.x,y.y,y.z),y=l[v.index2],a.push(y.x,y.y,y.z)}}this.addAttribute("position",new At(a,3))}function di(t,e,i,r,n,o,a,s){Et.call(this),this.type="CylinderGeometry",this.parameters={radiusTop:t,radiusBottom:e,height:i,radialSegments:r,heightSegments:n,openEnded:o,thetaStart:a,thetaLength:s},this.fromBufferGeometry(new fi(t,e,i,r,n,o,a,s)),this.mergeVertices()}function fi(t,e,i,r,n,o,a,s){function c(i){var n,o,c,v=new l,x=new g,_=0,w=!0===i?t:e,S=!0===i?1:-1;for(o=m,n=1;n<=r;n++)p.push(0,y*S,0),d.push(0,S,0),f.push(.5,.5),m++;for(c=m,n=0;n<=r;n++){var A=n/r*s+a,M=Math.cos(A),P=Math.sin(A);x.x=w*P,x.y=y*S,x.z=w*M,p.push(x.x,x.y,x.z),d.push(0,S,0),v.x=.5*M+.5,v.y=.5*P*S+.5,f.push(v.x,v.y),m++}for(n=0;n<r;n++){var T=o+n,E=c+n;!0===i?h.push(E,E+1,T):h.push(E+1,E,T),_+=3}u.addGroup(b,_,!0===i?1:2),b+=_}Ct.call(this),this.type="CylinderBufferGeometry",this.parameters={radiusTop:t,radiusBottom:e,height:i,radialSegments:r,heightSegments:n,openEnded:o,thetaStart:a,thetaLength:s};var u=this;t=void 0!==t?t:20,e=void 0!==e?e:20,i=void 0!==i?i:100,r=Math.floor(r)||8,n=Math.floor(n)||1,o=void 0!==o&&o,a=void 0!==a?a:0,s=void 0!==s?s:2*Math.PI;var h=[],p=[],d=[],f=[],m=0,v=[],y=i/2,b=0;!function(){var o,c,l=new g,x=new g,_=0,w=(e-t)/i;for(c=0;c<=n;c++){var S=[],A=c/n,M=A*(e-t)+t;for(o=0;o<=r;o++){var P=o/r,T=P*s+a,E=Math.sin(T),C=Math.cos(T);x.x=M*E,x.y=-A*i+y,x.z=M*C,p.push(x.x,x.y,x.z),l.set(E,w,C).normalize(),d.push(l.x,l.y,l.z),f.push(P,1-A),S.push(m++)}v.push(S)}for(o=0;o<r;o++)for(c=0;c<n;c++){var I=v[c][o],L=v[c+1][o],R=v[c+1][o+1],O=v[c][o+1];h.push(I,L,O),h.push(L,R,O),_+=6}u.addGroup(b,_,0),b+=_}(),!1===o&&(t>0&&c(!0),e>0&&c(!1)),this.setIndex(h),this.addAttribute("position",new At(p,3)),this.addAttribute("normal",new At(d,3)),this.addAttribute("uv",new At(f,2))}function mi(t,e,i,r,n,o,a){di.call(this,0,t,e,i,r,n,o,a),this.type="ConeGeometry",this.parameters={radius:t,height:e,radialSegments:i,heightSegments:r,openEnded:n,thetaStart:o,thetaLength:a}}function gi(t,e,i,r,n,o,a){fi.call(this,0,t,e,i,r,n,o,a),this.type="ConeBufferGeometry",this.parameters={radius:t,height:e,radialSegments:i,heightSegments:r,openEnded:n,thetaStart:o,thetaLength:a}}function vi(t,e,i,r){Et.call(this),this.type="CircleGeometry",this.parameters={radius:t,segments:e,thetaStart:i,thetaLength:r},this.fromBufferGeometry(new yi(t,e,i,r)),this.mergeVertices()}function yi(t,e,i,r){Ct.call(this),this.type="CircleBufferGeometry",this.parameters={radius:t,segments:e,thetaStart:i,thetaLength:r},t=t||50,e=void 0!==e?Math.max(3,e):8,i=void 0!==i?i:0,r=void 0!==r?r:2*Math.PI;var n,o,a=[],s=[],c=[],u=[],h=new g,p=new l;for(s.push(0,0,0),c.push(0,0,1),u.push(.5,.5),o=0,n=3;o<=e;o++,n+=3){var d=i+o/e*r;h.x=t*Math.cos(d),h.y=t*Math.sin(d),s.push(h.x,h.y,h.z),c.push(0,0,1),p.x=(s[n]/t+1)/2,p.y=(s[n+1]/t+1)/2,u.push(p.x,p.y)}for(n=1;n<=e;n++)a.push(n,n+1,0);this.setIndex(a),this.addAttribute("position",new At(s,3)),this.addAttribute("normal",new At(c,3)),this.addAttribute("uv",new At(u,2))}function bi(t){ot.call(this,{uniforms:Ll.merge([Il.lights,{opacity:{value:1}}]),vertexShader:Rl.shadow_vert,fragmentShader:Rl.shadow_frag}),this.lights=!0,this.transparent=!0,Object.defineProperties(this,{opacity:{enumerable:!0,get:function(){return this.uniforms.opacity.value},set:function(t){this.uniforms.opacity.value=t}}}),this.setValues(t)}function xi(t){ot.call(this,t),this.type="RawShaderMaterial"}function _i(t){nt.call(this),this.defines={STANDARD:""},this.type="MeshStandardMaterial",this.color=new tt(16777215),this.roughness=.5,this.metalness=.5,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new tt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalScale=new l(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.roughnessMap=null,this.metalnessMap=null,this.alphaMap=null,this.envMap=null,this.envMapIntensity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.skinning=!1,this.morphTargets=!1,this.morphNormals=!1,this.setValues(t)}function wi(t){_i.call(this),this.defines={PHYSICAL:""},this.type="MeshPhysicalMaterial",this.reflectivity=.5,this.clearCoat=0,this.clearCoatRoughness=0,this.setValues(t)}function Si(t){nt.call(this),this.type="MeshPhongMaterial",this.color=new tt(16777215),this.specular=new tt(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new tt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalScale=new l(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=ch,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.skinning=!1,this.morphTargets=!1,this.morphNormals=!1,this.setValues(t)}function Ai(t){Si.call(this),this.defines={TOON:""},this.type="MeshToonMaterial",this.gradientMap=null,this.setValues(t)}function Mi(t){nt.call(this,t),this.type="MeshNormalMaterial",this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalScale=new l(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.fog=!1,this.lights=!1,this.skinning=!1,this.morphTargets=!1,this.morphNormals=!1,this.setValues(t)}function Pi(t){nt.call(this),this.type="MeshLambertMaterial",this.color=new tt(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new tt(0),this.emissiveIntensity=1,this.emissiveMap=null,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.combine=ch,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.skinning=!1,this.morphTargets=!1,this.morphNormals=!1,this.setValues(t)}function Ti(t){nt.call(this),this.type="LineDashedMaterial",this.color=new tt(16777215),this.linewidth=1,this.scale=1,this.dashSize=3,this.gapSize=1,this.lights=!1,this.setValues(t)}function Ei(t,e,i){var r=this,n=!1,o=0,a=0;this.onStart=void 0,this.onLoad=t,this.onProgress=e,this.onError=i,this.itemStart=function(t){a++,!1===n&&void 0!==r.onStart&&r.onStart(t,o,a),n=!0},this.itemEnd=function(t){o++,void 0!==r.onProgress&&r.onProgress(t,o,a),o===a&&(n=!1,void 0!==r.onLoad&&r.onLoad())},this.itemError=function(t){void 0!==r.onError&&r.onError(t)}}function Ci(t){this.manager=void 0!==t?t:Gl}function Ii(t){this.manager=void 0!==t?t:Gl,this._parser=null}function Li(t){this.manager=void 0!==t?t:Gl,this._parser=null}function Ri(t){this.manager=void 0!==t?t:Gl}function Oi(t){this.manager=void 0!==t?t:Gl}function Di(t){this.manager=void 0!==t?t:Gl}function Ni(t,e){gt.call(this),this.type="Light",this.color=new tt(t),this.intensity=void 0!==e?e:1,this.receiveShadow=void 0}function ki(t,e,i){Ni.call(this,t,i),this.type="HemisphereLight",this.castShadow=void 0,this.position.copy(gt.DefaultUp),this.updateMatrix(),this.groundColor=new tt(e)}function Bi(t){this.camera=t,this.bias=0,this.radius=1,this.mapSize=new l(512,512),this.map=null,this.matrix=new v}function Fi(){Bi.call(this,new kt(50,1,.5,500))}function zi(t,e,i,r,n,o){Ni.call(this,t,e),this.type="SpotLight",this.position.copy(gt.DefaultUp),this.updateMatrix(),this.target=new gt,Object.defineProperty(this,"power",{get:function(){return this.intensity*Math.PI},set:function(t){this.intensity=t/Math.PI}}),this.distance=void 0!==i?i:0,this.angle=void 0!==r?r:Math.PI/3,this.penumbra=void 0!==n?n:0,this.decay=void 0!==o?o:1,this.shadow=new Fi}function Ui(t,e,i,r){Ni.call(this,t,e),this.type="PointLight",Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(t){this.intensity=t/(4*Math.PI)}}),this.distance=void 0!==i?i:0,this.decay=void 0!==r?r:1,this.shadow=new Bi(new kt(90,1,.5,500))}function ji(){Bi.call(this,new Bt(-5,5,5,-5,.5,500))}function Gi(t,e){Ni.call(this,t,e),this.type="DirectionalLight",this.position.copy(gt.DefaultUp),this.updateMatrix(),this.target=new gt,this.shadow=new ji}function Vi(t,e){Ni.call(this,t,e),this.type="AmbientLight",this.castShadow=void 0}function $i(t,e,i,r){Ni.call(this,t,e),this.type="RectAreaLight",this.position.set(0,1,0),this.updateMatrix(),this.width=void 0!==i?i:10,this.height=void 0!==r?r:10}function Hi(t,e,i,r){this.parameterPositions=t,this._cachedIndex=0,this.resultBuffer=void 0!==r?r:new e.constructor(i),this.sampleValues=e,this.valueSize=i}function Wi(t,e,i,r){Hi.call(this,t,e,i,r),this._weightPrev=-0,this._offsetPrev=-0,this._weightNext=-0,this._offsetNext=-0}function Xi(t,e,i,r){Hi.call(this,t,e,i,r)}function qi(t,e,i,r){Hi.call(this,t,e,i,r)}function Yi(t,e,i,r){if(void 0===t)throw new Error("track name is undefined");if(void 0===e||0===e.length)throw new Error("no keyframes in track named "+t);this.name=t,this.times=Vl.convertArray(e,this.TimeBufferType),this.values=Vl.convertArray(i,this.ValueBufferType),this.setInterpolation(r||this.DefaultInterpolation),this.validate(),this.optimize()}function Zi(t,e,i,r){Yi.call(this,t,e,i,r)}function Ki(t,e,i,r){Hi.call(this,t,e,i,r)}function Qi(t,e,i,r){Yi.call(this,t,e,i,r)}function Ji(t,e,i,r){Yi.call(this,t,e,i,r)}function tr(t,e,i,r){Yi.call(this,t,e,i,r)}function er(t,e,i){Yi.call(this,t,e,i)}function ir(t,e,i,r){Yi.call(this,t,e,i,r)}function rr(t,e,i,r){Yi.apply(this,arguments)}function nr(t,e,i){this.name=t,this.tracks=i,this.duration=void 0!==e?e:-1,this.uuid=xl.generateUUID(),this.duration<0&&this.resetDuration(),this.optimize()}function or(t){this.manager=void 0!==t?t:Gl,this.textures={}}function ar(t){this.manager=void 0!==t?t:Gl}function sr(){this.onLoadStart=function(){},this.onLoadProgress=function(){},this.onLoadComplete=function(){}}function cr(t){"boolean"==typeof t&&(console.warn("THREE.JSONLoader: showStatus parameter has been removed from constructor."),t=void 0),this.manager=void 0!==t?t:Gl,this.withCredentials=!1}function ur(t){this.manager=void 0!==t?t:Gl,this.texturePath=""}function hr(t,e,i,r,n){var o=.5*(r-e),a=.5*(n-i),s=t*t;return(2*i-2*r+o+a)*(t*s)+(-3*i+3*r-2*o-a)*s+o*t+i}function lr(t,e){var i=1-t;return i*i*e}function pr(t,e){return 2*(1-t)*t*e}function dr(t,e){return t*t*e}function fr(t,e,i,r){return lr(t,e)+pr(t,i)+dr(t,r)}function mr(t,e){var i=1-t;return i*i*i*e}function gr(t,e){var i=1-t;return 3*i*i*t*e}function vr(t,e){return 3*(1-t)*t*t*e}function yr(t,e){return t*t*t*e}function br(t,e,i,r,n){return mr(t,e)+gr(t,i)+vr(t,r)+yr(t,n)}function xr(){this.arcLengthDivisions=200}function _r(t,e){xr.call(this),this.v1=t,this.v2=e}function wr(){xr.call(this),this.curves=[],this.autoClose=!1}function Sr(t,e,i,r,n,o,a,s){xr.call(this),this.aX=t,this.aY=e,this.xRadius=i,this.yRadius=r,this.aStartAngle=n,this.aEndAngle=o,this.aClockwise=a,this.aRotation=s||0}function Ar(t){xr.call(this),this.points=void 0===t?[]:t}function Mr(t,e,i,r){xr.call(this),this.v0=t,this.v1=e,this.v2=i,this.v3=r}function Pr(t,e,i){xr.call(this),this.v0=t,this.v1=e,this.v2=i}function Tr(t){wr.call(this),this.currentPoint=new l,t&&this.fromPoints(t)}function Er(){Tr.apply(this,arguments),this.holes=[]}function Cr(){this.subPaths=[],this.currentPath=null}function Ir(t){this.data=t}function Lr(t){this.manager=void 0!==t?t:Gl}function Rr(t){this.manager=void 0!==t?t:Gl}function Or(){this.type="StereoCamera",this.aspect=1,this.eyeSep=.064,this.cameraL=new kt,this.cameraL.layers.enable(1),this.cameraL.matrixAutoUpdate=!1,this.cameraR=new kt,this.cameraR.layers.enable(2),this.cameraR.matrixAutoUpdate=!1}function Dr(t){kt.call(this),this.enabled=!1,this.cameras=t||[]}function Nr(){gt.call(this),this.type="AudioListener",this.context=Kl.getContext(),this.gain=this.context.createGain(),this.gain.connect(this.context.destination),this.filter=null}function kr(t){gt.call(this),this.type="Audio",this.context=t.context,this.gain=this.context.createGain(),this.gain.connect(t.getInput()),this.autoplay=!1,this.buffer=null,this.loop=!1,this.startTime=0,this.playbackRate=1,this.isPlaying=!1,this.hasPlaybackControl=!0,this.sourceType="empty",this.filters=[]}function Br(t){kr.call(this,t),this.panner=this.context.createPanner(),this.panner.connect(this.gain)}function Fr(t,e){this.analyser=t.context.createAnalyser(),this.analyser.fftSize=void 0!==e?e:2048,this.data=new Uint8Array(this.analyser.frequencyBinCount),t.getOutput().connect(this.analyser)}function zr(t,e,i){this.binding=t,this.valueSize=i;var r,n=Float64Array;switch(e){case"quaternion":r=this._slerp;break;case"string":case"bool":n=Array,r=this._select;break;default:r=this._lerp}this.buffer=new n(4*i),this._mixBufferRegion=r,this.cumulativeWeight=0,this.useCount=0,this.referenceCount=0}function Ur(t,e,i){var r=i||jr.parseTrackName(e);this._targetGroup=t,this._bindings=t.subscribe_(e,r)}function jr(t,e,i){this.path=e,this.parsedPath=i||jr.parseTrackName(e),this.node=jr.findNode(t,this.parsedPath.nodeName)||t,this.rootNode=t}function Gr(t){var e=arguments;this.uuid=xl.generateUUID(),this._objects=Array.prototype.slice.call(arguments),this.nCachedObjects_=0;var i={};this._indicesByUUID=i;for(var r=0,n=arguments.length;r!==n;++r)i[e[r].uuid]=r;this._paths=[],this._parsedPaths=[],this._bindings=[],this._bindingsIndicesByPath={};var o=this;this.stats={objects:{get total(){return o._objects.length},get inUse(){return this.total-o.nCachedObjects_}},get bindingsPerObject(){return o._bindings.length}}}function Vr(t,e,i){this._mixer=t,this._clip=e,this._localRoot=i||null;for(var r=e.tracks,n=r.length,o=new Array(n),a={endingStart:sl,endingEnd:sl},s=0;s!==n;++s){var c=r[s].createInterpolant(null);o[s]=c,c.settings=a}this._interpolantSettings=a,this._interpolants=o,this._propertyBindings=new Array(n),this._cacheIndex=null,this._byClipCacheIndex=null,this._timeScaleInterpolant=null,this._weightInterpolant=null,this.loop=al,this._loopCount=-1,this._startTime=null,this.time=0,this.timeScale=1,this._effectiveTimeScale=1,this.weight=1,this._effectiveWeight=1,this.repetitions=1/0,this.paused=!1,this.enabled=!0,this.clampWhenFinished=!1,this.zeroSlopeAtStart=!0,this.zeroSlopeAtEnd=!0}function $r(t){this._root=t,this._initMemoryManager(),this._accuIndex=0,this.time=0,this.timeScale=1}function Hr(t){"string"==typeof t&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),t=arguments[1]),this.value=t}function Wr(){Ct.call(this),this.type="InstancedBufferGeometry",this.maxInstancedCount=void 0}function Xr(t,e,i,r){this.uuid=xl.generateUUID(),this.data=t,this.itemSize=e,this.offset=i,this.normalized=!0===r}function qr(t,e){this.uuid=xl.generateUUID(),this.array=t,this.stride=e,this.count=void 0!==t?t.length/e:0,this.dynamic=!1,this.updateRange={offset:0,count:-1},this.onUploadCallback=function(){},this.version=0}function Yr(t,e,i){qr.call(this,t,e),this.meshPerAttribute=i||1}function Zr(t,e,i){_t.call(this,t,e),this.meshPerAttribute=i||1}function Kr(t,e,i,r){this.ray=new dt(t,e),this.near=i||0,this.far=r||1/0,this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}},Object.defineProperties(this.params,{PointCloud:{get:function(){return console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points."),this.Points}}})}function Qr(t,e){return t.distance-e.distance}function Jr(t,e,i,r){if(!1!==t.visible&&(t.raycast(e,i),!0===r))for(var n=t.children,o=0,a=n.length;o<a;o++)Jr(n[o],e,i,!0)}function tn(t){this.autoStart=void 0===t||t,this.startTime=0,this.oldTime=0,this.elapsedTime=0,this.running=!1}function en(t,e,i){return this.radius=void 0!==t?t:1,this.phi=void 0!==e?e:0,this.theta=void 0!==i?i:0,this}function rn(t,e,i){return this.radius=void 0!==t?t:1,this.theta=void 0!==e?e:0,this.y=void 0!==i?i:0,this}function nn(t,e,i,r){this.object=t,this.size=void 0!==e?e:1;var n=void 0!==i?i:16711680,o=void 0!==r?r:1,a=0,s=this.object.geometry;s&&s.isGeometry?a=3*s.faces.length:s&&s.isBufferGeometry&&(a=s.attributes.normal.count);var c=new Ct,u=new At(2*a*3,3);c.addAttribute("position",u),Ee.call(this,c,new Pe({color:n,linewidth:o})),this.matrixAutoUpdate=!1,this.update()}function on(t){var e=this;this.bones=this.getBoneList(t);for(var i=new Ct,r=[],n=[],o=new tt(0,0,1),a=new tt(0,1,0),s=0;s<this.bones.length;s++){var c=e.bones[s];c.parent&&c.parent.isBone&&(r.push(0,0,0),r.push(0,0,0),n.push(o.r,o.g,o.b),n.push(a.r,a.g,a.b))}i.addAttribute("position",new At(r,3)),i.addAttribute("color",new At(n,3));var u=new Pe({vertexColors:Lu,depthTest:!1,depthWrite:!1,transparent:!0});Ee.call(this,i,u),this.root=t,this.matrix=t.matrixWorld,this.matrixAutoUpdate=!1,this.update()}function an(t,e){gt.call(this),this.light=t,this.light.updateMatrixWorld(),this.matrix=t.matrixWorld,this.matrixAutoUpdate=!1;var i=new Ve(e);i.rotateY(.5*Math.PI);var r=new xt({vertexColors:Lu,wireframe:!0}),n=i.getAttribute("position"),o=new Float32Array(3*n.count);i.addAttribute("color",new _t(o,3)),this.add(new It(i,r)),this.update()}function sn(t,e,i,r){this.object=t,this.size=void 0!==e?e:1;var n=void 0!==i?i:16776960,o=void 0!==r?r:1,a=0,s=this.object.geometry;s&&s.isGeometry?a=s.faces.length:console.warn("THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.");var c=new Ct,u=new At(2*a*3,3);c.addAttribute("position",u),Ee.call(this,c,new Pe({color:n,linewidth:o})),this.matrixAutoUpdate=!1,this.update()}function cn(t){function e(t,e,r){i(t,r),i(e,r)}function i(t,e){o.push(0,0,0),a.push(e.r,e.g,e.b),void 0===s[t]&&(s[t]=[]),s[t].push(o.length/3-1)}var r=new Ct,n=new Pe({color:16777215,vertexColors:Iu}),o=[],a=[],s={},c=new tt(16755200),u=new tt(16711680),h=new tt(43775),l=new tt(16777215),p=new tt(3355443);e("n1","n2",c),e("n2","n4",c),e("n4","n3",c),e("n3","n1",c),e("f1","f2",c),e("f2","f4",c),e("f4","f3",c),e("f3","f1",c),e("n1","f1",c),e("n2","f2",c),e("n3","f3",c),e("n4","f4",c),e("p","n1",u),e("p","n2",u),e("p","n3",u),e("p","n4",u),e("u1","u2",h),e("u2","u3",h),e("u3","u1",h),e("c","t",l),e("p","c",p),e("cn1","cn2",p),e("cn3","cn4",p),e("cf1","cf2",p),e("cf3","cf4",p),r.addAttribute("position",new At(o,3)),r.addAttribute("color",new At(a,3)),Ee.call(this,r,n),this.camera=t,this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix(),this.matrix=t.matrixWorld,this.matrixAutoUpdate=!1,this.pointMap=s,this.update()}function un(){function t(t,o,a,s){e=t,i=a,r=-3*t+3*o-2*a-s,n=2*t-2*o+a+s}var e=0,i=0,r=0,n=0;return{initCatmullRom:function(e,i,r,n,o){t(i,r,o*(r-e),o*(n-i))},initNonuniformCatmullRom:function(e,i,r,n,o,a,s){var c=(i-e)/o-(r-e)/(o+a)+(r-i)/a,u=(r-i)/a-(n-i)/(a+s)+(n-r)/s;t(i,r,c*=a,u*=a)},calc:function(t){var o=t*t;return e+i*t+r*o+n*(o*t)}}}function hn(t){xr.call(this),this.points=t||[],this.closed=!1}function ln(t){console.warn("THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead."),hn.call(this,t),this.type="catmullrom"}function pn(t){if("undefined"!=typeof window){var e=new RegExp(t+"=([^&#=]*)").exec(window.location.search);return e?decodeURIComponent(e[1]):void 0}}function dn(t,e){return void 0!==t?t:e}function fn(){var t=window.location.protocol;return null===t.match(/http(s)?:/gi)?"http:":t}function mn(){if("undefined"==typeof window)return!1;var t=window.navigator.userAgent;return/Opera|OPR/.test(t)?"Opera":/Chrome/i.test(t)?"Chrome":/Firefox/i.test(t)?"Firefox":/Mobile(\/.*)? Safari/i.test(t)?"Mobile Safari":/MSIE/i.test(t)?"Internet Explorer":!!/Safari/i.test(t)&&"Safari"}function gn(t){var e=window.location,i=e.pathname,r=i.substring(0,i.lastIndexOf("/")+1);return e.origin+r+t}function vn(t,e){function i(t){window.open(t,"_blank")||(window.location.href=t)}function r(t){i(o?t:t.replace(/^data:[^;]*;/,"data:attachment/file;"))}if(t){e=e||"download";var n="Safari"===mn(),o=/CriOS\/[\d]+/.test(window.navigator.userAgent),a=document.createElement("a");if("undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob)navigator.msSaveOrOpenBlob(t,e);else if((n||o)&&window.FileReader)if(t instanceof Blob){var s=new FileReader;s.onloadend=function(){r(s.result)},s.readAsDataURL(t)}else r(t);else t instanceof Blob&&(t=URL.createObjectURL(t)),"download"in a?(a.style.display="hidden",document.body.appendChild(a),a.href=t,a.download=e,a.target="_blank",a.click(),document.body.removeChild(a)):i(t),t instanceof Blob&&URL.revokeObjectURL(t)}}function yn(t){var e,i,r,n=["gz"],o=(e="undefined"!=typeof File&&t instanceof File||"undefined"!=typeof Blob&&t instanceof Blob?t.name||"":t).lastIndexOf("?"),a=(e=e.substring(0,-1===o?e.length:o)).replace(/^.*[\\\/]/,""),s=a.substring(0,a.lastIndexOf(".")),c=a.split("."),u=c.length>1?c.pop().toLowerCase():"",h=e.match(/^(.+):\/\/(.+)$/);h&&(r=h[1].toLowerCase(),e=h[2]);var l=e.substring(0,e.lastIndexOf("/")+1);if(n.includes(u)){i=u;var p=e.length-u.length-1;u=e.substr(0,p).split(".").pop().toLowerCase();var d=s.length-u.length-1;s=s.substr(0,d)}else i=!1;return{path:e,name:a,ext:u,base:s,dir:l,compressed:i,protocol:r,src:t}}function bn(t,e,i){var r,n,o,a=null,s=0;i||(i={});var c=function(){s=!1===i.leading?0:Date.now(),a=null,o=t.apply(r,n),a||(r=n=null)};return function(){var u=Date.now();s||!1!==i.leading||(s=u);var h=e-(u-s);return r=this,n=arguments,h<=0||h>e?(a&&(clearTimeout(a),a=null),s=u,o=t.apply(r,n),a||(r=n=null)):a||!1===i.trailing||(a=setTimeout(c,h)),o}}function xn(t,e){return t<e?-1:t>e?1:0}function _n(t,e,i){void 0===i&&(i=xn);for(var r=0,n=t.length-1;r<=n;){var o=r+n>>1,a=i(e,t[o]);if(a>0)r=o+1;else{if(!(a<0))return o;n=o-1}}return-r-1}function wn(t,e){var i=t.length-1;if(t[i]<e)return-1;for(var r=0;r<=i;){var n=r+i>>1;t[n]>=e?i=n-1:r=n+1}return i+1}function Sn(t,e){if(t[0]>e)return-1;for(var i=0,r=t.length-1;i<=r;){var n=i+r>>1;t[n]>e?r=n-1:i=n+1}return i-1}function An(t,e,i){var r=wn(t,e),n=Sn(t,i);return-1===r||-1===n||r>n?0:n-r+1}function Mn(t){return t.sort().filter(function(t,e,i){return 0===e||t!==i[e-1]})}function Pn(t){if(t.length>28672){for(var e=[],i=0;i<t.length;i+=28672)e.push(String.fromCharCode.apply(null,t.subarray(i,i+28672)));return e.join("")}return String.fromCharCode.apply(null,t)}function Tn(t,e,i){e=void 0!==e?e:10485760,i=void 0!==i?i:"\n";for(var r="",n=[],o=0;o<t.length;o+=e){var a=Pn(t.subarray(o,o+e)),s=a.lastIndexOf(i);if(-1===s)r+=a;else{var c=r+a.substr(0,s);n=n.concat(c.split(i)),r=s===a.length-i.length?"":a.substr(s+i.length)}}return""!==r&&n.push(r),n}function En(t,e){switch(t){case"int8":return new Int8Array(e);case"int16":return new Int16Array(e);case"int32":return new Int32Array(e);case"uint8":return new Uint8Array(e);case"uint16":return new Uint16Array(e);case"uint32":return new Uint32Array(e);case"float32":return new Float32Array(e);default:throw"arrayType unknown: "+t}}function Cn(t,e){return new(e>65535?Uint32Array:Uint16Array)(t)}function In(t,e){return t instanceof e?t:new e(t)}function Ln(t,e){return void 0===t?t=new e:Array.isArray(t)&&(t=(new e).fromArray(t)),t}function Rn(t){return Ln(t,l)}function On(t){return Ln(t,g)}function Dn(t){return Ln(t,v)}function Nn(t){return Ln(t,m)}function kn(t){return In(t,Float32Array)}function Bn(t){return dn(t,"").toString().toLowerCase()}function Fn(t){var e=t;return t.forEach(function(t){t.__deps&&Array.prototype.push.apply(e,Fn(t.__deps))}),e}function zn(t){return Mn(Fn(t)).map(function(t){return t.toString()}).join("\n\n\n")}function Un(t){var e=t.data.__name,i=t.data.__postId;if(void 0===e)console.error("message __name undefined");else if(void 0===self.func)console.error("worker func undefined",e);else{var r=function(t,e){t=t||{},void 0!==i&&(t.__postId=i);try{self.postMessage(t,e)}catch(e){console.error("self.postMessage:",e),self.postMessage(t)}};self.func(t,r)}}function jn(t,e){var i="'use strict';\n\n"+zn(e);return i+="\n\n\nself.func = "+t.toString()+";",i+="\n\n\nself.onmessage = "+Un.toString()+";",new Blob([i],{type:"application/javascript"})}function Gn(t){return.01745*t}function Vn(t){return 57.29578*t}function $n(){for(var t,e=0,i=0;i<36;i++)8===i||13===i||18===i||23===i?Ld[i]="-":14===i?Ld[i]="4":(e<=2&&(e=33554432+16777216*Math.random()|0),t=15&e,e>>=4,Ld[i]=Id[19===i?3&t|8:t]);return Ld.join("")}function Hn(t){return t-=t>>1&1431655765,16843009*((t=(858993459&t)+(t>>2&858993459))+(t>>4)&252645135)>>24}function Wn(t,e,i){return(t-e)/(i-e)}function Xn(t,e,i){return Math.max(e,Math.min(i,t))}function qn(t){return Xn(t,0,100)}function Yn(t){return Xn(t,0,1)}function Zn(t,e,i){return t+(e-t)*i}function Kn(t,e,i,r,n,o){var a=(i-t)*o,s=(r-e)*o,c=n*n;return(2*e-2*i+a+s)*(n*c)+(-3*e+3*i-2*a-s)*c+a*n+e}function Qn(t,e,i){return(i=Yn(Wn(i,t,e)))*i*(3-2*i)}function Jn(t,e,i){if(t>e)return t;var r=t/e;return((2*i-e)*r+(2*e-3*i))*r*r+i}function to(t,e,i,r,n){this._listener=e,this._isOnce=i,this.context=r,this._signal=t,this._priority=n||0}function eo(t,e){if("function"!=typeof t)throw new Error("listener is a required param of {fn}() and should be a Function.".replace("{fn}",e))}function io(){this._bindings=[],this._prevParams=null;var t=this;this.dispatch=function(){io.prototype.dispatch.apply(t,arguments)}}function ro(t,e){if(void 0===e.atomname&&void 0===e.element&&void 0===e.altloc&&void 0===e.atomindex&&void 0===e.keyword&&void 0===e.inscode&&void 0===e.resname&&void 0===e.sstruc&&void 0===e.resno&&void 0===e.chainname&&void 0===e.model)return-1;if(void 0!==e.keyword){if(e.keyword===Nd.BACKBONE&&!t.isBackbone())return!1;if(e.keyword===Nd.SIDECHAIN&&!t.isSidechain())return!1;if(e.keyword===Nd.BONDED&&!t.isBonded())return!1;if(e.keyword===Nd.RING&&!t.isRing())return!1;if(e.keyword===Nd.HETERO&&!t.isHetero())return!1;if(e.keyword===Nd.PROTEIN&&!t.isProtein())return!1;if(e.keyword===Nd.NUCLEIC&&!t.isNucleic())return!1;if(e.keyword===Nd.RNA&&!t.isRna())return!1;if(e.keyword===Nd.DNA&&!t.isDna())return!1;if(e.keyword===Nd.POLYMER&&!t.isPolymer())return!1;if(e.keyword===Nd.WATER&&!t.isWater())return!1;if(e.keyword===Nd.HELIX&&!t.isHelix())return!1;if(e.keyword===Nd.SHEET&&!t.isSheet())return!1;if(e.keyword===Nd.TURN&&!t.isTurn())return!1;if(e.keyword===Nd.ION&&!t.isIon())return!1;if(e.keyword===Nd.SACCHARIDE&&!t.isSaccharide())return!1}if(void 0!==e.atomname&&e.atomname!==t.atomname)return!1;if(void 0!==e.element&&e.element!==t.element)return!1;if(void 0!==e.altloc&&e.altloc!==t.altloc)return!1;if(void 0!==e.atomindex&&_n(e.atomindex,t.index)<0)return!1;if(void 0!==e.resname)if(Array.isArray(e.resname)){if(!e.resname.includes(t.resname))return!1}else if(e.resname!==t.resname)return!1;if(void 0!==e.sstruc&&e.sstruc!==t.sstruc)return!1;if(void 0!==e.resno)if(Array.isArray(e.resno)&&2===e.resno.length){if(e.resno[0]>t.resno||e.resno[1]<t.resno)return!1}else if(e.resno!==t.resno)return!1;return(void 0===e.inscode||e.inscode===t.inscode)&&((void 0===e.chainname||e.chainname===t.chainname)&&(void 0===e.model||e.model===t.modelIndex))}function no(t,e){if(void 0===e.resname&&void 0===e.resno&&void 0===e.inscode&&void 0===e.sstruc&&void 0===e.model&&void 0===e.chainname&&void 0===e.atomindex&&(void 0===e.keyword||Bd.includes(e.keyword)))return-1;if(void 0!==e.keyword){if(e.keyword===Nd.HETERO&&!t.isHetero())return!1;if(e.keyword===Nd.PROTEIN&&!t.isProtein())return!1;if(e.keyword===Nd.NUCLEIC&&!t.isNucleic())return!1;if(e.keyword===Nd.RNA&&!t.isRna())return!1;if(e.keyword===Nd.DNA&&!t.isDna())return!1;if(e.keyword===Nd.POLYMER&&!t.isPolymer())return!1;if(e.keyword===Nd.WATER&&!t.isWater())return!1;if(e.keyword===Nd.HELIX&&!t.isHelix())return!1;if(e.keyword===Nd.SHEET&&!t.isSheet())return!1;if(e.keyword===Nd.TURN&&!t.isTurn())return!1;if(e.keyword===Nd.ION&&!t.isIon())return!1;if(e.keyword===Nd.SACCHARIDE&&!t.isSaccharide())return!1}if(void 0!==e.atomindex&&0===An(e.atomindex,t.atomOffset,t.atomEnd))return!1;if(void 0!==e.resname)if(Array.isArray(e.resname)){if(!e.resname.includes(t.resname))return!1}else if(e.resname!==t.resname)return!1;if(void 0!==e.sstruc&&e.sstruc!==t.sstruc)return!1;if(void 0!==e.resno)if(Array.isArray(e.resno)&&2===e.resno.length){if(e.resno[0]>t.resno||e.resno[1]<t.resno)return!1}else if(e.resno!==t.resno)return!1;return(void 0===e.inscode||e.inscode===t.inscode)&&((void 0===e.chainname||e.chainname===t.chainname)&&(void 0===e.model||e.model===t.modelIndex))}function oo(t,e){if(!(void 0!==e.chainname||void 0!==e.model||void 0!==e.atomindex||void 0!==e.keyword&&Fd.includes(e.keyword)&&t.entity))return-1;if(void 0!==e.keyword){if(e.keyword===Nd.POLYMER&&!t.entity.isPolymer())return!1;if(e.keyword===Nd.WATER&&!t.entity.isWater())return!1}return(void 0===e.atomindex||0!==An(e.atomindex,t.atomOffset,t.atomEnd))&&((void 0===e.chainname||e.chainname===t.chainname)&&(void 0===e.model||e.model===t.modelIndex))}function ao(t,e){return void 0===e.model&&void 0===e.atomindex?-1:(void 0===e.atomindex||0!==An(e.atomindex,t.atomOffset,t.atomEnd))&&(void 0===e.model||e.model===t.index)}function so(t){af=t}function co(t){sf=t}function uo(e){t.Debug=e}function ho(t,e){var i=e||{};this.compressed=dn(i.compressed,!1),this.binary=dn(i.binary,!1),this.json=dn(i.json,!1),this.xml=dn(i.xml,!1),this.src=t,this.chunkSize=10485760,this.newline="\n",this.__pointer=0,this.__partialLine="",this.__srcName&&(this[this.__srcName]=t)}function lo(t,e){ho.call(this,t,e)}function po(t,e){ho.call(this,t,e)}function fo(t){var e=yn(t),i=pf.get(e.protocol);return i&&!(e=yn(i.getUrl(e.src))).ext&&i.getExt&&(e.ext=i.getExt(t)),e}function mo(t,e){var i,r=Object.assign(fo(t),e);return ff.names.includes(r.ext)?i=wf:["ngl","js"].includes(r.ext)?i=Mf:"plugin"===r.ext&&(i=Pf),i?new i(r.src,r).load():Promise.reject("autoLoad: ext '"+r.ext+"' unknown")}function go(){var t=arguments[0],e=go.cache;return e[t]&&e.hasOwnProperty(t)||(e[t]=go.parse(t)),go.format.call(null,e[t],arguments)}function vo(t){return"number"==typeof t?"number":"string"==typeof t?"string":Object.prototype.toString.call(t).slice(8,-1).toLowerCase()}function yo(t,e){return e>=0&&e<=7&&Ef[t]?Ef[t][e]:Array(e+1).join(t)}function bo(t,e){function i(){d=[],n(),o(),a()}function r(t,e){return void 0!==t?t:e}function n(){d.push(go("TITEL %-74s",t.name))}function o(){p.forEach(function(t){d.push(go("REMARK %-73s",t))}),t.trajectory&&(d.push(go("REMARK %-73s","Trajectory '"+t.trajectory.name+"'")),d.push(go("REMARK %-73s","Frame "+t.trajectory.frame)))}function a(){var e=1,i=1;t.eachModel(function(t){d.push(go("MODEL %-74d",i++)),t.eachAtom(function(t){var i=t.hetero?m:f,n=l?e:t.serial,o=t.atomname;1===o.length&&(o=" "+o),d.push(go(i,n,o,t.resname,r(t.chainname," "),t.resno,t.x,t.y,t.z,r(t.occurence,1),r(t.bfactor,0),r(t.segid,""),r(t.element,""))),e+=1}),d.push(go("%-80s","ENDMDL")),i+=1}),d.push(go("%-80s","END"))}function s(){return i(),d.join("\n")}function c(){return new Blob([s()],{type:"text/plain"})}function u(t,e){var i=(t=t||"structure")+"."+(e=e||"pdb");vn(c(),i)}var h=Object.assign({},e),l=void 0===h.renumberSerial||h.renumberSerial,p=h.remarks||[];Array.isArray(p)||(p=[p]);var d,f="ATOM  %5d %-4s %3s %1s%4d    %8.3f%8.3f%8.3f%6.2f%6.2f      %4s%2s",m="HETATM%5d %-4s %3s %1s%4d    %8.3f%8.3f%8.3f%6.2f%6.2f      %4s%2s";this.getString=s,this.getBlob=c,this.download=u}function xo(){this.signals={updated:new io},this.begin(),this.maxDuration=-1/0,this.minDuration=1/0,this.avgDuration=14,this.lastDuration=1/0,this.prevFpsTime=0,this.lastFps=1/0,this.lastFrames=1,this.frames=0,this.count=0}function _o(t){if(void 0===t)return"";var e=[];for(var i in t){var r=t[i];!1!==r&&e.push("#define "+i+" "+r)}return e.join("\n")+"\n"}function wo(t,e){e=e||{};var i=t+"|";for(var r in e)i+=r+":"+e[r];if(!Lf[i]){var n=_o(e),o=mf.get("shader/"+t);if(!o)throw"empty shader, '"+t+"'";o=o.replace(If,function(t,e){var i="shader/chunk/"+e+".glsl",r=mf.get(i)||Rl[e];return r||""}),Lf[i]=n+o}return Lf[i]}function So(t,e,i,r){function n(e){var r=e%u,n=Math.floor(e/u),o=r*m,a=n*g;i.camera.setViewOffset(m*u,g*u,o,a,m,g),i.render(),h?v.drawImage(t.domElement,Math.floor(o/2),Math.floor(a/2),Math.ceil(m/2),Math.ceil(g/2)):v.drawImage(t.domElement,Math.floor(o),Math.floor(a),Math.ceil(m),Math.ceil(g)),"function"==typeof l&&l(e+1,d,!1)}function o(){i.setSampling(y),i.camera.view=null,"function"==typeof p&&p(d+1,d,!1)}function a(){for(var t=0;t<=d;++t)t===d?o():n(t)}function s(){function t(){e===d?o():n(e),e+=1}for(var e=0,i=0;i<=d;++i)setTimeout(t,0,i)}var c=r||{},u=void 0!==c.factor?c.factor:2,h=void 0!==c.antialias&&c.antialias,l=c.onProgress,p=c.onFinish;h&&(u*=2);var d=u*u,f=document.createElement("canvas"),m=i.width,g=i.height;h?(f.width=m*u/2,f.height=g*u/2):(f.width=m*u,f.height=g*u);var v=f.getContext("2d"),y=i.sampleLevel;i.setSampling(-1),this.render=a,this.renderAsync=s,this.canvas=f}function Ao(t,e,i,r,n){i=i||1,r=r||0;var o,a,s=n?n.length:t.length/i,c=0,u=0;if(n)for(a=0;a<s;++a)o=(t[n[a]*i+r]+e)%e/e*Ff-Math.PI,c+=Math.cos(o),u+=Math.sin(o);else for(a=r;a<s;a+=i)o=(t[a]+e)%e/e*Ff-Math.PI,c+=Math.cos(o),u+=Math.sin(o);return c/=s,u/=s,(Math.atan2(u,c)+Math.PI)/Ff*e}function Mo(t,e,i,r){var n=t.length;i=i||new Float32Array(n),r=r||0;for(var o=0;o<n;o+=3)i[r+o+0]=(t[o+0]+e[o+0])/2,i[r+o+1]=(t[o+1]+e[o+1])/2,i[r+o+2]=(t[o+2]+e[o+2])/2;return i}function Po(t,e,i){for(var r=i||new Float32Array(t),n=0;n<t;++n)r[n]=e;return r}function To(t,e,i,r,n){for(var o,a=n||new Float32Array(3*t),s=0;s<t;++s)a[(o=3*s)+0]=e,a[o+1]=i,a[o+2]=r;return a}function Eo(t,e){var i=t.length;e=e||new g;for(var r=0;r<i;r+=3)e.x+=t[r],e.y+=t[r+1],e.z+=t[r+2];return e.divideScalar(i/3),e}function Co(t){for(var e=new Float32Array(t),i=0;i<t;++i)e[i]=i;return e}function Io(t,e,i,r){void 0===i&&(i=0);for(var n=r||new Float32Array(t*e),o=0;o<t;++o)for(var a=i+o*e,s=0;s<e;++s)n[a+s]=o;return n}function Lo(t,e){for(var i=t.length,r=new Float32Array(i),n=0;n<i;n++)r[n]=Math.min(t[n],e[n]);return r}function Ro(t,e,i,r,n){for(var o=0;o<n;++o)e[r+o]=t[i+o]}function Oo(t,e,i,r){Ro(t,t,e,i,r)}function Do(t,e,i,r){function n(e,i){p=t[e],t[e]=t[i],t[i]=p}e=e||function(t,e){return t>e?1:t<e?-1:0};for(var o,a,s=[],c=-1,u=i=i||0,h=r=(r||t.length)-1,l=0,p=0;;)if(h-u<=25){for(a=u+1;a<=h;++a){for(l=t[a],o=a-1;o>=u&&e(t[o],l)>0;)t[o+1]=t[o],--o;t[o+1]=l}if(-1===c)break;h=s[c--],u=s[c--]}else{for(a=h,n(u+h>>1,o=u+1),e(t[u],t[h])>0&&n(u,h),e(t[o],t[h])>0&&n(o,h),e(t[u],t[o])>0&&n(u,o),l=t[o];;){do{o++}while(e(t[o],l)<0);do{a--}while(e(t[a],l)>0);if(a<o)break;n(o,a)}t[u+1]=t[a],t[a]=l,h-o+1>=a-u?(s[++c]=o,s[++c]=h,h=a-1):(s[++c]=u,s[++c]=a-1,u=o)}return t}function No(t){for(var e=-1/0,i=0,r=t.length;i<r;++i)t[i]>e&&(e=t[i]);return e}function ko(t){for(var e=1/0,i=0,r=t.length;i<r;++i)t[i]<e&&(e=t[i]);return e}function Bo(t){for(var e=t.length,i=0,r=0;r<e;++r)i+=t[r];return i}function Fo(t){return Bo(t)/t.length}function zo(t){for(var e=t.length,i=0,r=0;r<e;++r){var n=t[r];i+=n*n}return Math.sqrt(i/e)}function Uo(t,e,i,r,n){var o,a,s,c,u=t.height,h=t.width,l=t.getContext("2d").getImageData(0,0,h,u).data;for(s=!1,a=0;a<u;a++){for(o=0;o<h;o++)if(c=4*(a*h+o),l[c]!==e||l[c+1]!==i||l[c+2]!==r||l[c+3]!==n){s=!0;break}if(s)break}var p=a;for(s=!1,o=0;o<h;o++){for(a=0;a<u;a++)if(c=4*(a*h+o),l[c]!==e||l[c+1]!==i||l[c+2]!==r||l[c+3]!==n){s=!0;break}if(s)break}var d=o;for(s=!1,a=u-1;a>=0;a--){for(o=h-1;o>=0;o--)if(c=4*(a*h+o),l[c]!==e||l[c+1]!==i||l[c+2]!==r||l[c+3]!==n){s=!0;break}if(s)break}var f=a;for(s=!1,o=h-1;o>=0;o--){for(a=u-1;a>=0;a--)if(c=4*(a*h+o),l[c]!==e||l[c+1]!==i||l[c+2]!==r||l[c+3]!==n){s=!0;break}if(s)break}var m=o,g=document.createElement("canvas");return g.width=m-d,g.height=f-p,g.getContext("2d").drawImage(t,d,p,g.width,g.height,0,0,g.width,g.height),g}function jo(t,e){function i(e){var i=s;c&&(i*=2),e&&(i=1/i),t.scene.traverse(function(t){var e=t.material;e&&e.linewidth&&(e.linewidth*=i),e&&e.uniforms&&e.uniforms.size&&void 0===e.uniforms.size.__seen&&(e.uniforms.size.value*=i,e.uniforms.size.__seen=!0)}),t.scene.traverse(function(t){var e=t.material;e&&e.uniforms&&e.uniforms.size&&delete e.uniforms.size.__seen})}function r(t){if(a){var e=d;return Uo(t,0|(u?0:255*e.r),0|(u?0:255*e.g),0|(u?0:255*e.b),0|(u?0:255))}return t}function n(t,e,i){"function"==typeof o.onProgress&&o.onProgress(t,e,i)}var o=e||{},a=void 0!==o.trim&&o.trim,s=void 0!==o.factor?o.factor:1,c=void 0!==o.antialias&&o.antialias,u=void 0!==o.transparent&&o.transparent,h=t.renderer,l=t.camera,p=h.getClearAlpha(),d=h.getClearColor();return new Promise(function(e){function o(o,s){r(a.canvas).toBlob(function(r){h.setClearAlpha(p),i(!0),t.requestRender(),n(s,s,!0),e(r)},"image/png")}var a=new So(h,l,t,{factor:s,antialias:c,onProgress:n,onFinish:o});h.setClearAlpha(u?0:1),i(),a.renderAsync()})}function Go(t,e){var i;t.traverseVisible(function(t){if(t instanceof Le&&t.sortParticles){var r=t.geometry.attributes,n=r.position.count;if(0!==n){Uf.multiplyMatrices(e.matrixWorldInverse,t.matrixWorld),jf.multiplyMatrices(e.projectionMatrix,Uf);var o,a,s,c;for(t.userData.sortData?(o=t.userData.sortData,s=o.__zArray,a=o.__sortArray,c=o.__cmpFn):(s=new Float32Array(n),a=new Uint32Array(n),o={__zArray:s,__sortArray:a,__cmpFn:c=function(t,e){var i=s[t],r=s[e];return i>r?1:i<r?-1:0}},t.userData.sortData=o),i=0;i<n;++i)zf.fromArray(r.position.array,3*i),zf.applyMatrix4(jf),s[i]=-zf.z,a[i]=i;Do(a,c);var u,h,l;for(var p in r){var d=r[p],f=d.array,m=d.itemSize;for(o[p]||(o[p]=new Float32Array(m*n)),l=o[p],o[p]=f,i=0;i<n;++i){u=a[i];for(var g=0;g<m;++g)h=u*m+g,l[i*m+g]=f[h]}r[p].array=l,r[p].needsUpdate=!0}}}})}function Vo(t,e,i,r,n){var o=i.getSize().height,a=i.getPixelRatio(),s="OrthographicCamera"===e.type;Gf.getInverse(e.projectionMatrix),Vf.copy(e.projectionMatrix).transpose(),t.traverse(function(t){var e=t.material;if(e){var i=t.material.uniforms;if(i){if(e.clipNear){var c=(50-e.clipNear)/50,u=r-n*c;i.nearClip.value=u}i.canvasHeight&&(i.canvasHeight.value=o),i.pixelRatio&&(i.pixelRatio.value=a),i.projectionMatrixInverse&&i.projectionMatrixInverse.value.copy(Gf),i.projectionMatrixTranspose&&i.projectionMatrixTranspose.value.copy(Vf),i.ortho&&(i.ortho.value=s)}}})}function $o(t,e,i,r,n){var o=n.uniforms,a=[];if(o.objectId&&(o.objectId.value=af?this.id:this.id/255,a.push("objectId")),(o.modelViewMatrixInverse||o.modelViewMatrixInverseTranspose||o.modelViewProjectionMatrix||o.modelViewProjectionMatrixInverse)&&this.modelViewMatrix.multiplyMatrices(i.matrixWorldInverse,this.matrixWorld),o.modelViewMatrixInverse&&(o.modelViewMatrixInverse.value.getInverse(this.modelViewMatrix),a.push("modelViewMatrixInverse")),o.modelViewMatrixInverseTranspose&&(o.modelViewMatrixInverse?o.modelViewMatrixInverseTranspose.value.copy(o.modelViewMatrixInverse.value).transpose():o.modelViewMatrixInverseTranspose.value.getInverse(this.modelViewMatrix).transpose(),a.push("modelViewMatrixInverseTranspose")),o.modelViewProjectionMatrix&&(i.updateProjectionMatrix(),o.modelViewProjectionMatrix.value.multiplyMatrices(i.projectionMatrix,this.modelViewMatrix),a.push("modelViewProjectionMatrix")),o.modelViewProjectionMatrixInverse&&(o.modelViewProjectionMatrix?(Wf.copy(o.modelViewProjectionMatrix.value),o.modelViewProjectionMatrixInverse.value.getInverse(Wf)):(i.updateProjectionMatrix(),Wf.multiplyMatrices(i.projectionMatrix,this.modelViewMatrix),o.modelViewProjectionMatrixInverse.value.getInverse(Wf)),a.push("modelViewProjectionMatrixInverse")),a.length){var s=t.properties.get(n);if(s.program){var c=t.getContext(),u=s.program;c.useProgram(u.program);var h=u.getUniforms();a.forEach(function(t){h.setValue(c,t,o[t].value)})}}}function Ho(e){function i(){K||(K=new ye),(et=new Re).name="rotationGroup",K.add(et),(it=new Re).name="translationGroup",et.add(it),(rt=new Re).name="modelGroup",it.add(rt),(nt=new Re).name="pickingGroup",it.add(nt),(at=new Re).name="backgroundGroup",it.add(at),(ct=new Re).name="helperGroup",it.add(ct),K.fog=new ve,Q=new zi(W.lightColor,W.lightIntensity),K.add(Q),J=new Vi(W.ambientLight,W.ambientIntensity),K.add(J)}function r(){var t=yt.geometry.attributes.position,e=t.array,i=bt.min,r=bt.max;e[0]=r.x,e[1]=r.y,e[2]=r.z,e[3]=i.x,e[4]=r.y,e[5]=r.z,e[6]=i.x,e[7]=i.y,e[8]=r.z,e[9]=r.x,e[10]=i.y,e[11]=r.z,e[12]=r.x,e[13]=r.y,e[14]=i.z,e[15]=i.x,e[16]=r.y,e[17]=i.z,e[18]=i.x,e[19]=i.y,e[20]=i.z,e[21]=r.x,e[22]=i.y,e[23]=i.z,t.needsUpdate=!0,bt.isEmpty()||yt.geometry.computeBoundingSphere()}function n(e,i){i?i.forEach(function(t){o(e,t)}):o(e),e.background?(at.add(e.group),at.add(e.wireframeGroup)):(rt.add(e.group),rt.add(e.wireframeGroup)),e.pickable&&nt.add(e.pickingGroup),t.Debug&&r()}function o(t,e){function i(r){r instanceof Re?r.children.forEach(i):(r.userData.buffer=t,r.userData.instance=e,r.onBeforeRender=$o)}var r=t.getMesh();e&&r.applyMatrix(e.matrix),i(r),t.group.add(r);var n=t.getWireframeMesh();if(e&&(n.matrix.copy(r.matrix),n.position.copy(r.position),n.quaternion.copy(r.quaternion),n.scale.copy(r.scale)),i(n),t.wireframeGroup.add(n),t.pickable){var o=t.getPickingMesh();e&&(o.matrix.copy(r.matrix),o.position.copy(r.position),o.quaternion.copy(r.quaternion),o.scale.copy(r.scale)),i(o),t.pickingGroup.add(o)}e?s(t.geometry,t.matrix,e.matrix):s(t.geometry,t.matrix)}function a(e){it.children.forEach(function(t){t.remove(e.group),t.remove(e.wireframeGroup)}),e.pickable&&nt.remove(e.pickingGroup),s(),t.Debug&&r()}function s(t,e,i){function r(t,e,i){t.boundingBox||t.computeBoundingBox();var r=t.boundingBox.clone();e&&r.applyMatrix4(e),i&&r.applyMatrix4(i),r.min.equals(r.max)&&r.expandByScalar(5),bt.union(r)}function n(t){if(void 0!==t.geometry){var e,i;t.userData.buffer&&(e=t.userData.buffer.matrix),t.userData.instance&&(i=t.userData.instance.matrix),r(t.geometry,e,i)}}t?r(t,e,i):(bt.makeEmpty(),rt.traverse(n),at.traverse(n)),bt.getSize(xt),wt=xt.length()}function c(){return new Promise(function(t){ut.domElement.toBlob(t,"image/png")})}function u(t){return jo(this,t)}function h(t,e,i,r){var n=W;void 0!==t&&n.lightColor.set(t),void 0!==e&&(n.lightIntensity=e),void 0!==i&&n.ambientColor.set(i),void 0!==r&&(n.ambientIntensity=r),S()}function l(t,e,i){var r=W;void 0!==t&&r.fogColor.set(t),void 0!==e&&(r.fogNear=e),void 0!==i&&(r.fogFar=i),S()}function p(t){var e=W;t&&e.backgroundColor.set(t),l(e.backgroundColor),ut.setClearColor(e.backgroundColor,0),ut.domElement.style.backgroundColor=e.backgroundColor.getStyle(),S()}function d(t){void 0!==t&&(W.sampleLevel=t,V=t),S()}function m(t,e){var i=W;t&&(i.cameraType=t),e&&(i.cameraFov=e),"orthographic"===i.cameraType?Z!==Y&&((Z=Y).position.copy(q.position),Z.up.copy(q.up),A()):Z!==q&&((Z=q).position.copy(Y.position),Z.up.copy(Y.up)),q.fov=i.cameraFov,Z.updateProjectionMatrix(),S()}function v(t,e,i){var r=W;void 0!==t&&(r.clipNear=t),void 0!==e&&(r.clipFar=e),void 0!==i&&(r.clipDist=i),S()}function y(t,e){N=t||1,k=e||1,q.aspect=N/k,Y.left=-N/2,Y.right=N/2,Y.top=k/2,Y.bottom=-k/2,Z.updateProjectionMatrix();var i=window.devicePixelRatio;ut.setPixelRatio(i),ut.setSize(N,k);var r=N*i,n=k*i;lt.setSize(r,n),pt.setSize(r,n),dt.setSize(r,n),S()}function b(){if(D===document.body)y(window.innerWidth,window.innerHeight);else{var t=D.getBoundingClientRect();y(t.width,t.height)}}function x(t){var e=At.memory,i=At.render;if(t)e.programs=0,e.geometries=0,e.textures=0,i.calls=0,i.vertices=0,i.faces=0,i.points=0;else{var r=ut.info,n=r.memory,o=r.render;e.programs=n.programs,e.geometries=n.geometries,e.textures=n.textures,i.calls+=o.calls,i.vertices+=o.vertices,i.faces+=o.faces,i.points+=o.points}}function _(){if(B.ticked.dispatch(X),performance.now()-X.startTime>500&&!G&&V<3&&-1!==V){var e=V;V=3,U=!0,R(),G=!0,V=e,t.Debug&&cf.log("rendered still frame")}requestAnimationFrame(_)}function w(t,e){t*=window.devicePixelRatio,e*=window.devicePixelRatio;var i,r,n,o=af?$f:Hf;R(!0),ut.readRenderTargetPixels(lt,t,e,1,1,o),i=af?Math.round(255*o[0])<<16&16711680|Math.round(255*o[1])<<8&65280|255&Math.round(255*o[2]):o[0]<<16|o[1]<<8|o[2];var a=Math.round(o[3]),s=nt.getObjectById(a);return s&&(r=s.userData.instance,n=s.userData.buffer.picking),{pid:i,instance:r,picker:n}}function S(){U||(performance.now()-X.startTime>22&&(X.begin(),G=!1),U=!0,requestAnimationFrame(function(){R(),X.update()}))}function A(){var t=Gn(q.fov),e=2*Math.tan(t/2)*-Z.position.z;Y.zoom=k/e}function M(){var t=W;($=St.copy(Z.position).length())||(Z.position.set(0,0,t.cameraZ),$=Math.abs(t.cameraZ)),H=Math.max(10,.5*wt),((H+=bt.getCenter(St).length())===1/0||H===-1/0||isNaN(H))&&(H=50);var e=(50-t.clipNear)/50,i=-(50-t.clipFar)/50;Z.near=$-H*e,Z.far=$+H*i;var r=(50-t.fogNear)/50,n=-(50-t.fogFar)/50,o=K.fog;o.color.set(t.fogColor),o.near=$-H*r,o.far=$+H*n,"PerspectiveCamera"===Z.type?(Z.near=Math.max(.1,t.clipDist,Z.near),Z.far=Math.max(1,Z.far),o.near=Math.max(.1,o.near),o.far=Math.max(1,o.far)):"OrthographicCamera"===Z.type&&0===t.clipNear&&t.clipDist>0&&$+Z.zoom>2*-t.clipDist&&(Z.near+=Z.zoom+t.clipDist)}function P(){Z.updateMatrix(),Z.updateMatrixWorld(!0),Z.matrixWorldInverse.getInverse(Z.matrixWorld),Z.updateProjectionMatrix(),Vo(K,Z,ut,$,H),Go(K,Z)}function T(t,e,i,r){rt.visible=t,nt.visible=e,at.visible=i,ct.visible=r}function E(){St.copy(Z.position).setLength(100*wt),Q.position.copy(Z.position).add(St),Q.color.set(W.lightColor),Q.intensity=W.lightIntensity,J.color.set(W.ambientColor),J.intensity=W.ambientIntensity}function C(){ut.clearTarget(lt),T(!1,!0,!1,!1),ut.render(K,Z,lt),x(),ut.setRenderTarget(null)}function I(e){e?ut.clearTarget(e):ut.clear(),T(!1,!1,!0,!1),ut.render(K,Z,e),e?ut.clearTarget(e,!1,!0,!1):ut.clearDepth(),x(),T(!0,!1,!1,t.Debug),ut.render(K,Z,e),x()}function L(){var t=Bf[Math.max(0,Math.min(V,5))],e=1/t.length;ft.tForeground.value=pt.texture;for(var i=pt.width,r=pt.height,n=0;n<t.length;++n){var o=t[n];Z.setViewOffset(i,r,o[0],o[1],i,r),P();var a=e;a+=1/32*((n+.5)/t.length-.5),ft.scale.value=a,I(pt),ut.render(vt,gt,dt,0===n)}ft.scale.value=1,ft.tForeground.value=dt.texture,ut.render(vt,gt,null,!0),Z.view=null}function R(t){if(z)return void cf.warn("tried to call 'render' from within 'render'");z=!0,M(),P(),E(),x(!0),t?j||C():V>0?L():I(),j=t,z=!1,U=!1}function O(){cf.log("scene cleared"),K.remove(et),i(),ut.clear()}var D,N,k,B={ticked:new io};if((D="string"==typeof e?document.getElementById(e):e instanceof Element?e:document.createElement("div"))===document.body)N=window.innerWidth||1,k=window.innerHeight||1;else{var F=D.getBoundingClientRect();N=F.width||1,k=F.height||1}var z,U,j,G,V,$,H,W;!function(){W={fogColor:new tt(0),fogNear:50,fogFar:100,backgroundColor:new tt(0),cameraType:"perspective",cameraFov:40,cameraZ:-80,clipNear:0,clipFar:100,clipDist:10,lightColor:new tt(14540253),lightIntensity:1,ambientColor:new tt(14540253),ambientIntensity:.2,sampleLevel:0}}();var X;!function(){X=new xo}();var q,Y,Z;!function(){var t=new g(0,0,0);(q=new kt(W.cameraFov,N/k)).position.z=W.cameraZ,q.lookAt(t),(Y=new Bt(N/-2,N/2,k/2,k/-2)).position.z=W.cameraZ,Y.lookAt(t),(Z="orthographic"===W.cameraType?Y:q).updateProjectionMatrix()}();var K,Q,J,et,it,rt,nt,at,ct;i();var ut,ht,lt,pt,dt,ft,mt,gt,vt;if(!1===function(){var t=window.devicePixelRatio;try{ut=new me({preserveDrawingBuffer:!0,alpha:!0,antialias:!0})}catch(t){return D.innerHTML=uf,!1}ut.setPixelRatio(t),ut.setSize(N,k),ut.autoClear=!1,ut.sortObjects=!0,co(ut.extensions.get("EXT_frag_depth")),ut.extensions.get("OES_element_index_uint"),so(ut.extensions.get("OES_texture_float")&&ut.extensions.get("WEBGL_color_buffer_float")||"Chrome"===nf&&ut.extensions.get("OES_texture_float")),D.appendChild(ut.domElement);var e=N*t,i=k*t;ut.extensions.get("OES_texture_float"),ht=ut.extensions.get("OES_texture_half_float"),ut.extensions.get("WEBGL_color_buffer_float"),(lt=new f(e,i,{minFilter:Ph,magFilter:Ph,stencilBuffer:!1,format:Wh,type:af?Fh:Rh})).texture.generateMipmaps=!1,pt=new f(e,i,{minFilter:Ch,magFilter:Ch,format:Wh}),dt=new f(e,i,{minFilter:Ph,magFilter:Ph,format:Wh,type:of?Rh:ht?zh:af?Fh:Rh}),mt=new ot({uniforms:ft={tForeground:{type:"t",value:null},scale:{type:"f",value:1}},vertexShader:wo("Quad.vert"),fragmentShader:wo("Quad.frag"),premultipliedAlpha:!0,transparent:!0,blending:Du,depthTest:!1,depthWrite:!1}),gt=new Bt(-1,1,1,-1,0,1),vt=(new ye).add(new It(new Ot(2,2),mt))}())return this.container=D,void cf.error("Viewer: could not initialize renderer");var yt,bt=new st,xt=new g,wt=0;!function(){var t=new Uint16Array([0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7]),e=new Float32Array(24),i=new Ct;i.setIndex(new _t(t,1)),i.addAttribute("position",new _t(e,3));var r=new ot({uniforms:{uColor:{value:new tt("skyblue")}},vertexShader:wo("BasicLine.vert"),fragmentShader:wo("BasicLine.frag"),linewidth:2});yt=new Ee(i,r),ct.add(yt)}(),p(),l();var St=new g,At={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0,points:0}};this.container=D,this.stats=X,this.signals=B,this.rotationGroup=et,this.translationGroup=it,this.add=n,this.remove=a,this.clear=O,this.getImage=c,this.makeImage=u,this.setLight=h,this.setFog=l,this.setBackground=p,this.setSampling=d,this.setCamera=m,this.setClip=v,this.setSize=y,this.handleResize=b,this.pick=w,this.requestRender=S,this.render=R,this.animate=_,this.updateZoom=A,this.updateHelper=r,this.renderer=ut,this.scene=K,this.perspectiveCamera=q,this.boundingBox=bt,this.updateBoundingBox=function(){s(),t.Debug&&r()},Object.defineProperties(this,{camera:{get:function(){return Z}},width:{get:function(){return N}},height:{get:function(){return k}},sampleLevel:{get:function(){return V}}})}function Wo(t){var e=t.touches[0].pageX-t.touches[1].pageX,i=t.touches[0].pageY-t.touches[1].pageY;return Math.sqrt(e*e+i*i)}function Xo(t){if("object"==typeof t){if("buttons"in t)return t.buttons;if("which"in t){var e=t.which;if(2===e)return 4;if(3===e)return 2;if(e>0)return 1<<e-1}else if("button"in t){var i=t.button;if(1===i)return 4;if(2===i)return 2;if(i>=0)return 1<<i}}return 0}function qo(t,e,i){return t.distanceTo(e)<t.distanceTo(i)}function Yo(t){var e=t.split(/[-+]/),i="";e.includes("scroll")&&(i="scroll"),e.includes("drag")&&(i="drag"),e.includes("click")&&(i="click"),e.includes("hover")&&(i="hover"),e.includes("clickPick")&&(i="clickPick"),e.includes("hoverPick")&&(i="hoverPick");var r=0;e.includes("alt")&&(r+=1),e.includes("ctrl")&&(r+=2),e.includes("meta")&&(r+=4),e.includes("shift")&&(r+=8);var n=0;return e.includes("left")&&(n+=1),e.includes("right")&&(n+=2),e.includes("middle")&&(n+=4),[i,r,n]}function Zo(t){var e,i=t.length,r=t.length/3,n=0,o=0,a=0;for(e=0;e<i;e+=3)n+=t[e+0],o+=t[e+1],a+=t[e+2];return new g(n/r,o/r,a/r)}function Ko(t,e,i){return i?t.sub(i).projectOnVector(e).add(i):t.projectOnVector(e),t}function Qo(t){for(var e=1/0,i=1/0,r=1/0,n=-1/0,o=-1/0,a=-1/0,s=0,c=t.length;s<c;s+=3){var u=t[s],h=t[s+1],l=t[s+2];u<e&&(e=u),h<i&&(i=h),l<r&&(r=l),u>n&&(n=u),h>o&&(o=h),l>a&&(a=l)}return[ia([e,i,r]),ia([n,o,a])]}function Jo(t,e){for(var i=0,r=e.length;i<r;i+=3){var n=e[i],o=e[i+1],a=e[i+2];e[i]=t[0]*n+t[4]*o+t[8]*a+t[12],e[i+1]=t[1]*n+t[5]*o+t[9]*a+t[13],e[i+2]=t[2]*n+t[6]*o+t[10]*a+t[14]}}function ta(t,e){for(var i=0,r=e.length;i<r;i+=3){var n=e[i],o=e[i+1],a=e[i+2];e[i]=t[0]*n+t[3]*o+t[6]*a,e[i+1]=t[1]*n+t[4]*o+t[7]*a,e[i+2]=t[2]*n+t[5]*o+t[8]*a}}function ea(t){for(var e=0,i=t.length;e<i;e+=3){var r=t[e],n=t[e+1],o=t[e+2],a=1/Math.sqrt(r*r+n*n+o*o);t[e]=r*a,t[e+1]=n*a,t[e+2]=o*a}}function ia(t){return new Float32Array(t||3)}function ra(t,e,i){var r=e[0],n=e[1],o=e[2],a=i[0],s=i[1],c=i[2];t[0]=n*c-o*s,t[1]=o*a-r*c,t[2]=r*s-n*a}function na(t,e,i){t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2]}function oa(t,e,i){t[0]=e[i],t[1]=e[i+1],t[2]=e[i+2]}function aa(t){return Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2])}function sa(t,e,i){ca(t,e,1/i)}function ca(t,e,i){t[0]=e[0]*i,t[1]=e[1]*i,t[2]=e[2]*i}function ua(t,e){ca(t,e,1/aa(e))}function ha(t,e,i){t[0]=e[0]-i,t[1]=e[1]-i,t[2]=e[2]-i}function la(t,e,i){t[0]=e[0]+i,t[1]=e[1]+i,t[2]=e[2]+i}function pa(t,e){t[0]=Math.floor(e[0]),t[1]=Math.floor(e[1]),t[2]=Math.floor(e[2])}function da(t,e){t[0]=Math.ceil(e[0]),t[1]=Math.ceil(e[1]),t[2]=Math.ceil(e[2])}function fa(t,e){t[0]=-e[0],t[1]=-e[1],t[2]=-e[2]}function ma(t){return t-=t>>>1&1431655765,16843009*((t=(858993459&t)+(t>>>2&858993459))+(t>>>4)&252645135)>>>24}function ga(t,e){this.type=t,this.scale=e||1,this.max=10}function va(t,e){this.cols=t,this.rows=e,this.size=this.cols*this.rows,this.data=new Float32Array(this.size)}function ya(t,e){for(var i=0,r=0,n=e.rows,o=e.cols,a=0,s=0,c=0,u=e.data,h=t.data;i<n;s+=1,a+=o,i++)for(c=s,r=0;r<o;c+=n,r++)h[c]=u[a+r]}function ba(t,e,i){for(var r=0,n=0,o=0,a=0,s=0,c=0,u=0,h=e.cols,l=e.rows,p=i.rows,d=e.data,f=i.data,m=t.data,g=0;r<l;a+=h,r++)for(c=0,n=0;n<p;u++,n++){for(s=a,g=0,o=0;o<h;s++,c++,o++)g+=d[s]*f[c];m[u]=g}}function xa(t,e){var i=t.data,r=e.data,n=i[4],o=i[8],a=i[5],s=i[7],c=i[0],u=c*n,h=c*a,l=i[3],p=i[1],d=l*p,f=i[2],m=l*f,g=i[6],v=g*p,y=g*f,b=1/(u*o-h*s-d*o+m*s+v*a-y*n);r[0]=(n*o-a*s)*b,r[1]=-(p*o-f*s)*b,r[2]=-(-p*a+f*n)*b,r[3]=-(l*o-a*g)*b,r[4]=(c*o-y)*b,r[5]=-(h-m)*b,r[6]=-(-l*s+n*g)*b,r[7]=-(c*s-v)*b,r[8]=(u-d)*b}function _a(t){var e=t.data;return e[0]*e[4]*e[8]-e[0]*e[5]*e[7]-e[3]*e[1]*e[8]+e[3]*e[2]*e[7]+e[6]*e[1]*e[5]-e[6]*e[2]*e[4]}function wa(t,e,i){var r=t.data,n=e.data,o=i.data,a=n[0],s=n[1],c=n[2],u=n[3],h=n[4],l=n[5],p=n[6],d=n[7],f=n[8],m=o[0],g=o[1],v=o[2],y=o[3],b=o[4],x=o[5],_=o[6],w=o[7],S=o[8];r[0]=a*m+s*y+c*_,r[1]=a*g+s*b+c*w,r[2]=a*v+s*x+c*S,r[3]=u*m+h*y+l*_,r[4]=u*g+h*b+l*w,r[5]=u*v+h*x+l*S,r[6]=p*m+d*y+f*_,r[7]=p*g+d*b+f*w,r[8]=p*v+d*x+f*S}function Sa(t){var e,i,r=0,n=t.rows,o=t.cols,a=t.data,s=new Array(o);for(i=0;i<o;++i)s[i]=0;for(e=0;e<n;++e)for(i=0;i<o;++i,++r)s[i]+=a[r];for(i=0;i<o;++i)s[i]/=n;return s}function Aa(t,e){var i,r,n=0,o=t.rows,a=t.cols,s=t.data;for(i=0;i<o;++i)for(r=0;r<a;++r,++n)s[n]-=e[r]}function Ma(t,e){var i,r,n=0,o=t.rows,a=t.cols,s=t.data;for(i=0;i<o;++i)for(r=0;r<a;++r,++n)s[n]+=e[r]}function Pa(t,e,i,r){r=t[e],t[e]=t[i],t[i]=r}function Ta(t,e){return t=Math.abs(t),e=Math.abs(e),t>e?(e/=t,t*Math.sqrt(1+e*e)):e>0?(t/=e,e*Math.sqrt(1+t*t)):0}function Ea(t,e,i,r,n,o,a,s){for(var c=2*kg,u=Bg,h=0,l=0,p=0,d=0,f=Math.max(o,30),m=0,g=0,v=0,y=0,b=0,x=0,_=0,w=0,S=0,A=0,M=0,P=0,T=0,E=0,C=0,I=0,L=0,R=4660,O=0,D=0,N=0,k=new Float64Array(a<<3);h<a;h++){for(p=0,M=0;p<o;p++)M+=(w=t[h*e+p])*w;if(k[h]=M,r){for(p=0;p<a;p++)r[h*n+p]=0;r[h*n+h]=1}}for(;d<f;d++){for(b=0,h=0;h<a-1;h++)for(l=h+1;l<a;l++){for(m=h*e|0,g=l*e|0,C=k[h],I=0,L=k[l],p=2,I+=t[m]*t[g],I+=t[m+1]*t[g+1];p<o;p++)I+=t[m+p]*t[g+p];if(!(Math.abs(I)<=c*Math.sqrt(C*L))){for(T=Ta(I*=2,P=C-L),P<0?(E=.5*(T-P),x=I/(T*(_=Math.sqrt(E/T))*2)):_=I/(T*(x=Math.sqrt((T+P)/(2*T)))*2),C=0,L=0,p=2,S=x*t[m]+_*t[g],A=-_*t[m]+x*t[g],t[m]=S,t[g]=A,C+=S*S,L+=A*A,S=x*t[m+1]+_*t[g+1],A=-_*t[m+1]+x*t[g+1],t[m+1]=S,t[g+1]=A,C+=S*S,L+=A*A;p<o;p++)S=x*t[m+p]+_*t[g+p],A=-_*t[m+p]+x*t[g+p],t[m+p]=S,t[g+p]=A,C+=S*S,L+=A*A;if(k[h]=C,k[l]=L,b=1,r)for(y=l*n|0,p=2,S=x*r[v=h*n|0]+_*r[y],A=-_*r[v]+x*r[y],r[v]=S,r[y]=A,S=x*r[v+1]+_*r[y+1],A=-_*r[v+1]+x*r[y+1],r[v+1]=S,r[y+1]=A;p<a;p++)S=x*r[v+p]+_*r[y+p],A=-_*r[v+p]+x*r[y+p],r[v+p]=S,r[y+p]=A}}if(0===b)break}for(h=0;h<a;h++){for(p=0,M=0;p<o;p++)M+=(w=t[h*e+p])*w;k[h]=Math.sqrt(M)}for(h=0;h<a-1;h++){for(l=h,p=h+1;p<a;p++)k[l]<k[p]&&(l=p);if(h!=l&&(Pa(k,h,l,M),r)){for(p=0;p<o;p++)Pa(t,h*e+p,l*e+p,w);for(p=0;p<a;p++)Pa(r,h*n+p,l*n+p,w)}}for(h=0;h<a;h++)i[h]=k[h];if(r)for(h=0;h<s;h++){for(M=h<a?k[h]:0;M<=u;){for(D=1/o,p=0;p<o;p++)O=0!=(256&(R=214013*R+2531011)>>16)?D:-D,t[h*e+p]=O;for(d=0;d<2;d++)for(l=0;l<h;l++){for(M=0,p=0;p<o;p++)M+=t[h*e+p]*t[l*e+p];for(N=0,p=0;p<o;p++)w=t[h*e+p]-M*t[l*e+p],t[h*e+p]=w,N+=Math.abs(w);for(N=N?1/N:0,p=0;p<o;p++)t[h*e+p]*=N}for(M=0,p=0;p<o;p++)M+=(w=t[h*e+p])*w;M=Math.sqrt(M)}for(_=1/M,p=0;p<o;p++)t[h*e+p]*=_}}function Ca(t,e,i,r){var n=0,o=0,a=t.rows,s=t.cols,c=a,u=s;c<u&&(n=1,o=c,c=u,u=o);var h=new va(c,c),l=new va(1,u),p=new va(u,u);if(0===n)ya(h,t);else{for(o=0;o<s*a;o++)h.data[o]=t.data[o];for(;o<u*c;o++)h.data[o]=0}if(Ea(h.data,c,l.data,p.data,u,c,u,c),e){for(o=0;o<u;o++)e.data[o]=l.data[o];for(;o<s;o++)e.data[o]=0}0===n?(i&&ya(i,h),r&&ya(r,p)):(i&&ya(i,p),r&&ya(r,h))}function Ia(){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}function La(t,e,i,r,n,o,a,s,c,u,h,l,p,d,f,m,g){t[0]=e,t[4]=i,t[8]=r,t[12]=n,t[1]=o,t[5]=a,t[9]=s,t[13]=c,t[2]=u,t[6]=h,t[10]=l,t[14]=p,t[3]=d,t[7]=f,t[11]=m,t[15]=g}function Ra(t,e,i){var r=e[0],n=e[4],o=e[8],a=e[12],s=e[1],c=e[5],u=e[9],h=e[13],l=e[2],p=e[6],d=e[10],f=e[14],m=e[3],g=e[7],v=e[11],y=e[15],b=i[0],x=i[4],_=i[8],w=i[12],S=i[1],A=i[5],M=i[9],P=i[13],T=i[2],E=i[6],C=i[10],I=i[14],L=i[3],R=i[7],O=i[11],D=i[15];t[0]=r*b+n*S+o*T+a*L,t[4]=r*x+n*A+o*E+a*R,t[8]=r*_+n*M+o*C+a*O,t[12]=r*w+n*P+o*I+a*D,t[1]=s*b+c*S+u*T+h*L,t[5]=s*x+c*A+u*E+h*R,t[9]=s*_+c*M+u*C+h*O,t[13]=s*w+c*P+u*I+h*D,t[2]=l*b+p*S+d*T+f*L,t[6]=l*x+p*A+d*E+f*R,t[10]=l*_+p*M+d*C+f*O,t[14]=l*w+p*P+d*I+f*D,t[3]=m*b+g*S+v*T+y*L,t[7]=m*x+g*A+v*E+y*R,t[11]=m*_+g*M+v*C+y*O,t[15]=m*w+g*P+v*I+y*D}function Oa(t,e,i,r){La(t,e,0,0,0,0,i,0,0,0,0,r,0,0,0,0,1)}function Da(t,e,i,r){La(t,1,0,0,e,0,1,0,i,0,0,1,r,0,0,0,1)}function Na(t,e){var i=Math.cos(e),r=Math.sin(e);La(t,i,0,r,0,0,1,0,0,-r,0,i,0,0,0,0,1)}function ka(){return new Float32Array([1,0,0,0,1,0,0,0,1])}function Ba(t,e){var i=ia([e[0],e[1],e[2]]),r=ia([e[4],e[5],e[6]]),n=ia([e[8],e[9],e[10]]),o=ia();ra(o,r,n),t[0]=o[0],t[1]=o[1],t[2]=o[2],ra(o,n,i),t[3]=o[0],t[4]=o[1],t[5]=o[2],ra(o,i,r),t[6]=o[0],t[7]=o[1],t[8]=o[2]}function Fa(t,e){function i(t,e,i,r){for(var n=r*r,a=Math.max(0,t-r-s>>o),d=Math.max(0,e-r-c>>o),f=Math.max(0,i-r-u>>o),y=Math.min(h,t+r-s>>o),x=Math.min(l,e+r-c>>o),_=Math.min(p,i+r-u>>o),w=[],S=a;S<=y;++S)for(var A=d;A<=x;++A)for(var P=f;P<=_;++P){var E=b[(S*l+A)*p+P];if(E>0)for(var I=E-1,L=T[I],R=L+M[I],O=L;O<R;++O){var D=C[O],N=m[D]-t,k=g[D]-e,B=v[D]-i;N*N+k*k+B*B<=n&&w.push(D)}}return w}var r,n,o=3,a=e,s=a.min.x,c=a.min.y,u=a.min.z,h=1+(a.max.x-s>>o),l=1+(a.max.y-c>>o),p=1+(a.max.z-u>>o),d=h*l*p,f=t.count,m=t.x,g=t.y,v=t.z,y=0,b=new Uint32Array(d),x=new Int32Array(f);for(r=0;r<f;++r){var _=m[r]-s>>o,w=g[r]-c>>o,S=v[r]-u>>o,A=(_*l+w)*p+S;1===(b[A]+=1)&&(y+=1),x[r]=A}var M=new Uint16Array(y);for(r=0,n=0;r<d;++r){var P=b[r];P>0&&(b[r]=n+1,M[n]=P,n+=1)}var T=new Uint32Array(y);for(r=1;r<y;++r)T[r]+=T[r-1]+M[r-1];var E=new Uint16Array(y),C=new Int32Array(f);for(r=0;r<f;++r){var I=b[x[r]];if(I>0){var L=I-1;C[T[L]+E[L]]=r,E[L]+=1}}this.within=i}function za(e){var i=0,r=0,n={},o={},a=URL.createObjectURL(hf.get(e)),s=new window.Worker(a);hf.activeWorkerCount+=1,s.onmessage=function(r){i-=1;var a=r.data.__postId;t.Debug&&cf.timeEnd("Worker.postMessage "+e+" #"+a),n[a]&&n[a].call(s,r),delete n[a],delete o[a]},s.onerror=function(t){if(i-=1,t.data){var r=t.data.__postId;o[r]?o[r].call(s,t):cf.error("Worker.onerror",r,e,t),delete n[r],delete o[r]}else cf.error("Worker.onerror",e,t)},this.name=e,this.post=function(a,c,u,h){n[r]=u,o[r]=h,(a=a||{}).__name=e,a.__postId=r,a.__debug=t.Debug,t.Debug&&cf.time("Worker.postMessage "+e+" #"+r);try{s.postMessage(a,c)}catch(t){cf.error("worker.post:",t),s.postMessage(a)}return i+=1,r+=1,this},this.terminate=function(){s?(s.terminate(),URL.revokeObjectURL(a),hf.activeWorkerCount-=1):cf.log("no worker to terminate")},Object.defineProperties(this,{postCount:{get:function(){return r}},pending:{get:function(){return i}}})}function Ua(t,e){e=Math.min(8,e||2);var i=[],r=0;this.name=t,this.maxCount=e,this.post=function(t,e,i,r){return this.getNextWorker().post(t,e,i,r),this},this.terminate=function(){i.forEach(function(t){t.terminate()})},this.getNextWorker=function(){for(var n,o=1/0,a=0;a<e;++a){if(a>=r){n=new za(t),i.push(n),r+=1;break}var s=i[a];if(0===s.pending){n=s;break}s.pending<o&&(o=s.pending,n=s)}return n},Object.defineProperties(this,{count:{get:function(){return r}}})}function ja(){return new Uint32Array([0,265,515,778,1030,1295,1541,1804,2060,2309,2575,2822,3082,3331,3593,3840,400,153,915,666,1430,1183,1941,1692,2460,2197,2975,2710,3482,3219,3993,3728,560,825,51,314,1590,1855,1077,1340,2620,2869,2111,2358,3642,3891,3129,3376,928,681,419,170,1958,1711,1445,1196,2988,2725,2479,2214,4010,3747,3497,3232,1120,1385,1635,1898,102,367,613,876,3180,3429,3695,3942,2154,2403,2665,2912,1520,1273,2035,1786,502,255,1013,764,3580,3317,4095,3830,2554,2291,3065,2800,1616,1881,1107,1370,598,863,85,348,3676,3925,3167,3414,2650,2899,2137,2384,1984,1737,1475,1226,966,719,453,204,4044,3781,3535,3270,3018,2755,2505,2240,2240,2505,2755,3018,3270,3535,3781,4044,204,453,719,966,1226,1475,1737,1984,2384,2137,2899,2650,3414,3167,3925,3676,348,85,863,598,1370,1107,1881,1616,2800,3065,2291,2554,3830,4095,3317,3580,764,1013,255,502,1786,2035,1273,1520,2912,2665,2403,2154,3942,3695,3429,3180,876,613,367,102,1898,1635,1385,1120,3232,3497,3747,4010,2214,2479,2725,2988,1196,1445,1711,1958,170,419,681,928,3376,3129,3891,3642,2358,2111,2869,2620,1340,1077,1855,1590,314,51,825,560,3728,3993,3219,3482,2710,2975,2197,2460,1692,1941,1183,1430,666,915,153,400,3840,3593,3331,3082,2822,2575,2309,2060,1804,1541,1295,1030,778,515,265,0])}function Ga(){return new Int32Array([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,8,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,8,3,9,8,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,2,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,8,3,1,2,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,2,10,0,2,9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,8,3,2,10,8,10,9,8,-1,-1,-1,-1,-1,-1,-1,3,11,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,11,2,8,11,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,9,0,2,3,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,11,2,1,9,11,9,8,11,-1,-1,-1,-1,-1,-1,-1,3,10,1,11,10,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,10,1,0,8,10,8,11,10,-1,-1,-1,-1,-1,-1,-1,3,9,0,3,11,9,11,10,9,-1,-1,-1,-1,-1,-1,-1,9,8,10,10,8,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,7,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,3,0,7,3,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,9,8,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,1,9,4,7,1,7,3,1,-1,-1,-1,-1,-1,-1,-1,1,2,10,8,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,4,7,3,0,4,1,2,10,-1,-1,-1,-1,-1,-1,-1,9,2,10,9,0,2,8,4,7,-1,-1,-1,-1,-1,-1,-1,2,10,9,2,9,7,2,7,3,7,9,4,-1,-1,-1,-1,8,4,7,3,11,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,4,7,11,2,4,2,0,4,-1,-1,-1,-1,-1,-1,-1,9,0,1,8,4,7,2,3,11,-1,-1,-1,-1,-1,-1,-1,4,7,11,9,4,11,9,11,2,9,2,1,-1,-1,-1,-1,3,10,1,3,11,10,7,8,4,-1,-1,-1,-1,-1,-1,-1,1,11,10,1,4,11,1,0,4,7,11,4,-1,-1,-1,-1,4,7,8,9,0,11,9,11,10,11,0,3,-1,-1,-1,-1,4,7,11,4,11,9,9,11,10,-1,-1,-1,-1,-1,-1,-1,9,5,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,5,4,0,8,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,5,4,1,5,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,5,4,8,3,5,3,1,5,-1,-1,-1,-1,-1,-1,-1,1,2,10,9,5,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,0,8,1,2,10,4,9,5,-1,-1,-1,-1,-1,-1,-1,5,2,10,5,4,2,4,0,2,-1,-1,-1,-1,-1,-1,-1,2,10,5,3,2,5,3,5,4,3,4,8,-1,-1,-1,-1,9,5,4,2,3,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,11,2,0,8,11,4,9,5,-1,-1,-1,-1,-1,-1,-1,0,5,4,0,1,5,2,3,11,-1,-1,-1,-1,-1,-1,-1,2,1,5,2,5,8,2,8,11,4,8,5,-1,-1,-1,-1,10,3,11,10,1,3,9,5,4,-1,-1,-1,-1,-1,-1,-1,4,9,5,0,8,1,8,10,1,8,11,10,-1,-1,-1,-1,5,4,0,5,0,11,5,11,10,11,0,3,-1,-1,-1,-1,5,4,8,5,8,10,10,8,11,-1,-1,-1,-1,-1,-1,-1,9,7,8,5,7,9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,3,0,9,5,3,5,7,3,-1,-1,-1,-1,-1,-1,-1,0,7,8,0,1,7,1,5,7,-1,-1,-1,-1,-1,-1,-1,1,5,3,3,5,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,7,8,9,5,7,10,1,2,-1,-1,-1,-1,-1,-1,-1,10,1,2,9,5,0,5,3,0,5,7,3,-1,-1,-1,-1,8,0,2,8,2,5,8,5,7,10,5,2,-1,-1,-1,-1,2,10,5,2,5,3,3,5,7,-1,-1,-1,-1,-1,-1,-1,7,9,5,7,8,9,3,11,2,-1,-1,-1,-1,-1,-1,-1,9,5,7,9,7,2,9,2,0,2,7,11,-1,-1,-1,-1,2,3,11,0,1,8,1,7,8,1,5,7,-1,-1,-1,-1,11,2,1,11,1,7,7,1,5,-1,-1,-1,-1,-1,-1,-1,9,5,8,8,5,7,10,1,3,10,3,11,-1,-1,-1,-1,5,7,0,5,0,9,7,11,0,1,0,10,11,10,0,-1,11,10,0,11,0,3,10,5,0,8,0,7,5,7,0,-1,11,10,5,7,11,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,6,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,8,3,5,10,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,0,1,5,10,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,8,3,1,9,8,5,10,6,-1,-1,-1,-1,-1,-1,-1,1,6,5,2,6,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,6,5,1,2,6,3,0,8,-1,-1,-1,-1,-1,-1,-1,9,6,5,9,0,6,0,2,6,-1,-1,-1,-1,-1,-1,-1,5,9,8,5,8,2,5,2,6,3,2,8,-1,-1,-1,-1,2,3,11,10,6,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,0,8,11,2,0,10,6,5,-1,-1,-1,-1,-1,-1,-1,0,1,9,2,3,11,5,10,6,-1,-1,-1,-1,-1,-1,-1,5,10,6,1,9,2,9,11,2,9,8,11,-1,-1,-1,-1,6,3,11,6,5,3,5,1,3,-1,-1,-1,-1,-1,-1,-1,0,8,11,0,11,5,0,5,1,5,11,6,-1,-1,-1,-1,3,11,6,0,3,6,0,6,5,0,5,9,-1,-1,-1,-1,6,5,9,6,9,11,11,9,8,-1,-1,-1,-1,-1,-1,-1,5,10,6,4,7,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,3,0,4,7,3,6,5,10,-1,-1,-1,-1,-1,-1,-1,1,9,0,5,10,6,8,4,7,-1,-1,-1,-1,-1,-1,-1,10,6,5,1,9,7,1,7,3,7,9,4,-1,-1,-1,-1,6,1,2,6,5,1,4,7,8,-1,-1,-1,-1,-1,-1,-1,1,2,5,5,2,6,3,0,4,3,4,7,-1,-1,-1,-1,8,4,7,9,0,5,0,6,5,0,2,6,-1,-1,-1,-1,7,3,9,7,9,4,3,2,9,5,9,6,2,6,9,-1,3,11,2,7,8,4,10,6,5,-1,-1,-1,-1,-1,-1,-1,5,10,6,4,7,2,4,2,0,2,7,11,-1,-1,-1,-1,0,1,9,4,7,8,2,3,11,5,10,6,-1,-1,-1,-1,9,2,1,9,11,2,9,4,11,7,11,4,5,10,6,-1,8,4,7,3,11,5,3,5,1,5,11,6,-1,-1,-1,-1,5,1,11,5,11,6,1,0,11,7,11,4,0,4,11,-1,0,5,9,0,6,5,0,3,6,11,6,3,8,4,7,-1,6,5,9,6,9,11,4,7,9,7,11,9,-1,-1,-1,-1,10,4,9,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,10,6,4,9,10,0,8,3,-1,-1,-1,-1,-1,-1,-1,10,0,1,10,6,0,6,4,0,-1,-1,-1,-1,-1,-1,-1,8,3,1,8,1,6,8,6,4,6,1,10,-1,-1,-1,-1,1,4,9,1,2,4,2,6,4,-1,-1,-1,-1,-1,-1,-1,3,0,8,1,2,9,2,4,9,2,6,4,-1,-1,-1,-1,0,2,4,4,2,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,3,2,8,2,4,4,2,6,-1,-1,-1,-1,-1,-1,-1,10,4,9,10,6,4,11,2,3,-1,-1,-1,-1,-1,-1,-1,0,8,2,2,8,11,4,9,10,4,10,6,-1,-1,-1,-1,3,11,2,0,1,6,0,6,4,6,1,10,-1,-1,-1,-1,6,4,1,6,1,10,4,8,1,2,1,11,8,11,1,-1,9,6,4,9,3,6,9,1,3,11,6,3,-1,-1,-1,-1,8,11,1,8,1,0,11,6,1,9,1,4,6,4,1,-1,3,11,6,3,6,0,0,6,4,-1,-1,-1,-1,-1,-1,-1,6,4,8,11,6,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,10,6,7,8,10,8,9,10,-1,-1,-1,-1,-1,-1,-1,0,7,3,0,10,7,0,9,10,6,7,10,-1,-1,-1,-1,10,6,7,1,10,7,1,7,8,1,8,0,-1,-1,-1,-1,10,6,7,10,7,1,1,7,3,-1,-1,-1,-1,-1,-1,-1,1,2,6,1,6,8,1,8,9,8,6,7,-1,-1,-1,-1,2,6,9,2,9,1,6,7,9,0,9,3,7,3,9,-1,7,8,0,7,0,6,6,0,2,-1,-1,-1,-1,-1,-1,-1,7,3,2,6,7,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,3,11,10,6,8,10,8,9,8,6,7,-1,-1,-1,-1,2,0,7,2,7,11,0,9,7,6,7,10,9,10,7,-1,1,8,0,1,7,8,1,10,7,6,7,10,2,3,11,-1,11,2,1,11,1,7,10,6,1,6,7,1,-1,-1,-1,-1,8,9,6,8,6,7,9,1,6,11,6,3,1,3,6,-1,0,9,1,11,6,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,8,0,7,0,6,3,11,0,11,6,0,-1,-1,-1,-1,7,11,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,6,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,0,8,11,7,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,9,11,7,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,1,9,8,3,1,11,7,6,-1,-1,-1,-1,-1,-1,-1,10,1,2,6,11,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,2,10,3,0,8,6,11,7,-1,-1,-1,-1,-1,-1,-1,2,9,0,2,10,9,6,11,7,-1,-1,-1,-1,-1,-1,-1,6,11,7,2,10,3,10,8,3,10,9,8,-1,-1,-1,-1,7,2,3,6,2,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,0,8,7,6,0,6,2,0,-1,-1,-1,-1,-1,-1,-1,2,7,6,2,3,7,0,1,9,-1,-1,-1,-1,-1,-1,-1,1,6,2,1,8,6,1,9,8,8,7,6,-1,-1,-1,-1,10,7,6,10,1,7,1,3,7,-1,-1,-1,-1,-1,-1,-1,10,7,6,1,7,10,1,8,7,1,0,8,-1,-1,-1,-1,0,3,7,0,7,10,0,10,9,6,10,7,-1,-1,-1,-1,7,6,10,7,10,8,8,10,9,-1,-1,-1,-1,-1,-1,-1,6,8,4,11,8,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,6,11,3,0,6,0,4,6,-1,-1,-1,-1,-1,-1,-1,8,6,11,8,4,6,9,0,1,-1,-1,-1,-1,-1,-1,-1,9,4,6,9,6,3,9,3,1,11,3,6,-1,-1,-1,-1,6,8,4,6,11,8,2,10,1,-1,-1,-1,-1,-1,-1,-1,1,2,10,3,0,11,0,6,11,0,4,6,-1,-1,-1,-1,4,11,8,4,6,11,0,2,9,2,10,9,-1,-1,-1,-1,10,9,3,10,3,2,9,4,3,11,3,6,4,6,3,-1,8,2,3,8,4,2,4,6,2,-1,-1,-1,-1,-1,-1,-1,0,4,2,4,6,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,9,0,2,3,4,2,4,6,4,3,8,-1,-1,-1,-1,1,9,4,1,4,2,2,4,6,-1,-1,-1,-1,-1,-1,-1,8,1,3,8,6,1,8,4,6,6,10,1,-1,-1,-1,-1,10,1,0,10,0,6,6,0,4,-1,-1,-1,-1,-1,-1,-1,4,6,3,4,3,8,6,10,3,0,3,9,10,9,3,-1,10,9,4,6,10,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,9,5,7,6,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,8,3,4,9,5,11,7,6,-1,-1,-1,-1,-1,-1,-1,5,0,1,5,4,0,7,6,11,-1,-1,-1,-1,-1,-1,-1,11,7,6,8,3,4,3,5,4,3,1,5,-1,-1,-1,-1,9,5,4,10,1,2,7,6,11,-1,-1,-1,-1,-1,-1,-1,6,11,7,1,2,10,0,8,3,4,9,5,-1,-1,-1,-1,7,6,11,5,4,10,4,2,10,4,0,2,-1,-1,-1,-1,3,4,8,3,5,4,3,2,5,10,5,2,11,7,6,-1,7,2,3,7,6,2,5,4,9,-1,-1,-1,-1,-1,-1,-1,9,5,4,0,8,6,0,6,2,6,8,7,-1,-1,-1,-1,3,6,2,3,7,6,1,5,0,5,4,0,-1,-1,-1,-1,6,2,8,6,8,7,2,1,8,4,8,5,1,5,8,-1,9,5,4,10,1,6,1,7,6,1,3,7,-1,-1,-1,-1,1,6,10,1,7,6,1,0,7,8,7,0,9,5,4,-1,4,0,10,4,10,5,0,3,10,6,10,7,3,7,10,-1,7,6,10,7,10,8,5,4,10,4,8,10,-1,-1,-1,-1,6,9,5,6,11,9,11,8,9,-1,-1,-1,-1,-1,-1,-1,3,6,11,0,6,3,0,5,6,0,9,5,-1,-1,-1,-1,0,11,8,0,5,11,0,1,5,5,6,11,-1,-1,-1,-1,6,11,3,6,3,5,5,3,1,-1,-1,-1,-1,-1,-1,-1,1,2,10,9,5,11,9,11,8,11,5,6,-1,-1,-1,-1,0,11,3,0,6,11,0,9,6,5,6,9,1,2,10,-1,11,8,5,11,5,6,8,0,5,10,5,2,0,2,5,-1,6,11,3,6,3,5,2,10,3,10,5,3,-1,-1,-1,-1,5,8,9,5,2,8,5,6,2,3,8,2,-1,-1,-1,-1,9,5,6,9,6,0,0,6,2,-1,-1,-1,-1,-1,-1,-1,1,5,8,1,8,0,5,6,8,3,8,2,6,2,8,-1,1,5,6,2,1,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,3,6,1,6,10,3,8,6,5,6,9,8,9,6,-1,10,1,0,10,0,6,9,5,0,5,6,0,-1,-1,-1,-1,0,3,8,5,6,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,5,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,5,10,7,5,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,5,10,11,7,5,8,3,0,-1,-1,-1,-1,-1,-1,-1,5,11,7,5,10,11,1,9,0,-1,-1,-1,-1,-1,-1,-1,10,7,5,10,11,7,9,8,1,8,3,1,-1,-1,-1,-1,11,1,2,11,7,1,7,5,1,-1,-1,-1,-1,-1,-1,-1,0,8,3,1,2,7,1,7,5,7,2,11,-1,-1,-1,-1,9,7,5,9,2,7,9,0,2,2,11,7,-1,-1,-1,-1,7,5,2,7,2,11,5,9,2,3,2,8,9,8,2,-1,2,5,10,2,3,5,3,7,5,-1,-1,-1,-1,-1,-1,-1,8,2,0,8,5,2,8,7,5,10,2,5,-1,-1,-1,-1,9,0,1,5,10,3,5,3,7,3,10,2,-1,-1,-1,-1,9,8,2,9,2,1,8,7,2,10,2,5,7,5,2,-1,1,3,5,3,7,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,8,7,0,7,1,1,7,5,-1,-1,-1,-1,-1,-1,-1,9,0,3,9,3,5,5,3,7,-1,-1,-1,-1,-1,-1,-1,9,8,7,5,9,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,5,8,4,5,10,8,10,11,8,-1,-1,-1,-1,-1,-1,-1,5,0,4,5,11,0,5,10,11,11,3,0,-1,-1,-1,-1,0,1,9,8,4,10,8,10,11,10,4,5,-1,-1,-1,-1,10,11,4,10,4,5,11,3,4,9,4,1,3,1,4,-1,2,5,1,2,8,5,2,11,8,4,5,8,-1,-1,-1,-1,0,4,11,0,11,3,4,5,11,2,11,1,5,1,11,-1,0,2,5,0,5,9,2,11,5,4,5,8,11,8,5,-1,9,4,5,2,11,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,5,10,3,5,2,3,4,5,3,8,4,-1,-1,-1,-1,5,10,2,5,2,4,4,2,0,-1,-1,-1,-1,-1,-1,-1,3,10,2,3,5,10,3,8,5,4,5,8,0,1,9,-1,5,10,2,5,2,4,1,9,2,9,4,2,-1,-1,-1,-1,8,4,5,8,5,3,3,5,1,-1,-1,-1,-1,-1,-1,-1,0,4,5,1,0,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,4,5,8,5,3,9,0,5,0,3,5,-1,-1,-1,-1,9,4,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,11,7,4,9,11,9,10,11,-1,-1,-1,-1,-1,-1,-1,0,8,3,4,9,7,9,11,7,9,10,11,-1,-1,-1,-1,1,10,11,1,11,4,1,4,0,7,4,11,-1,-1,-1,-1,3,1,4,3,4,8,1,10,4,7,4,11,10,11,4,-1,4,11,7,9,11,4,9,2,11,9,1,2,-1,-1,-1,-1,9,7,4,9,11,7,9,1,11,2,11,1,0,8,3,-1,11,7,4,11,4,2,2,4,0,-1,-1,-1,-1,-1,-1,-1,11,7,4,11,4,2,8,3,4,3,2,4,-1,-1,-1,-1,2,9,10,2,7,9,2,3,7,7,4,9,-1,-1,-1,-1,9,10,7,9,7,4,10,2,7,8,7,0,2,0,7,-1,3,7,10,3,10,2,7,4,10,1,10,0,4,0,10,-1,1,10,2,8,7,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,9,1,4,1,7,7,1,3,-1,-1,-1,-1,-1,-1,-1,4,9,1,4,1,7,0,8,1,8,7,1,-1,-1,-1,-1,4,0,3,7,4,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,8,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,10,8,10,11,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,0,9,3,9,11,11,9,10,-1,-1,-1,-1,-1,-1,-1,0,1,10,0,10,8,8,10,11,-1,-1,-1,-1,-1,-1,-1,3,1,10,11,3,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,2,11,1,11,9,9,11,8,-1,-1,-1,-1,-1,-1,-1,3,0,9,3,9,11,1,2,9,2,11,9,-1,-1,-1,-1,0,2,11,8,0,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,2,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,3,8,2,8,10,10,8,9,-1,-1,-1,-1,-1,-1,-1,9,10,2,0,9,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,3,8,2,8,10,0,1,8,1,10,8,-1,-1,-1,-1,1,10,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,3,8,9,1,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,9,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,3,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1])}function Va(){return[[0,4,4,4,2,0,0,0,2,2,0,0],[4,0,4,4,0,8,0,0,0,8,8,0],[4,4,0,4,0,0,8,0,0,0,8,8],[4,4,4,0,0,0,0,1,1,0,0,1],[2,0,0,0,0,8,8,8,2,2,0,0],[0,8,0,0,8,0,8,8,0,8,8,0],[0,0,8,0,8,8,0,8,0,0,8,8],[0,0,0,1,8,8,8,0,1,0,0,1],[2,0,0,1,2,0,0,1,0,2,0,1],[2,8,0,0,2,8,0,0,2,0,8,0],[0,8,8,0,0,8,8,0,0,8,0,8],[0,0,8,1,0,0,8,1,1,0,8,0]]}function $a(t,e,i,r,n){function o(t,e,i){return t+(e-t)*i}function a(t,n,o){return t=(t+v)%e,n=(n+y)%i,o=(o+b)%r,P*o+M*n+t}function s(t,e,i,r,a,s,c){var u=w?3*t:t;if(f[u]<0){var h=(x-s)/(c-s),l=d,p=3*m;if(E[p+0]=i+h,E[p+1]=r,E[p+2]=a,!_){var g=3*t;C[p]=-o(l[g],l[g+3],h),C[p+1]=-o(l[g+1],l[g+4],h),C[p+2]=-o(l[g+2],l[g+5],h)}n&&(L[m]=n[t+Math.round(h)]),f[u]=m,T[e]=m,m+=1}else T[e]=f[u]}function c(t,e,i,r,a,s,c){var u=w?3*t+1:t;if(f[u]<0){var h=(x-s)/(c-s),l=d,p=3*m;if(E[p]=i,E[p+1]=r+h,E[p+2]=a,!_){var g=3*t,v=g+3*M;C[p]=-o(l[g],l[v],h),C[p+1]=-o(l[g+1],l[v+1],h),C[p+2]=-o(l[g+2],l[v+2],h)}n&&(L[m]=n[t+Math.round(h)*M]),f[u]=m,T[e]=m,m+=1}else T[e]=f[u]}function u(t,e,i,r,a,s,c){var u=w?3*t+2:t;if(f[u]<0){var h=(x-s)/(c-s),l=d,p=3*m;if(E[p]=i,E[p+1]=r,E[p+2]=a+h,!_){var g=3*t,v=g+3*P;C[p]=-o(l[g],l[v],h),C[p+1]=-o(l[g+1],l[v+1],h),C[p+2]=-o(l[g+2],l[v+2],h)}n&&(L[m]=n[t+Math.round(h)*P]),f[u]=m,T[e]=m,m+=1}else T[e]=f[u]}function h(e){var i=3*e;0===d[i]&&(d[i]=t[(e-1+A)%A]-t[(e+1)%A],d[i+1]=t[(e-M+A)%A]-t[(e+M)%A],d[i+2]=t[(e-P+A)%A]-t[(e+P)%A])}function l(e,i,r,n,o){var l,p,d,f,m,v,y;S?(n=a(e,i,r),l=a(e+1,i,r),p=a(e,i+1,r),d=a(e,i,r+1),f=a(e+1,i+1,r),m=a(e+1,i,r+1),v=a(e,i+1,r+1),y=a(e+1,i+1,r+1)):(l=n+1,f=(p=n+M)+1,m=(d=n+P)+1,y=(v=p+P)+1);var b=0,A=t[n],E=t[l],C=t[p],L=t[f],N=t[d],k=t[m],B=t[v],F=t[y];A<x&&(b|=1),E<x&&(b|=2),C<x&&(b|=8),L<x&&(b|=4),N<x&&(b|=16),k<x&&(b|=32),B<x&&(b|=128),F<x&&(b|=64);var z=R[b];if(0===z)return 0;var U=e+1,j=i+1,G=r+1;1&z&&(_||(h(n),h(l)),s(n,0,e,i,r,A,E)),2&z&&(_||(h(l),h(f)),c(l,1,U,i,r,E,L)),4&z&&(_||(h(p),h(f)),s(p,2,e,j,r,C,L)),8&z&&(_||(h(n),h(p)),c(n,3,e,i,r,A,C)),16&z&&(_||(h(d),h(m)),s(d,4,e,i,G,N,k)),32&z&&(_||(h(m),h(y)),c(m,5,U,i,G,k,F)),64&z&&(_||(h(v),h(y)),s(v,6,e,j,G,B,F)),128&z&&(_||(h(d),h(v)),c(d,7,e,i,G,N,B)),256&z&&(_||(h(n),h(d)),u(n,8,e,i,r,A,N)),512&z&&(_||(h(l),h(m)),u(l,9,U,i,r,E,k)),1024&z&&(_||(h(f),h(y)),u(f,10,U,j,r,L,F)),2048&z&&(_||(h(p),h(v)),u(p,11,e,j,r,C,B));for(var V,$,H,W=b<<4,X=0;-1!=O[W+X];)V=O[W+X],$=O[W+X+1],H=O[W+X+2],w?(D[V][$]&o&&(I[g++]=T[V],I[g++]=T[$]),D[$][H]&o&&(I[g++]=T[$],I[g++]=T[H]),D[V][H]&o&&(I[g++]=T[V],I[g++]=T[H])):(I[g++]=T[$],I[g++]=T[V],I[g++]=T[H]),X+=3}function p(n,o,s,c,u,h){var p,d,m,g,v,y,b;n=void 0!==n?n:0,o=void 0!==o?o:0,s=void 0!==s?s:0,c=void 0!==c?c:e-1,u=void 0!==u?u:i-1,h=void 0!==h?h:r-1,S||(_?(n=Math.max(0,n),o=Math.max(0,o),s=Math.max(0,s),c=Math.min(e-1,c),u=Math.min(i-1,u),h=Math.min(r-1,h)):(n=Math.max(1,n),o=Math.max(1,o),s=Math.max(1,s),c=Math.min(e-2,c),u=Math.min(i-2,u),h=Math.min(r-2,h)));var A,T,E,C,I,L;if(S)for(A=n-2,T=o-2,C=c+2,I=u+2,L=h+2,v=E=s-2;v<L;++v)for(g=T;g<I;++g)for(m=A;m<C;++m)w?(d=3*a(m,g,v),f[d]=-1,f[d+1]=-1,f[d+2]=-1):(p=a(m,g,v),f[p]=-1);else for(A=Math.max(0,n-2),T=Math.max(0,o-2),E=Math.max(0,s-2),C=Math.min(e,c+2),I=Math.min(i,u+2),L=Math.min(r,h+2),v=E;v<L;++v)for(b=P*v,g=T;g<I;++g)for(y=b+M*g,m=A;m<C;++m)w?(f[p=3*(y+m)]=-1,f[p+1]=-1,f[p+2]=-1):f[p=y+m]=-1;if(!S){var R,O=n,D=o,N=s,k=c,B=u,F=h;for(R=!1,v=s;v<h;++v){for(g=o;g<u;++g){for(m=n;m<c;++m)if(p=e*i*v+e*g+m,t[p]>=x){N=v,R=!0;break}if(R)break}if(R)break}for(R=!1,g=o;g<u;++g){for(v=N;v<h;++v){for(m=n;m<c;++m)if(p=e*i*v+e*g+m,t[p]>=x){D=g,R=!0;break}if(R)break}if(R)break}for(R=!1,m=n;m<c;++m){for(g=D;g<u;++g){for(v=N;v<h;++v)if(p=e*i*v+e*g+m,t[p]>=x){O=m,R=!0;break}if(R)break}if(R)break}for(R=!1,v=h;v>=s;--v){for(g=u;g>=o;--g){for(m=c;m>=n;--m)if(p=e*i*v+e*g+m,t[p]>=x){F=v,R=!0;break}if(R)break}if(R)break}for(R=!1,g=u;g>=o;--g){for(v=F;v>=s;--v){for(m=c;m>=n;--m)if(p=e*i*v+e*g+m,t[p]>=x){B=g,R=!0;break}if(R)break}if(R)break}for(R=!1,m=c;m>=n;--m){for(g=B;g>=o;--g){for(v=F;v>=s;--v)if(p=e*i*v+e*g+m,t[p]>=x){k=m,R=!0;break}if(R)break}if(R)break}_?(n=Math.max(0,O-1),o=Math.max(0,D-1),s=Math.max(0,N-1),c=Math.min(e-1,k+1),u=Math.min(i-1,B+1),h=Math.min(r-1,F+1)):(n=Math.max(1,O-1),o=Math.max(1,D-1),s=Math.max(1,N-1),c=Math.min(e-2,k+1),u=Math.min(i-2,B+1),h=Math.min(r-2,F+1))}var z=15;for(v=s;v<h;++v,z&=-5)for(b=P*v,z|=2,g=o;g<u;++g,z&=-3)for(y=b+M*g,z|=1,m=n;m<c;++m,z&=-2)l(m,g,v,p=y+m,z)}var d,f,m,g,v,y,b,x=0,_=!1,w=!1,S=!1,A=e*i*r,M=e,P=e*i,T=new Int32Array(12),E=[],C=[],I=[],L=[],R=ja(),O=Ga(),D=Va();this.triangulate=function(t,o,a,s,c){x=t,w=s,S=c,(_=o||w)||d||(d=new Float32Array(3*A));var u=w?3*A:A;if(f&&f.length===u||(f=new Int32Array(u)),m=0,g=0,void 0!==a){var h=a[0].map(Math.round),l=a[1].map(Math.round);v=e*Math.ceil(Math.abs(h[0])/e),y=i*Math.ceil(Math.abs(h[1])/i),b=r*Math.ceil(Math.abs(h[2])/r),p(h[0],h[1],h[2],l[0],l[1],l[2])}else v=y=b=0,p();return E.length=3*m,_||(C.length=3*m),I.length=g,n&&(L.length=m),{position:new Float32Array(E),normal:_?void 0:new Float32Array(C),index:Cn(I,E.length/3),atomindex:n?new Int32Array(L):void 0,contour:w}}}function Ha(t,e,i,r){i=i||1,r=r||!0;var n,o=t.length/3,a=e.length/3;r&&(n=new Float32Array(3*o));var s,c=new Float32Array(3*o),u=new Array(20);for(s=0;s<20;++s)u[s]=new Uint32Array(o);for(s=0;s<o;++s)u[0][s]=0;var h,l,p;for(s=0;s<a;++s){var d=3*s,f=3*s+1,m=3*s+2;for(p=!0,h=0,l=u[0][e[d]];h<l;++h)if(e[f]==u[h+1][e[d]]){p=!1;break}for(p&&(u[++u[0][e[d]]][e[d]]=e[f]),p=!0,h=0,l=u[0][e[d]];h<l;++h)if(e[m]==u[h+1][e[d]]){p=!1;break}for(p&&(u[++u[0][e[d]]][e[d]]=e[m]),p=!0,h=0,l=u[0][e[f]];h<l;++h)if(e[d]==u[h+1][e[f]]){p=!1;break}for(p&&(u[++u[0][e[f]]][e[f]]=e[d]),p=!0,h=0,l=u[0][e[f]];h<l;++h)if(e[m]==u[h+1][e[f]]){p=!1;break}for(p&&(u[++u[0][e[f]]][e[f]]=e[m]),p=!0,h=0;h<u[0][e[m]];++h)if(e[d]==u[h+1][e[m]]){p=!1;break}for(p&&(u[++u[0][e[m]]][e[m]]=e[d]),p=!0,h=0,l=u[0][e[m]];h<l;++h)if(e[f]==u[h+1][e[m]]){p=!1;break}p&&(u[++u[0][e[m]]][e[m]]=e[f])}for(var g,v,y,b,x,_=0;_<i;++_){for(s=0;s<o;++s)if(g=3*s,(y=u[0][s])<3)c[g]=t[g],c[g+1]=t[g+1],c[g+2]=t[g+2];else if(3===y||4===y){for(c[g]=0,c[g+1]=0,c[g+2]=0,h=0;h<y;++h)v=3*u[h+1][s],c[g]+=t[v],c[g+1]+=t[v+1],c[g+2]+=t[v+2];c[g]+=.5*t[g],c[g+1]+=.5*t[g+1],c[g+2]+=.5*t[g+2],x=.5+y,c[g]/=x,c[g+1]/=x,c[g+2]/=x}else{for(c[g]=0,c[g+1]=0,c[g+2]=0,h=0;h<y;++h)v=3*u[h+1][s],c[g]+=t[v],c[g+1]+=t[v+1],c[g+2]+=t[v+2];c[g]+=1*t[g],c[g+1]+=1*t[g+1],c[g+2]+=1*t[g+2],b=1+y,c[g]/=b,c[g+1]/=b,c[g+2]/=b}if(t.set(c),r){Wa(t,e,n);var w=3*o;for(g=0;g<w;g+=3)t[g]+=.75/4.5*-1*n[g],t[g+1]+=.75/4.5*-1*n[g+1],t[g+2]+=.75/4.5*-1*n[g+2]}}}function Wa(t,e,i){var r,n;if(void 0===i)i=new Float32Array(t.length);else for(r=0,n=i.length;r<n;r++)i[r]=0;var o=new Float32Array(3),a=new Float32Array(3),s=new Float32Array(3),c=new Float32Array(3),u=new Float32Array(3);if(e)for(r=0,n=e.length;r<n;r+=3){var h=3*e[r],l=3*e[r+1],p=3*e[r+2];oa(o,t,h),oa(a,t,l),oa(s,t,p),na(c,s,a),na(u,o,a),ra(c,c,u),i[h]+=c[0],i[h+1]+=c[1],i[h+2]+=c[2],i[l]+=c[0],i[l+1]+=c[1],i[l+2]+=c[2],i[p]+=c[0],i[p+1]+=c[1],i[p+2]+=c[2]}else for(r=0,n=t.length;r<n;r+=9)oa(o,t,r),oa(a,t,r+3),oa(s,t,r+6),na(c,s,a),na(u,o,a),ra(c,c,u),i[r]=c[0],i[r+1]=c[1],i[r+2]=c[2],i[r+3]=c[0],i[r+4]=c[1],i[r+5]=c[2],i[r+6]=c[0],i[r+7]=c[1],i[r+8]=c[2];return ea(i),i}function Xa(t){for(var e={},i=0,r=t.length;i<r;++i)e[t[i]]=!0;return e}function qa(t,e,i,r,n){var o=1/r*3;ha(t,t,n+(o+=i)),la(e,e,n+o),ca(t,t,r),pa(t,t),sa(t,t,r),ca(e,e,r),da(e,e),sa(e,e,r);var a=new Float32Array(3);na(a,e,t),ca(a,a,r),da(a,a),la(a,a,1);var s=256*Math.pow(10,6),c=a[0]*a[1]*a[2]*3;s<=c&&(ca(t,t,r*=Math.pow(s/c,1/3)),pa(t,t),sa(t,t,r),ca(e,e,r),da(e,e),sa(e,e,r),na(a,e,t),ca(a,a,r),da(a,a),la(a,a,1));var u=new Float32Array(t);fa(u,u);var h=Ia(),l=Ia();Na(l,Gn(90)),Ra(h,h,l);var p=Ia();Oa(p,-1/r,1/r,1/r),Ra(h,h,p);var d=Ia();return Da(d,-r*u[2],-r*u[1],-r*u[0]),Ra(h,h,d),{dim:a,tran:u,matrix:h,scaleFactor:r}}function Ya(t,e,i,r,n){function o(t,e,i,r,n,o){var s=a.triangulate(t,e,i,n,o);if(e&&!n&&(Ha(s.position,s.index,e,!0),s.normal=Wa(s.position,s.index)),r&&(Jo(r,s.position),s.normal)){var c=ka();Ba(c,r),ta(c,s.normal)}return s}var a=new $a(t,e,i,r,n);this.getSurface=o}function Za(t){this.polymer=t,this.size=t.residueCount}function Ka(t){this.polymer=t,this.helixorient=new Za(t),this.position=this.helixorient.getPosition()}function Qa(t){this.content=[],this.scoreFunction=t}function Ja(t,e){function i(e,r,n,o){e>s&&(s=e);var a=o-n;if(0===a)return-1;var u=4*l;if(l+=1,1===a)return h[u]=n,h[u+1]=-1,h[u+2]=-1,h[u+3]=r,u;var d=n+Math.floor(a/2);p=e%3;for(var f,m,g,v,y,b=n,x=o-1;x>b;){for(v=t[3*c[g=b+x>>1]+p],m=c[g],c[g]=c[x],c[x]=m,y=b,f=b;f<x;++f)t[3*c[f]+p]<v&&(m=c[y],c[y]=c[f],c[f]=m,++y);if(m=c[x],c[x]=c[y],c[y]=m,g=y,d===g)break;d<g?x=g-1:b=g+1}return h[u]=d,h[u+1]=i(e+1,u,n,d),h[u+2]=i(e+1,u,d+1,o),h[u+3]=r,u}function r(t){var e=h[t+3];return-1===e?0:r(e)+1}function n(i,n,o){function a(u){function l(t,e){s.push([t,e]),s.size()>n&&s.pop()}var p,d,f=r(u)%3,m=3*c[h[u]],g=[t[m+0],t[m+1],t[m+2]],v=e(i,g),y=h[u+1],b=h[u+2];if(-1===b&&-1===y)return void((s.size()<n||v<s.peek()[1])&&v<=o&&l(u,v));a(p=-1===b?y:-1===y?b:i[f]<=t[m+f]?y:b),(s.size()<n||v<s.peek()[1])&&v<=o&&l(u,v);for(var x=[],_=0;_<3;_+=1)x[_]=_===f?i[_]:t[m+_];var w=e(x,g);(s.size()<n||Math.abs(w)<s.peek()[1])&&Math.abs(w)<=o&&-1!==(d=p===y?b:y)&&a(d)}var s=new Qa(function(t){return-t[1]});a(d);for(var u=[],l=0,p=Math.min(s.size(),n);l<p;l+=1)u.push(s.content[l]);return u}function o(e,i){var r=1;if(void 0===e&&(e=d,i=0),-1===e)throw"node is null";var n=i%3,a=h[e+1],s=h[e+2];if(-1!==a){if(t[3*c[h[a]]+n]>t[3*c[h[e]]+n])throw"left child is > parent!";r+=o(a,i+1)}if(-1!==s){if(t[3*c[h[s]]+n]<t[3*c[h[e]]+n])throw"right child is < parent!";r+=o(s,i+1)}return r}for(var a=t.length/3,s=0,c=new Uint32Array(a),u=0;u<a;++u)c[u]=u;var h=new Int32Array(4*a),l=0,p=0,d=i(0,-1,0,a);this.rootIndex=d,this.maxDepth=s,this.nearest=n,this.indices=c,this.nodes=h,this.verify=o}function ts(e,i){t.Debug&&cf.time("Kdtree build");var r;r=i?function(t,e){var i=t[0]-e[0],r=t[1]-e[1],n=t[2]-e[2];return i*i+r*r+n*n}:function(t,e){var i=t[0]-e[0],r=t[1]-e[1],n=t[2]-e[2];return Math.sqrt(i*i+r*r+n*n)};var n=new Float32Array(3*e.atomCount),o=new Uint32Array(e.atomCount),a=0;e.eachAtom(function(t){n[a+0]=t.x,n[a+1]=t.y,n[a+2]=t.z,o[a/3]=t.index,a+=3}),this.atomIndices=o,this.points=n,this.kdtree=new Ja(n,r),t.Debug&&cf.timeEnd("Kdtree build")}function es(t){var e=ev[t],i={};if(void 0===e)return console.warn("getSymmetryOperations: spacegroup '"+t+"' not found in symop library"),i;for(var r=[],n=0,o=e.length;n<o;n+=3){for(var a=[],s=0;s<3;++s)a.push(tv[e[n+s]]);r.push(a)}var c=/^[1-9]$/;return r.forEach(function(t){var e=0,r=(new v).set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),n=r.elements;i[t]=r,t.forEach(function(t){for(var i=!1,r=!1,o=0,a=t.length;o<a;++o){var s=t[o];if("-"===s)i=!0;else if("+"===s)i=!1;else if("/"===s)r=!0;else if("X"===s)n[0+e]=i?-1:1;else if("Y"===s)n[4+e]=i?-1:1;else if("Z"===s)n[8+e]=i?-1:1;else if(c.test(s)){var u=parseInt(s);r?n[12+e]/=u:n[12+e]=u}else cf.warn("getSymmetryOperations: unknown token '"+s+"'")}e+=1})}),i}function is(t){var e="";return t.length>0&&(e=":"+Mn(t).join(" OR :")),new Kd(e)}function rs(e,i){if(i){t.Debug&&cf.time("assignSecondaryStructure");var r=[];e.eachModel(function(t){t.eachChain(function(t){r.push(t.chainname)})});var n=r.slice().sort(),o=[];n.forEach(function(t){o.push(r.indexOf(t))});var a=i.helices;(a=a.filter(function(t){return _n(n,t[0])>=0})).sort(function(t,e){var i=t[0],r=e[0],a=t[1],s=e[1];if(i===r)return a===s?0:a<s?-1:1;var c=_n(n,i),u=_n(n,r);return o[c]<o[u]?-1:1});var s=e.residueStore;e.eachModel(function(t){var e=0,i=a.length;if(0!==i){var r=a[e],n=!1,o=!1;t.eachChain(function(t){var c=!1;if(t.chainname===r[0])for(var u=t.residueCount,h=t.residueOffset,l=h+u,p=h;p<l;++p)if(s.resno[p]===r[1]&&s.getInscode(p)===r[2]&&(n=!0),n&&(s.sstruc[p]=r[6],s.resno[p]===r[4]&&s.getInscode(p)===r[5]&&(n=!1,(e+=1)<i?(p=h-1,r=a[e],c=t.chainname!==r[0]):o=!0)),c||o)return})}});var c=i.sheets;(c=c.filter(function(t){return _n(n,t[0])>=0})).sort(function(t,e){var i=t[0],r=e[0];if(i===r)return 0;var a=_n(n,i),s=_n(n,r);return o[a]<o[s]?-1:1});var u="e".charCodeAt(0);e.eachModel(function(t){var e=0,i=c.length;if(0!==i){var r=c[e],n=!1,o=!1;t.eachChain(function(t){var a=!1;if(t.chainname===r[0])for(var h=t.residueCount,l=t.residueOffset,p=l+h,d=l;d<p;++d)if(s.resno[d]===r[1]&&s.getInscode(d)===r[2]&&(n=!0),n&&(s.sstruc[d]=u,s.resno[d]===r[4]&&s.getInscode(d)===r[5]&&(n=!1,(e+=1)<i?(d=l-1,r=c[e],a=t.chainname!==r[0]):o=!0)),a||o)return})}}),t.Debug&&cf.timeEnd("assignSecondaryStructure")}}function ns(e){t.Debug&&cf.time("calculateChainnames");var i=!0;if(e.eachChain(function(t){t.chainname&&(i=!1)}),i){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZ",n=r.length,o=e.modelStore,a=e.chainStore,s=e.residueStore,c=function(t,e,i,r){for(var n=a.count,c=0;c<r;++c)s.chainIndex[i+c]=n;a.growIfFull(),a.modelIndex[n]=t,a.setChainname(n,e),a.setChainid(n,e),a.residueOffset[n]=i,a.residueCount[n]=r,a.count+=1,o.chainCount[t]+=1},u=function(t){for(var e=t,i=0,o=r[e%n];e>=n;)e=Math.floor(e/n),o+=r[e%n],i+=1;return i>=5&&cf.warn("chainname overflow"),o},h=e.getAtomProxy(),l=e.getAtomProxy(),p=0,d=0,f=0,m=0,g=[];1===s.count?g.push({mIndex:0,chainname:"A",rStart:0,rCount:1}):e.eachResidueN(2,function(t,e){var i=!1,r=t.backboneType,n=e.backboneType,o=lg;m=t.index,t.modelIndex!==e.modelIndex?i=!0:t.moleculeType!==e.moleculeType?i=!0:r!==o&&r===n&&(h.index=t.backboneEndAtomIndex,l.index=e.backboneStartAtomIndex,h.connectedTo(l)||(i=!0)),i||e.index!==s.count-1||(i=!0,m=e.index),i&&(g.push({mIndex:d,chainname:u(p),rStart:f,rCount:m-f+1}),p+=1,t.modelIndex!==e.modelIndex&&(p=0,d+=1),e.index===s.count-1&&m!==e.index&&g.push({mIndex:d,chainname:u(p),rStart:s.count-1,rCount:1}),f=e.index,m=e.index)}),a.count=0,g.forEach(function(t){c(t.mIndex,t.chainname,t.rStart,t.rCount)});var v=0;e.eachModel(function(t){o.chainOffset[t.index]=v,o.chainCount[t.index]-=1,v+=o.chainCount[t.index]})}t.Debug&&cf.timeEnd("calculateChainnames")}function os(e){t.Debug&&cf.time("calculateBonds"),cs(e),us(e),t.Debug&&cf.timeEnd("calculateBonds")}function as(e){var i=e.structure,r=i.getAtomProxy(),n=i.getAtomProxy(),o=e.atomCount,a=e.atomOffset,s=a+o-1;if(o>500)return void(t.Debug&&cf.warn("more than 500 atoms, skip residue for auto-bonding",e.qualifiedName()));var c,u,h=[],l=[],p=[];if(o>50){var d=new ts(e,!0),f=e.isCg()?1.2:2.3;for(c=a;c<s;++c){r.index=c;var m=r.covalent+f+.3,g=d.nearest(r,1/0,m*m),v=g.length;for(u=0;u<v;++u)n.index=g[u].index,r.index<n.index&&r.connectedTo(n)&&(h.push(r.index-a),l.push(n.index-a),p.push(1))}}else for(c=a;c<s;++c)for(r.index=c,u=c+1;u<=s;++u)n.index=u,r.connectedTo(n)&&(h.push(c-a),l.push(u-a),p.push(1));return{atomIndices1:h,atomIndices2:l,bondOrders:p}}function ss(e){t.Debug&&cf.time("calculateAtomBondMap");var i=[];return e.eachBond(function(t){var e=t.atomIndex1,r=t.atomIndex2;void 0===i[e]&&(i[e]=[]),i[e][r]=t.index}),t.Debug&&cf.timeEnd("calculateAtomBondMap"),i}function cs(e,i){t.Debug&&cf.time("calculateBondsWithin");var r=e.bondStore,n=e.rungBondStore,o=e.getAtomSet(!1),a=e.getAtomProxy(),s=e.getAtomProxy(),c=e.getBondProxy(),u=i?null:ss(e);e.eachResidue(function(t){if(!i){var e=t.atomCount,h=t.atomOffset;if(e>500)return void cf.warn("more than 500 atoms, skip residue for auto-bonding",t.qualifiedName());for(var l=t.getBonds(),p=l.atomIndices1,d=l.atomIndices2,f=l.bondOrders,m=p.length,g=0;g<m;++g){var v=p[g]+h,y=d[g]+h,b=u[v];void 0!==b&&void 0!==(b=b[y])?(c.index=b,f[t.residueType.getBondIndex(v,y)]=c.bondOrder):(a.index=v,s.index=y,r.addBond(a,s,f[g]))}}var x=t.residueType.traceAtomIndex,_=t.residueType.rungEndAtomIndex;-1!==x&&-1!==_&&(a.index=t.traceAtomIndex,s.index=t.rungEndAtomIndex,n.addBond(a,s),o.set(a.index),o.set(s.index))}),e.atomSetDict.rung=o,t.Debug&&cf.timeEnd("calculateBondsWithin")}function us(e,i){function r(t,e){var r=t.backboneType,u=e.backboneType;r!==lg&&r===u&&(s.index=t.backboneEndAtomIndex,c.index=e.backboneStartAtomIndex,s.connectedTo(c)&&(i||n.addBond(s,c,1),s.index=t.traceAtomIndex,c.index=e.traceAtomIndex,o.addBond(s,c),a.set(s.index),a.set(c.index)))}t.Debug&&cf.time("calculateBondsBetween");var n=e.bondStore,o=e.backboneBondStore,a=e.getAtomSet(!1),s=e.getAtomProxy(),c=e.getAtomProxy();0===o.count&&o.resize(e.residueStore.count),e.eachResidueN(2,r);var u=e.getResidueProxy(),h=e.getResidueProxy();e.eachChain(function(t){0!==t.residueCount&&(u.index=t.residueOffset,h.index=t.residueOffset+t.residueCount-1,r(h,u))}),e.atomSetDict.backbone=a,t.Debug&&cf.timeEnd("calculateBondsBetween")}function hs(e){function i(t){var e=[];return Object.keys(o).forEach(function(i){var u=o[i].clone();s.copy(n).applyMatrix4(u),c.setFromMatrixPosition(u),c.sub(a),s.x>1&&(c.x-=1),s.x<0&&(c.x+=1),s.y>1&&(c.y-=1),s.y<0&&(c.y+=1),s.z>1&&(c.z-=1),s.z<0&&(c.z+=1),t&&c.add(t),u.setPosition(c),u.multiplyMatrices(r.fracToCart,u),u.multiply(r.cartToFrac),e.push(u)}),e}if(e.unitcell){t.Debug&&cf.time("buildUnitcellAssembly");var r=e.unitcell,n=e.center.clone().applyMatrix4(r.cartToFrac),o=es(r.spacegroup),a=new g,s=new g,c=new g;n.x>1&&(a.x-=1),n.x<0&&(a.x+=1),n.y>1&&(a.y-=1),n.y<0&&(a.y+=1),n.z>1&&(a.z-=1),n.z<0&&(a.z+=1);var u,h=new iv("UNITCELL"),l=i();if(e.biomolDict.NCS){u=[new v].concat(e.biomolDict.NCS.partList[0].matrixList);var p=[];l.forEach(function(t){u.forEach(function(e){p.push(t.clone().multiply(e))})}),h.addPart(p)}else h.addPart(l);var d=new g,f=new iv("SUPERCELL"),m=Array.prototype.concat.call(i(d.set(1,0,0)),i(d.set(0,1,0)),i(d.set(0,0,1)),i(d.set(-1,0,0)),i(d.set(0,-1,0)),i(d.set(0,0,-1)),i(d.set(1,1,0)),i(d.set(1,0,1)),i(d.set(0,1,1)),i(d.set(-1,-1,0)),i(d.set(-1,0,-1)),i(d.set(0,-1,-1)),i(d.set(1,-1,-1)),i(d.set(1,1,-1)),i(d.set(1,-1,1)),i(d.set(-1,1,1)),i(d.set(-1,-1,1)),i(d.set(-1,1,-1)),i(d.set(0,1,-1)),i(d.set(0,-1,1)),i(d.set(1,0,-1)),i(d.set(-1,0,1)),i(d.set(1,-1,0)),i(d.set(-1,1,0)),i(),i(d.set(1,1,1)),i(d.set(-1,-1,-1)));if(e.biomolDict.NCS){var y=[];m.forEach(function(t){u.forEach(function(e){y.push(t.clone().multiply(e))})}),f.addPart(y)}else f.addPart(m);e.biomolDict.UNITCELL=h,e.biomolDict.SUPERCELL=f,t.Debug&&cf.timeEnd("buildUnitcellAssembly")}}function ls(t){var e=t.trim().toUpperCase();parseInt(e.charAt(0))&&(e=e.substr(1)),parseInt(e.charAt(0))&&(e=e.substr(1));var i=e.length;if(0===i)return"";if(1===i)return e;if(2===i){if(-1!==cv.indexOf(e))return e;if(-1!==sv.indexOf(e[0]))return e[0]}return i>=3&&-1!==sv.indexOf(e[0])?e[0]:""}function ps(t){var e=t.bondHash,i=e.countArray,r=e.offsetArray,n=e.indexArray,o=t.getBondProxy();t.eachResidue(function(t){var e=t.residueType;if(void 0===e.bonds){var a=t.atomOffset,s=[],c=[],u=[],h={};t.eachAtom(function(t){for(var e=t.index,l=r[e],p=0,d=i[e];p<d;++p){o.index=n[l+p];var f=o.atomIndex1,m=o.atomIndex2;if(f>m){var g=m;m=f,f=g}var v=f+"|"+m;void 0===h[v]&&(h[v]=!0,s.push(f-a),c.push(m-a),u.push(o.bondOrder))}}),e.bonds={atomIndices1:s,atomIndices2:c,bondOrders:u}}})}function ds(t,e){return t+"|"+e}function fs(t,e,i,r){return t+"|"+e.join(",")+"|"+(i?1:0)+"|"+(r||"")}function ms(t,e){function i(e){t(e,r)}function r(){var t=n.shift();void 0!==t?(o=!0,setTimeout(function(){i(t)})):o=!1}var n=[],o=!1;if(e){for(var a=0,s=e.length;a<s;++a)n.push(e[a]);r()}this.push=function(t){n.push(t),o||r()},this.kill=function(){n.length=0},this.length=function(){return n.length}}function gs(t,e,i){if(0!==i[0]&&0!==i[8]&&0!==i[4]){var r,n=t.length,o=i[0],a=i[1],s=i[2],c=-e[0]+o+o/2,u=-e[1]+a+a/2,h=-e[2]+s+s/2;for(r=0;r<n;r+=3)t[r+0]=(t[r+0]+c)%o,t[r+1]=(t[r+1]+u)%a,t[r+2]=(t[r+2]+h)%s}}function vs(t,e){if(0!==e[0]&&0!==e[8]&&0!==e[4]){var i,r,n,o,a=t.length;for(i=3;i<a;i+=3)for(r=0;r<3;++r)if(o=t[i+r]-t[i-3+r],Math.abs(o)>.9*e[3*r+r])if(o>0)for(n=0;n<3;++n)t[i+n]-=e[3*r+n];else for(n=0;n<3;++n)t[i+n]+=e[3*r+n];return t}}function ys(t){return"front"===t?Au:"back"===t?Mu:Pu}function bs(t,e){t.matrix.copy(e),t.matrix.decompose(t.position,t.quaternion,t.scale),t.matrixWorldNeedsUpdate=!0}function xs(t){var e=JSON.stringify(t);return void 0===my[e]&&(my[e]=new gy(t)),my[e]}function _s(t,e){void 0!==t.toArray?t=t.toArray():void 0!==t.x?t=[t.x,t.y,t.z]:void 0!==t.r&&(t=[t.r,t.g,t.b]),e.push.apply(e,t)}function ws(t){t.visible=!0}function Ss(t){t.visible=!1}function As(t,e,i,r){var n=i-t,o=r-e;return Math.sqrt(n*n+o*o)}function Ms(t){for(var e=t||{},i=dn(e.width,256),r=dn(e.height,256),n=[i/2,r/2],o=Math.min(i/2,r/2),a=dn(e.delta,1/(o+1))*o,s=0,c=0,u=new Uint8Array(i*r*4),h=0,l=u.length;h<l;h+=4){var p=1-Qn(o-a,o,As(s,c,n[0],n[1]));u[h]=255*p,u[h+1]=255*p,u[h+2]=255*p,u[h+3]=255*p,++s===i&&(s=0,c++)}var d=new y(u,i,r);return d.needsUpdate=!0,d}function Ps(t){cf.error("makeRepresentation: representation type "+t+" unknown")}function Ts(e,i,r,n){t.Debug&&cf.time("makeRepresentation "+e);var o;if(i instanceof Mv){if(!(o=df.get(e)))return void Ps(e)}else if(i instanceof jg)if("surface"===e)o=Ey;else{if("dot"!==e)return void Ps(e);o=Iy}else if(i instanceof Vg)if("surface"===e)o=Ey;else if("dot"===e)o=Iy;else{if("slice"!==e)return void Ps(e);o=Ny}else if(i instanceof Cv)o=Fy;else if(i instanceof xy)o=Sy,i=i.getBufferList();else{if("buffer"!==e)return void cf.error("makeRepresentation: object "+i+" unknown");o=Sy}var a=new o(i,r,n);return t.Debug&&cf.timeEnd("makeRepresentation "+e),a}function Es(t,e){return t instanceof RegExp?null!==e.name.match(t):e.name===t}function Cs(t,e){var i,r=0,n={};return e.forEach(function(e){i=0;var o={};e.forEach(function(e){o[t[i++]]=e}),n[t[r++]]=o}),n}function Is(t,e,i,r,n){i=dn(i,!1),r=dn(r,""),n=dn(n,"");var o,a,s,c,u;if(i){var h=t,l=e;r&&n&&(h=t.getView(new Kd(r)),l=e.getView(new Kd(n)));var p=h.getSequence(),d=l.getSequence(),f=new Jy(p.join(""),d.join(""));f.calc(),f.trace();var m,g,v,y,b;o=0,a=0,s=f.ali1.length;var x=[],_=[];for(m=0;m<s;++m)y=f.ali1[m],b=f.ali2[m],g=0,v=0,"-"===y?_[a]=!1:(_[a]=!0,g=1),"-"===b?x[o]=!1:(x[o]=!0,v=1),o+=g,a+=v;var w=[],S=[],A=h.getAtomProxy(),M=l.getAtomProxy();o=0,h.eachResidue(function(t){void 0!==t.traceAtomIndex&&t.traceAtomIndex===t.getAtomIndexByName("CA")&&(x[o]&&(A.index=t.getAtomIndexByName("CA"),w.push(A.x,A.y,A.z)),o+=1)}),o=0,l.eachResidue(function(t){void 0!==t.traceAtomIndex&&t.traceAtomIndex===t.getAtomIndexByName("CA")&&(_[o]&&(M.index=t.getAtomIndexByName("CA"),S.push(M.x,M.y,M.z)),o+=1)}),c=new Float32Array(w),u=new Float32Array(S)}else c=t.getView(new Kd(r+" and .CA")),u=e.getView(new Kd(n+" and .CA"));new Tv(c,u).transform(t),t.refreshPosition()}function Ls(t,e){var i=!1,r=!1,n=!1;return(e=e||new g).set(2*t.x,2*t.y,2*t.z),t.eachBondedAtom(function(t){if(!i)return"H"===t.atomname?(e.set(t),void(i=!0)):void(r||"CA"!==t.atomname?n||"C"!==t.atomname||(n=!0,e.sub(t)):(e.sub(t),r=!0))}),i?e:r&&n?(e.normalize(),e.multiplyScalar(cb),e.add(t),e):void 0}function Rs(t){for(var e=t.length,i=new Float32Array(e),r=new Float32Array(e),n=new Float32Array(e),o=0;o<t.length;o++){var a=t[o];i[o]=a.x,r[o]=a.y,n[o]=a.z}return{x:i,y:r,z:n,count:e}}function Os(){return 16777215*Math.random()}function Ds(t,e,i){return t&&"Frames"===t.type?new Rb(t,e,i):!t&&e.frames?new Ob(t,e,i):new Db(t,e,i)}function Ns(t,e){function i(t,i,r,n,o,a,s){a[s+0]=Kn(t.x,i.x,r.x,n.x,o,e),a[s+1]=Kn(t.y,i.y,r.y,n.y,o,e),a[s+2]=Kn(t.z,i.z,r.z,n.z,o,e)}function r(t,i,r,n,o,a){a.x=Kn(t.x,i.x,r.x,n.x,o,e),a.y=Kn(t.y,i.y,r.y,n.y,o,e),a.z=Kn(t.z,i.z,r.z,n.z,o,e)}function n(e,r,n,o,a,s){for(var c=0;c<t;++c)i(e,r,n,o,p*c,a,s+3*c)}function o(e,i,n,o,a,s){for(var c=0;c<t;++c){var u=p*c,h=u-d,l=u+d,g=s+3*c;h<0&&(h=0),l>1&&(l=1),r(e,i,n,o,h,f),r(e,i,n,o,l,m),m.sub(f).normalize(),m.toArray(a,g)}}function a(e,i,r,n,o){for(var a=i.next(),s=i.next(),c=i.next(),u=i.size,h=u-1,l=n||0,p=0;p<h;++p)e(a,a=s,s=c,c=i.next(),r,l),l+=3*t;o&&(e(i.get(u-2),a=i.get(u-1),s=i.get(0),c=i.get(1),r,l),l+=3*t)}function s(e,i,n,o,a,s,c,u,h,l,d,g,w){for(var S=0;S<t;++S){var A=g+3*S;w&&(A+=3*_);var M=p*S;r(e,i,n,o,M,f),r(a,s,c,u,M,m),v.subVectors(m,f).normalize(),y.fromArray(h,A),x.crossVectors(v,y).normalize(),x.toArray(d,A),b.crossVectors(y,x).normalize(),b.toArray(l,A)}}function c(e,i,r,n,o){for(var a=0;a<t;++a){var s=o+3*a;e.copy(b),y.fromArray(i,s),x.crossVectors(e,y).normalize(),x.toArray(n,s),b.crossVectors(y,x).normalize(),b.toArray(r,s)}}function u(e,i,r,n,o){var a;for(a=0;a<_;++a)r(e,n,o+3*a);for(a=_;a<t;++a)r(i,n,o+3*a)}function h(e,i,r,n,o){var a;for(a=0;a<_;++a)n[o+a]=r(e);for(a=_;a<t;++a)n[o+a]=r(i)}function l(e,i,r,n,o){for(var a=r(e),s=r(i),c=0;c<t;++c){var u=c/t;n[o+c]=(1-u)*a+u*s}}var p=1/t,d=1e-4,f=new g,m=new g;this.getPosition=function(e,i,r,o){e.reset(),a(n,e,i,r,o);var s=e.size-1,c=s*t*3;o&&(c+=3*t);var u=e.get(o?0:s);i[c]=u.x,i[c+1]=u.y,i[c+2]=u.z},this.getTangent=function(e,i,r,n){e.reset(),a(o,e,i,r,n);var s=(e.size-1)*t*3;n&&(s+=3*t),Ro(i,i,s-3,s,3)};var v=new g,y=new g,b=new g,x=new g,_=Math.ceil(t/2);this.getNormal=function(e,i,r,n,o,a){b.set(0,0,1);for(var s=e-1,u=o||0,h=0;h<s;++h)c(v,i,r,n,u),u+=3*t;a&&(c(v,i,r,n,u),u+=3*t),x.toArray(n,u),b.toArray(r,u)},this.getNormalDir=function(e,i,r,n,o,a,c,u){e.reset(),i.reset();var h=new g,l=new g,p=new g,d=new g,f=new g,m=(new g).copy(e.next()),v=(new g).copy(e.next()),y=(new g).copy(e.next()),w=new g,S=(new g).copy(i.next()),A=(new g).copy(i.next()),M=(new g).copy(i.next());b.set(0,0,1);for(var P=e.size,T=P-1,E=a||0,C=0;C<T;++C)f.copy(m),m.copy(v),v.copy(y),y.copy(e.next()),w.copy(S),S.copy(A),A.copy(M),M.copy(i.next()),0===C?(h.subVectors(w,f),l.subVectors(S,m),h.dot(l)<0&&(l.multiplyScalar(-1),S.addVectors(m,l)),p.subVectors(A,v),l.dot(p)<0&&(p.multiplyScalar(-1),A.addVectors(v,p))):p.copy(d),d.subVectors(M,y),p.dot(d)<0&&(d.multiplyScalar(-1),M.addVectors(y,d)),s(f,m,v,y,w,S,A,M,r,n,o,E,u),E+=3*t;if(c&&(f.copy(e.get(P-2)),m.copy(e.get(P-1)),v.copy(e.get(0)),y.copy(e.get(1)),w.copy(i.get(P-2)),S.copy(i.get(P-1)),A.copy(i.get(0)),M.copy(i.get(1)),p.copy(d),d.subVectors(M,y),p.dot(d)<0&&(d.multiplyScalar(-1),M.addVectors(y,d)),s(f,m,v,y,w,S,A,M,r,n,o,E,u),E+=3*t),u){x.fromArray(o,3*_),b.fromArray(n,3*_);for(var I=0;I<_;++I)x.toArray(o,3*I),b.toArray(n,3*I)}else x.toArray(o,E),b.toArray(n,E)},this.getColor=function(e,i,r,n,o){e.reset(),e.next();for(var a=e.next(),s=e.size,c=s-1,h=n||0,l=0;l<c;++l)u(a,a=e.next(),i,r,h),h+=3*t;o&&(u(e.get(s-1),a=e.get(0),i,r,h),h+=3*t),r[h]=r[h-3],r[h+1]=r[h-2],r[h+2]=r[h-1]},this.getPicking=function(e,i,r,n,o){e.reset(),e.next();for(var a=e.next(),s=e.size,c=s-1,u=n||0,l=0;l<c;++l)h(a,a=e.next(),i,r,u),u+=t;o&&(h(e.get(s-1),a=e.get(0),i,r,u),u+=t),r[u]=r[u-1]},this.getSize=function(e,i,r,n,o){e.reset(),e.next();for(var a=e.next(),s=e.size,c=s-1,u=n||0,h=0;h<c;++h)l(a,a=e.next(),i,r,u),u+=t;o&&(l(e.get(s-1),a=e.get(0),i,r,u),u+=t),r[u]=r[u-1]}}function ks(t,e){this.polymer=t,this.size=t.residueCount;var i=e||{};this.directional=i.directional||!1,this.positionIterator=i.positionIterator||!1,this.subdiv=i.subdiv||1,this.smoothSheet=i.smoothSheet||!1,isNaN(i.tension)?this.tension=this.polymer.isNucleic()?.5:.9:this.tension=i.tension||.5,this.interpolator=new Ns(this.subdiv,this.tension)}function Bs(t,e,i){e=e||3.5,i=i||40;for(var r=new Kd("( ARG and ( .NE or .NH1 or .NH2 ) ) or ( ASP and .ND2 ) or ( GLN and .NE2 ) or ( HIS and ( .ND1 or .NE2 ) ) or ( LYS and .NZ ) or ( SER and .OG ) or ( THR and .OG1 ) or ( TRP and .NE1 ) or ( TYR and .OH ) or ( PROTEIN and .N )"),n=new Kd("( ASN and .OD1 ) or ( ASP and ( OD1 or .OD2 ) ) or ( GLN and .OE1 ) or ( GLU and ( .OE1 or .OE2 ) ) or ( HIS and ( .ND1 or .NE2 ) ) or ( SER and .OG ) or ( THR and .OG1 ) or ( TYR and .OH ) or ( PROTEIN and .O )"),o=t.getView(r),a=t.getView(n),s=new Xb(o,a).within(e),c=s.bondStore,u=t.getAtomProxy(),h=t.getAtomProxy(),l=t.getAtomProxy(),p=t.getAtomProxy(),d=t.getResidueProxy(),f=t.getResidueProxy(),m=new g,v=new g,y=0,b=c.count;y<b;++y)if(u.index=c.atomIndex1[y],h.index=c.atomIndex2[y],"O"===u.atomname&&"N"===h.atomname||"N"===u.atomname&&"O"===h.atomname)s.bondSet.clear(y);else if("N"===u.atomname||"N"===h.atomname){var x,_;if("N"===u.atomname?(x=u,_=h):(x=h,_=u),d.index=x.residueIndex,l.index=d.getAtomIndexByName("CA"),void 0===l.index)continue;var w=d.getPreviousConnectedResidue(f);if(void 0===w)continue;if(p.index=w.getAtomIndexByName("C"),void 0===p.index)continue;m.subVectors(x,p),v.subVectors(x,l),m.add(v).multiplyScalar(.5),v.subVectors(_,x),Vn(m.angleTo(v))>i&&s.bondSet.clear(y)}else("OH"===u.atomname&&"TYR"===u.resname||"OH"===h.atomname&&"TYR"===h.resname)&&(function(t,e,r,n){var o,a;t.atomname===r?(o=t,a=e):(o=e,a=t),d.index=o.residueIndex;var s=d.getAtomIndexByName(n);return m.subVectors(s,o),v.subVectors(s,a),Vn(m.angleTo(v))<i}(u,h,"OH","CZ")||s.bondSet.clear(y));return{atomSet:s.atomSet,bondSet:s.bondSet,bondStore:s.bondStore}}function Fs(t,e,i){e=e||3.5,i=i||40;for(var r=new Kd("( PROTEIN and .N )"),n=new Kd("( PROTEIN and .O )"),o=t.getView(r),a=t.getView(n),s=new Xb(o,a).within(e),c=s.bondStore,u=t.getAtomProxy(),h=t.getAtomProxy(),l=t.getAtomProxy(),p=t.getAtomProxy(),d=t.getResidueProxy(),f=t.getResidueProxy(),m=new g,v=new g,y=0,b=c.count;y<b;++y){u.index=c.atomIndex1[y],h.index=c.atomIndex2[y];var x,_;if("N"===u.atomname?(x=u,_=h):(x=h,_=u),d.index=x.residueIndex,l.index=d.getAtomIndexByName("CA"),void 0!==l.index){var w=d.getPreviousConnectedResidue(f);void 0!==w&&(p.index=w.getAtomIndexByName("C"),void 0!==p.index&&(m.subVectors(x,p),v.subVectors(x,l),m.add(v).multiplyScalar(.5),v.subVectors(_,x),Vn(m.angleTo(v))>i&&s.bondSet.clear(y)))}}return{atomSet:s.atomSet,bondSet:s.bondSet,bondStore:s.bondStore}}function zs(t,e){this.type=t,this.text=e||{}}function Us(t,e,i,r,n){function o(t,r,o){return((t*e+r)*i+o)*n}var a,s=new(r=r||Int32Array)(t*e*i*(n=n||1));this.data=s,this.index=o,this.set=function(t,e,i){var r=arguments,c=o(t,e,i);for(a=0;a<n;++a)s[c+a]=r[3+a]},this.toArray=function(t,e,i,r,c){var u=o(t,e,i);for(void 0===r&&(r=[]),void 0===c&&(c=0),a=0;a<n;++a)r[c+a]=s[u+a]},this.fromArray=function(t,e,i,r,c){var u=o(t,e,i);for(void 0===c&&(c=0),a=0;a<n;++a)s[u+a]=r[c+a]},this.copy=function(t){this.data.set(t.data)},this.clone=function(){return new Us(t,e,i,r,n).copy(this)}}function js(t,e,i){function r(t,e,i,r,o){m=e||1.4,g=i||2,P=o||!0;var a=0;for(var s in d)a=Math.max(a,s);var c=qa(I,L,a,g,t?m:0);y=c.dim[0],b=c.dim[1],x=c.dim[2],_=c.matrix,w=c.tran,g=c.scaleFactor,S={},A={},n(t),M=m*g,v=r||m/g,T=new Uint8Array(y*b*x),t&&(E=new Float64Array(y*b*x)),P&&(C=new Int32Array(y*b*x))}function n(t){var e,i,r,n,o,a,s,c,u,h;for(var l in d)if(e=d[l],!S[l]){for(a=(s=t?(e+m)*g+.5:e*g+.5)*s,c=Math.floor(s)+1,u=new Int32Array(c*c),h=0,i=0;i<c;++i)for(r=0;r<c;++r)(n=i*i+r*r)>a?u[h]=-1:(o=Math.sqrt(a-n),u[h]=Math.floor(o)),++h;A[l]=c,S[l]=u}}function o(i){var r,n,o,a,s,c,u,h,l,p,d,f,m,v,_,M,E,I,L=3*i,O=i;r=Math.floor(.5+g*(t[L]+w[0])),n=Math.floor(.5+g*(t[L+1]+w[1])),o=Math.floor(.5+g*(t[L+2]+w[2]));var D,N=e[O],k=S[N],B=0,F=b*x,z=A[N];for(p=0;p<z;++p)for(d=0;d<z;++d){if(-1!=(D=k[B]))for(M=-1;M<2;++M)for(E=-1;E<2;++E)for(I=-1;I<2;++I)if(0!==M&&0!==E&&0!==I)for(u=M*p,l=I*d,f=0;f<=D;++f)if(h=f*E,m=r+u,v=n+h,_=o+l,!(m<0||v<0||_<0||m>=y||v>=b||_>=x)){var U=m*F+v*x+_;if(P)if(T[U]&R){if(T[U]&R){var j=C[U];j!==L&&u*u+h*h+l*l<(a=r+u-Math.floor(.5+g*(t[j]+w[0])))*a+(s=n+h-Math.floor(.5+g*(t[j+1]+w[1])))*s+(c=o+l-Math.floor(.5+g*(t[j+2]+w[2])))*c&&(C[U]=i)}}else T[U]|=R,C[U]=i;else T[U]|=R}B++}}function a(e){console.time("EDTSurface fillvoxels");var i,r;for(i=0,r=T.length;i<r;++i)T[i]=0,e&&(E[i]=-1),P&&(C[i]=-1);for(i=0,r=t.length/3;i<r;++i)o(i);for(i=0,r=T.length;i<r;++i)T[i]&R&&(T[i]|=O);console.timeEnd("EDTSurface fillvoxels")}function s(i){var r,n,o,a,s,c,u,h,l,p,d,f,m,v,_,M,E,I,L,R=3*i,D=i,N=0;r=Math.floor(.5+g*(t[R]+w[0])),n=Math.floor(.5+g*(t[R+1]+w[1])),o=Math.floor(.5+g*(t[R+2]+w[2]));var k=e[D],B=b*x;for(m=0,L=A[k];m<L;++m)for(v=0;v<L;++v){if(-1!=S[k][N])for(M=-1;M<2;++M)for(E=-1;E<2;++E)for(I=-1;I<2;++I)if(0!==M&&0!==E&&0!==I)for(u=M*m,l=I*v,_=0;_<=S[k][N];++_)if(h=_*E,p=r+u,d=n+h,f=o+l,!(p<0||d<0||f<0||p>=y||d>=b||f>=x)){var F=p*B+d*x+f;if(T[F]&O){if(P){var z=C[F];u*u+h*h+l*l<(a=Math.floor(.5+g*(t[z]+w[0])))*a+(s=Math.floor(.5+g*(t[z+1]+w[1])))*s+(c=Math.floor(.5+g*(t[z+2]+w[2])))*c&&(C[F]=i)}}else T[F]|=O,P&&(C[F]=i)}N++}}function c(){var e,i;for(e=0,i=T.length;e<i;++e)T[e]&=~O;for(e=0,i=t.length/3;e<i;++e)s(e)}function u(){var t,e,i,r=b*x;for(t=0;t<y;++t)for(e=0;e<x;++e)for(i=0;i<b;++i){var n=t*r+i*x+e;if(T[n]&R)for(var o=0;o<26;){var a=t+N[o][0],s=e+N[o][2],c=i+N[o][1];if(a>-1&&a<y&&c>-1&&c<b&&s>-1&&s<x&&!(T[a*r+c*x+s]&R)){T[n]|=D;break}o++}}}function h(){console.time("EDTSurface fastdistancemap");var t,e,i,r,n,o=new Us(y,b,x,Uint16Array,3),a=b*x,s=M*M,c=0;for(t=0;t<y;++t)for(e=0;e<b;++e)for(i=0;i<x;++i)T[n=t*a+e*x+i]&=~O,T[n]&R&&T[n]&D&&(o.set(t,e,i,t,e,i),E[n]=0,T[n]|=O,c+=1);var u=new Int32Array(3*c),h=0,p=new Int32Array(3*c),d=0;for(t=0;t<y;++t)for(e=0;e<b;++e)for(i=0;i<x;++i)T[n=t*a+e*x+i]&D&&(u[h]=t,u[h+1]=e,u[h+2]=i,h+=3,T[n]&=~D);do{for(d=l(u,o,h,p),h=0,t=0,r=d;t<r;t+=3)n=a*p[t]+x*p[t+1]+p[t+2],T[n]&=~D,E[n]<=1.0404*s&&(u[h]=p[t],u[h+1]=p[t+1],u[h+2]=p[t+2],h+=3)}while(h>0);var f,m=v*v,g=new Uint16Array(3);for(t=0;t<y;++t)for(e=0;e<b;++e)for(i=0;i<x;++i)T[n=t*a+e*x+i]&=~D,T[n]&R&&(T[n]&O&&!(T[n]&O&&E[n]>=m)||(T[n]|=D,P&&T[n]&O&&(o.toArray(t,e,i,g),f=g[0]*a+g[1]*x+g[2],C[n]=C[f])));console.timeEnd("EDTSurface fastdistancemap")}function l(t,e,i,r){var n,o,a,s,c,u,h,l,p,d,f,m,g=new Uint16Array(3),v=0;if(0===i)return v;var _=-1,w=-1,S=-1,A=b*x;for(h=0,p=i;h<p;h+=3)for(n=t[h],o=t[h+1],a=t[h+2],e.toArray(n,o,a,g),l=0;l<6;++l)_=n+(m=N[l])[0],w=o+m[1],S=a+m[2],_<y&&_>-1&&w<b&&w>-1&&S<x&&S>-1&&(T[f=_*A+x*w+S]&R&&!(T[f]&O)?(e.fromArray(_,w,S,g),d=(s=_-g[0])*s+(c=w-g[1])*c+(u=S-g[2])*u,E[f]=d,T[f]|=O,T[f]|=D,r[v]=_,r[v+1]=w,r[v+2]=S,v+=3):T[f]&R&&T[f]&O&&(d=(s=_-g[0])*s+(c=w-g[1])*c+(u=S-g[2])*u)<E[f]&&(e.fromArray(_,w,S,g),E[f]=d,T[f]&D||(T[f]|=D,r[v]=_,r[v+1]=w,r[v+2]=S,v+=3)));for(h=0,p=i;h<p;h+=3)for(n=t[h],o=t[h+1],a=t[h+2],e.toArray(n,o,a,g),l=6;l<18;l++)_=n+(m=N[l])[0],w=o+m[1],S=a+m[2],_<y&&_>-1&&w<b&&w>-1&&S<x&&S>-1&&(T[f=_*A+x*w+S]&R&&!(T[f]&O)?(e.fromArray(_,w,S,g),d=(s=_-g[0])*s+(c=w-g[1])*c+(u=S-g[2])*u,E[f]=d,T[f]|=O,T[f]|=D,r[v]=_,r[v+1]=w,r[v+2]=S,v+=3):T[f]&R&&T[f]&O&&(d=(s=_-g[0])*s+(c=w-g[1])*c+(u=S-g[2])*u)<E[f]&&(e.fromArray(_,w,S,g),E[f]=d,T[f]&D||(T[f]|=D,r[v]=_,r[v+1]=w,r[v+2]=S,v+=3)));for(h=0,p=i;h<p;h+=3)for(n=t[h],o=t[h+1],a=t[h+2],e.toArray(n,o,a,g),l=18;l<26;l++)_=n+(m=N[l])[0],w=o+m[1],S=a+m[2],_<y&&_>-1&&w<b&&w>-1&&S<x&&S>-1&&(T[f=_*A+x*w+S]&R&&!(T[f]&O)?(e.fromArray(_,w,S,g),d=(s=_-g[0])*s+(c=w-g[1])*c+(u=S-g[2])*u,E[f]=d,T[f]|=O,T[f]|=D,r[v]=_,r[v+1]=w,r[v+2]=S,v+=3):T[f]&R&&T[f]&O&&(d=(s=_-g[0])*s+(c=w-g[1])*c+(u=S-g[2])*u)<E[f]&&(e.fromArray(_,w,S,g),E[f]=d,T[f]&D||(T[f]|=D,r[v]=_,r[v+1]=w,r[v+2]=S,v+=3)));return v}function p(t){var e,i=T.length;if("vws"===t)for(e=0;e<i;++e)T[e]&=~D,T[e]=T[e]&O?1:0;else if("ms"===t)for(e=0;e<i;++e)T[e]&=~O,T[e]&D&&(T[e]|=O),T[e]&=~D,T[e]=T[e]&O?1:0;else if("ses"===t)for(e=0;e<i;++e)T[e]&D&&T[e]&O?T[e]&=~D:T[e]&D&&!(T[e]&O)&&(T[e]|=O),T[e]=T[e]&O?1:0;else if("sas"===t)for(e=0;e<i;++e)T[e]&=~D,T[e]=T[e]&O?1:0}var d=Xa(e),f=Qo(t);0===t.length&&(f[0].set([0,0,0]),f[1].set([0,0,0]));var m,g,v,y,b,x,_,w,S,A,M,P,T,E,C,I=f[0],L=f[1],R=1,O=2,D=4,N=[new Int32Array([1,0,0]),new Int32Array([-1,0,0]),new Int32Array([0,1,0]),new Int32Array([0,-1,0]),new Int32Array([0,0,1]),new Int32Array([0,0,-1]),new Int32Array([1,1,0]),new Int32Array([1,-1,0]),new Int32Array([-1,1,0]),new Int32Array([-1,-1,0]),new Int32Array([1,0,1]),new Int32Array([1,0,-1]),new Int32Array([-1,0,1]),new Int32Array([-1,0,-1]),new Int32Array([0,1,1]),new Int32Array([0,1,-1]),new Int32Array([0,-1,1]),new Int32Array([0,-1,-1]),new Int32Array([1,1,1]),new Int32Array([1,1,-1]),new Int32Array([1,-1,1]),new Int32Array([-1,1,1]),new Int32Array([1,-1,-1]),new Int32Array([-1,-1,1]),new Int32Array([-1,1,-1]),new Int32Array([-1,-1,-1])];this.getVolume=function(t,e,o,s,l){console.time("EDTSurface.getVolume");var d="vws"!==t;r(d,e,o,s,l),a(d),u(),"ms"!==t&&"ses"!==t||h(),"ses"===t&&(n(!1),c()),p(t);for(var f=0,m=C.length;f<m;++f)C[f]=i[C[f]];return console.timeEnd("EDTSurface.getVolume"),{data:T,nx:x,ny:b,nz:y,atomindex:C}},this.getSurface=function(t,e,i,r,n,o,a){var s=this.getVolume(t,e,i,r,n);return new Ya(s.data,s.nx,s.ny,s.nz,s.atomindex).getSurface(1,o,void 0,_,a)}}function Gs(t,e,i,r,n,o,a){function s(t,e){return Math.floor((t-e)/a)}for(var c=t.length,u=n[0],h=n[1],l=n[2],p=o[0],d=o[1],f=o[2],m=s(p,u)+1,g=s(d,h)+1,v=s(f,l)+1,y=m*g*v,b=g*v,x=[],_=0;_<c;_++){var w=function(t,e,i){return(s(t,u)*g+s(e,h))*v+s(i,l)}(t[_],e[_],i[_]);void 0===x[w]?x[w]=[_]:x[w].push(_)}var S=new Uint32Array(y),A=new Uint16Array(y),M=new Uint32Array(c),P=0,T=0;for(_=0;_<y;_++){var E=S[_]=P,C=x[_];if(void 0!==C)for(var I=0;I<C.length;I++)M[P]=C[I],P++;var L=P-E;A[_]=L,L>T&&(T=L)}this.neighbourListLength=27*T+1,this.withinRadii=function(n,o,a,c,p){for(var d=0,f=s(n,u),y=s(o,h),x=s(a,l),_=Math.max(0,f-1),w=Math.max(0,y-1),P=Math.max(0,x-1),T=Math.min(m,f+1),E=Math.min(g,y+1),C=Math.min(v,x+1),I=_;I<=T;++I)for(var L=I*b,R=w;R<=E;++R)for(var O=R*v,D=P;D<=C;++D)for(var N=L+O+D,k=S[N],B=k+A[N],F=k;F<B;F++){var z=M[F],U=t[z]-n,j=e[z]-o,G=i[z]-a,V=r[z]+c;U*U+j*j+G*G<=V*V&&(p[d++]=M[F])}p[d]=-1}}function Vs(t,e,i){function r(t,i,r,n){T=dn(t,1.4),E=dn(i,2),C=dn(r,!0),I=dn(n,30),A=new Float32Array(v),M=new Float32Array(v);for(var c=0;c<A.length;++c){var u=e[c]+T;A[c]=u,M[c]=u*u}P=0;for(var h=0;h<A.length;++h)A[h]>P&&(P=A[h]);o(),a(),s(),H=-1}function n(t,e,i){for(var r=0;r<t.length;r++)t[r]=e+i*r}function o(){var t=qa(V,$,P,E,0);E=t.scaleFactor,L=t.dim,R=t.matrix,G=Math.min(5,2+Math.floor(T*E)),O=Po(L[0]*L[1]*L[2],-1001),D=new Int32Array(O.length),N=new Float32Array(L[0]),k=new Float32Array(L[1]),B=new Float32Array(L[2]),n(N,V[0],1/E),n(k,V[1],1/E),n(B,V[2],1/E)}function a(){var t=0,e=2*Math.PI/I;z=new Float32Array(I),F=new Float32Array(I);for(var i=0;i<I;i++)z[i]=Math.cos(t),F[i]=Math.sin(t),t+=e}function s(){U=new Gs(y,b,x,A,V,$,2.01*P),j=new Int32Array(U.neighbourListLength)}function c(t,e,i,r,n){var o;if(-1!==H){if((o=H)!==r&&o!==n&&u(o,t,e,i))return o;H=-1}var a=0;for(o=j[a];o>=0;){if(o!==r&&o!==n&&u(o,t,e,i))return H=o,o;o=j[++a]}return H=-1,-1}function u(e,i,r,n){var o=3*e,a=M[e],s=t[o]-i,c=t[o+1]-r,u=t[o+2]-n;return s*s+c*c+u*u<a}function h(){for(var t=0;t<v;t++){var e=y[t],i=b[t],r=x[t],n=A[t],o=M[t];U.withinRadii(e,i,r,n,j);for(var a=Math.ceil(n*E),s=Math.floor(E*(e-V[0])),u=Math.floor(E*(i-V[1])),h=Math.floor(E*(r-V[2])),l=Math.max(0,s-a),p=Math.max(0,u-a),d=Math.max(0,h-a),f=Math.min(L[0],s+a+2),m=Math.min(L[1],u+a+2),g=Math.min(L[2],h+a+2),_=l;_<f;_++)for(var w=N[_]-e,S=L[1]*L[2]*_,P=p;P<m;P++)for(var T=k[P]-i,I=w*w+T*T,R=S+L[2]*P,F=d;F<g;F++){var z=B[F]-r,G=I+z*z;if(G<o){var $=F+R;O[$]<0&&(O[$]=-O[$]);var H=Math.sqrt(G),W=n/H,X=w*W,q=T*W,Y=z*W;if(X+=e,q+=i,Y+=r,-1===c(X,q,Y,t,-1)){var Z=n-H;Z<O[$]&&(O[$]=Z,C&&(D[$]=t))}}}}}function l(){for(var t=0;t<v;t++){U.withinRadii(y[t],b[t],x[t],A[t],j);for(var e=0,i=j[e];i>=0;)t<i&&p(t,i),i=j[++e]}}function p(t,e){var i=A[t],r=A[e],n=W[0]=y[e]-y[t],o=W[1]=b[e]-b[t],a=W[2]=x[e]-x[t],s=n*n+o*o+a*a,u=Math.sqrt(s),h=i*((i*i+u*u-r*r)/(2*i*u));ua(W,W),d(X,W),ua(X,X),ra(q,W,X),ua(q,q);var l=Math.sqrt(i*i-h*h);ca(X,X,l),ca(q,q,l),ca(W,W,h),W[0]+=y[t],W[1]+=b[t],W[2]+=x[t],H=-1;for(var p=G,f=0;f<I;f++){var m=z[f],g=F[f],v=W[0]+m*X[0]+g*q[0],_=W[1]+m*X[1]+g*q[1],w=W[2]+m*X[2]+g*q[2];if(-1==c(v,_,w,t,e))for(var S=Math.floor(E*(v-V[0])),M=Math.floor(E*(_-V[1])),P=Math.floor(E*(w-V[2])),T=Math.max(0,S-p),R=Math.max(0,M-p),U=Math.max(0,P-p),j=Math.min(L[0],S+p+2),$=Math.min(L[1],M+p+2),Y=Math.min(L[2],P+p+2),Z=T;Z<j;Z++){n=v-N[Z];for(var K=L[1]*L[2]*Z,Q=R;Q<$;Q++)for(var J=n*n+(o=_-k[Q])*o,tt=K+L[2]*Q,et=U;et<Y;et++){s=J+(a=w-B[et])*a;var it=et+tt,rt=O[it];rt>0&&s<rt*rt&&(O[it]=Math.sqrt(s),C&&(D[it]=t))}}}}function d(t,e){return t[0]=t[1]=t[2]=1,0!=e[0]?t[0]=(e[1]+e[2])/-e[0]:0!=e[1]?t[1]=(e[0]+e[2])/-e[1]:0!=e[2]&&(t[2]=(e[0]+e[1])/-e[2]),t}function f(){for(var t=0;t<O.length;t++)O[t]<0&&(O[t]=0)}function m(){for(var t=0;t<D.length;t++)D[t]=i[D[t]]}function g(t,e,i){console.time("AVSurface.getVolume"),console.time("AVSurface.init"),r(t,e,i),console.timeEnd("AVSurface.init"),console.time("AVSurface.projectPoints"),h(),console.timeEnd("AVSurface.projectPoints"),console.time("AVSurface.projectTorii"),l(),console.timeEnd("AVSurface.projectTorii"),f(),m(),console.timeEnd("AVSurface.getVolume")}for(var v=e.length,y=new Float32Array(v),b=new Float32Array(v),x=new Float32Array(v),_=0;_<v;_++){var w=3*_;y[_]=t[w],b[_]=t[w+1],x[_]=t[w+2]}var S=Qo(t);0===t.length&&(S[0].set([0,0,0]),S[1].set([0,0,0]));var A,M,P,T,E,C,I,L,R,O,D,N,k,B,F,z,U,j,G,V=S[0],$=S[1],H=-1,W=new Float32Array([0,0,0]),X=new Float32Array([0,0,0]),q=new Float32Array([0,0,0]);this.getSurface=function(t,e,i,r,n,o,a){return g(e,i,n),new Ya(O,L[2],L[1],L[0],D).getSurface(e,!1,void 0,R,a)}}function $s(t){function e(t){for(var e=l.atomCount[t],n=l.atomOffset[t],o=new Array(e),a=0;a<e;++a)o[a]=h.atomTypeId[n+a];l.residueTypeId[t]=f.add(i,o,r)}var i,r,n=null,o=null,a=null,s=null,c=null,u=null,h=t.atomStore,l=t.residueStore,p=t.chainStore,d=t.modelStore,f=t.residueMap,m=-1,g=-1,v=-1,y=-1;this.addAtom=function(t,f,b,x,_,w,S,A){var M=!1,P=!1,T=!1;n!==t?(M=!0,P=!0,T=!0,y+=1,v+=1,g+=1):o!==b?(P=!0,T=!0,v+=1,g+=1):s===_&&a===x&&c===A||(T=!0,g+=1),m+=1,M&&(d.growIfFull(),d.chainOffset[y]=v,d.chainCount[y]=0,d.count+=1,p.modelIndex[v]=y),P&&(p.growIfFull(),p.setChainname(v,f),p.setChainid(v,b),p.residueOffset[v]=g,p.residueCount[v]=0,p.count+=1,p.modelIndex[v]=y,d.chainCount[y]+=1,l.chainIndex[g]=v),T&&(i=a,r=u,g>0&&e(g-1),l.growIfFull(),l.resno[g]=_,void 0!==S&&(l.sstruc[g]=S.charCodeAt(0)),void 0!==A&&(l.inscode[g]=A.charCodeAt(0)),l.atomOffset[g]=m,l.atomCount[g]=0,l.count+=1,l.chainIndex[g]=v,p.residueCount[v]+=1),h.count+=1,h.residueIndex[m]=g,l.atomCount[g]+=1,n=t,o=b,a=x,s=_,c=A,u=w},this.finalize=function(){i=a,r=u,g>-1&&e(g)}}function Hs(t){switch(t=t.toLowerCase()){case"polymer":return sg;case"non-polymer":return cg;case"macrolide":return ug;case"water":return hg;default:return ag}}function Ws(t){return!t||t[0]!==t[t.length-1]||"'"!==t[0]&&'"'!==t[0]?t:t.substring(1,t.length-1)}function Xs(t,e){Array.isArray(t[e])||Object.keys(t).forEach(function(e){t[e]=[t[e]]})}function qs(t){return"?"!==t}function Ys(t,e){return qs(t)?t:e}function Zs(t){switch(t.toLowerCase()){case"?":case"sing":return 1;case"doub":return 2;case"trip":return 3;case"quad":return 4}return 0}function Ks(t,e,i){var r,n,o=e.atomStore,a=e.atomMap,s=t.chem_comp,c=t.chem_comp_atom,u=t.chem_comp_bond;s&&(s.name&&(e.title=s.name.trim().replace(Lx,"")),s.id&&(e.id=s.id.trim().replace(Lx,"")));var h={};if(c){var l,p,d,f;for(n=c.comp_id.length,r=0;r<n;++r)o.growIfFull(),l=c.atom_id[r].replace(Ix,""),p=c.type_symbol[r],h[l]=r,o.atomTypeId[r]=a.add(l,p),o.x[r]=c.model_Cartn_x[r],o.y[r]=c.model_Cartn_y[r],o.z[r]=c.model_Cartn_z[r],o.serial[r]=r,d=c.pdbx_component_comp_id[r],f=c.pdbx_residue_numbering?c.pdbx_residue_numbering[r]:1,i.addAtom(0,"","",d,f,1);for(r=0;r<n;++r){var m=r+n;o.growIfFull(),l=c.atom_id[r].replace(Ix,""),p=c.type_symbol[r],o.atomTypeId[m]=a.add(l,p),o.x[m]=c.pdbx_model_Cartn_x_ideal[r],o.y[m]=c.pdbx_model_Cartn_y_ideal[r],o.z[m]=c.pdbx_model_Cartn_z_ideal[r],o.serial[m]=m,d=c.pdbx_component_comp_id[r],f=c.pdbx_residue_numbering?c.pdbx_residue_numbering[r]:1,i.addAtom(1,"","",d,f,1)}}if(c&&u){var g,v,y;n=u.comp_id.length;var b=c.comp_id.length,x=e.getAtomProxy(),_=e.getAtomProxy();for(r=0;r<n;++r)g=u.atom_id_1[r].replace(Ix,""),v=u.atom_id_2[r].replace(Ix,""),y=Zs(u.value_order[r]),x.index=h[g],_.index=h[v],e.bondStore.growIfFull(),e.bondStore.addBond(x,_,y),x.index+=b,_.index+=b,e.bondStore.growIfFull(),e.bondStore.addBond(x,_,y)}}function Qs(t,e,i){function r(t){return o.get(n.atomTypeId[t]).covalent}var n=e.atomStore,o=e.atomMap;t.data&&(e.id=t.data,e.name=t.data),e.unitcell=new Mx({a:parseFloat(t.cell_length_a),b:parseFloat(t.cell_length_b),c:parseFloat(t.cell_length_c),alpha:parseFloat(t.cell_angle_alpha),beta:parseFloat(t.cell_angle_beta),gamma:parseFloat(t.cell_angle_gamma),spacegroup:Ws(t.symmetry_space_group_name_H)});for(var a=new g,s=new g,c=t.atom_site_type_symbol.length,u=0;u<c;++u){n.growIfFull();var h=t.atom_site_label[u],l=t.atom_site_type_symbol[u];n.atomTypeId[u]=o.add(h,l),a.set(t.atom_site_fract_x[u],t.atom_site_fract_y[u],t.atom_site_fract_z[u]),a.applyMatrix4(e.unitcell.fracToCart),s.add(a),n.x[u]=a.x,n.y[u]=a.y,n.z[u]=a.z,t.atom_site_occupancy&&(n.occupancy[u]=parseFloat(t.atom_site_occupancy[u])),n.serial[u]=u,i.addAtom(0,"","","HET",1,1)}s.divideScalar(c),e.center=s,hs(e);for(var p=new g,d=new g,f=e.biomolDict.SUPERCELL.partList[0].matrixList,m=c,y=new v,b=0;b<c;++b)!function(t){var e=r(t);a.set(n.x[t],n.y[t],n.z[t]),f.forEach(function(o){if(!y.equals(o)){p.copy(a),p.applyMatrix4(o);for(var s=0;s<c;++s){d.set(n.x[s],n.y[s],n.z[s]);var u=p.distanceToSquared(d),h=r(s)+e,l=h+.3,f=h-.5;if(u<l*l&&u>f*f)return n.growIfFull(),n.atomTypeId[m]=n.atomTypeId[t],n.x[m]=p.x,n.y[m]=p.y,n.z[m]=p.z,n.occupancy[m]=n.occupancy[t],n.serial[m]=m,n.altloc[m]="A".charCodeAt(0),i.addAtom(0,"","","HET",1,1),void(m+=1)}}})}(b)}function Js(t,e,i){var r,n,o,a,s=[],c=[],u=t.struct_conf;if(u)for(Xs(u,"id"),r=0,n=u.beg_auth_seq_id.length;r<n;++r){var h=parseInt(u.pdbx_PDB_helix_class[r]);Number.isNaN(h)||(o=u.pdbx_beg_PDB_ins_code[r],a=u.pdbx_end_PDB_ins_code[r],s.push([i[u.beg_label_asym_id[r]],parseInt(u.beg_auth_seq_id[r]),Ys(o,""),i[u.end_label_asym_id[r]],parseInt(u.end_auth_seq_id[r]),Ys(a,""),(Px[h]||Px[""]).charCodeAt(0)]))}var l=t.struct_sheet_range;if(l)for(Xs(l,"id"),r=0,n=l.beg_auth_seq_id.length;r<n;++r)o=l.pdbx_beg_PDB_ins_code[r],a=l.pdbx_end_PDB_ins_code[r],c.push([i[l.beg_label_asym_id[r]],parseInt(l.beg_auth_seq_id[r]),Ys(o,""),i[l.end_label_asym_id[r]],parseInt(l.end_auth_seq_id[r]),Ys(a,"")]);return!(!u&&!l)&&{helices:s,sheets:c}}function tc(t,e,i){var r={},n=e.biomolDict;if(t.pdbx_struct_oper_list){var o=t.pdbx_struct_oper_list;Xs(o,"id"),o.id.forEach(function(t,e){var i=new v,n=i.elements;n[0]=parseFloat(o["matrix[1][1]"][e]),n[1]=parseFloat(o["matrix[1][2]"][e]),n[2]=parseFloat(o["matrix[1][3]"][e]),n[4]=parseFloat(o["matrix[2][1]"][e]),n[5]=parseFloat(o["matrix[2][2]"][e]),n[6]=parseFloat(o["matrix[2][3]"][e]),n[8]=parseFloat(o["matrix[3][1]"][e]),n[9]=parseFloat(o["matrix[3][2]"][e]),n[10]=parseFloat(o["matrix[3][3]"][e]),n[3]=parseFloat(o["vector[1]"][e]),n[7]=parseFloat(o["vector[2]"][e]),n[11]=parseFloat(o["vector[3]"][e]),i.transpose(),r[t]=i})}if(t.pdbx_struct_assembly_gen){var a=t.pdbx_struct_assembly_gen;Xs(a,"assembly_id");var s=function(t){var e={};return t.replace(/[\(\)']/g,"").split(",").forEach(function(t){if(t.includes("-"))for(var i=t.split("-"),n=parseInt(i[0]),o=parseInt(i[1]);n<=o;++n)e[n]=r[n];else e[t]=r[t]}),e};a.assembly_id.forEach(function(t,e){var r={},o=a.oper_expression[e].replace(/['"]\(|['"]/g,"");if(o.includes(")(")||o.indexOf("(")>0){o=o.split("(");var c=s(o[0]),u=s(o[1]);Object.keys(c).forEach(function(t){Object.keys(u).forEach(function(e){var i=new v;i.multiplyMatrices(c[t],u[e]),r[t+"x"+e]=i})})}else r=s(o);var h=[];for(var l in r)h.push(r[l]);var p=t;/^(0|[1-9][0-9]*)$/.test(p)&&(p="BU"+p);for(var d=a.asym_id_list[e].split(","),f=0,m=d.length;f<m;++f)d[f]=i[d[f]];void 0===n[p]&&(n[p]=new iv(p)),n[p].addPart(h,d)})}if(t.struct_ncs_oper){var c=t.struct_ncs_oper;Xs(c,"id");n.NCS=new iv("NCS");var u=n.NCS.addPart();c.id.forEach(function(t,e){if("given"!==c.code[e]){var i=new v,r=i.elements;r[0]=parseFloat(c["matrix[1][1]"][e]),r[1]=parseFloat(c["matrix[1][2]"][e]),r[2]=parseFloat(c["matrix[1][3]"][e]),r[4]=parseFloat(c["matrix[2][1]"][e]),r[5]=parseFloat(c["matrix[2][2]"][e]),r[6]=parseFloat(c["matrix[2][3]"][e]),r[8]=parseFloat(c["matrix[3][1]"][e]),r[9]=parseFloat(c["matrix[3][2]"][e]),r[10]=parseFloat(c["matrix[3][3]"][e]),r[3]=parseFloat(c["vector[1]"][e]),r[7]=parseFloat(c["vector[2]"][e]),r[11]=parseFloat(c["vector[3]"][e]),i.transpose(),u.matrixList.push(i)}}),0===u.matrixList.length&&delete n.NCS}var h={};if(t.cell){var l=t.cell,p=parseFloat(l.length_a),d=parseFloat(l.length_b),f=parseFloat(l.length_c),m=new Float32Array(9);m[0]=p,m[4]=d,m[8]=f,e.boxes.push(m),h.a=p,h.b=d,h.c=f,h.alpha=parseFloat(l.angle_alpha),h.beta=parseFloat(l.angle_beta),h.gamma=parseFloat(l.angle_gamma)}t.symmetry&&(h.spacegroup=Ws(t.symmetry["space_group_name_H-M"]));var g=new v;if(t.database_PDB_matrix){var y=t.database_PDB_matrix,b=g.elements;b[0]=parseFloat(y["origx[1][1]"]),b[1]=parseFloat(y["origx[1][2]"]),b[2]=parseFloat(y["origx[1][3]"]),b[4]=parseFloat(y["origx[2][1]"]),b[5]=parseFloat(y["origx[2][2]"]),b[6]=parseFloat(y["origx[2][3]"]),b[8]=parseFloat(y["origx[3][1]"]),b[9]=parseFloat(y["origx[3][2]"]),b[10]=parseFloat(y["origx[3][3]"]),b[3]=parseFloat(y["origx_vector[1]"]),b[7]=parseFloat(y["origx_vector[2]"]),b[11]=parseFloat(y["origx_vector[3]"]),g.transpose(),h.origx=g}var x=new v;if(t.atom_sites){var _=t.atom_sites,w=x.elements;w[0]=parseFloat(_["fract_transf_matrix[1][1]"]),w[1]=parseFloat(_["fract_transf_matrix[1][2]"]),w[2]=parseFloat(_["fract_transf_matrix[1][3]"]),w[4]=parseFloat(_["fract_transf_matrix[2][1]"]),w[5]=parseFloat(_["fract_transf_matrix[2][2]"]),w[6]=parseFloat(_["fract_transf_matrix[2][3]"]),w[8]=parseFloat(_["fract_transf_matrix[3][1]"]),w[9]=parseFloat(_["fract_transf_matrix[3][2]"]),w[10]=parseFloat(_["fract_transf_matrix[3][3]"]),w[3]=parseFloat(_["fract_transf_vector[1]"]),w[7]=parseFloat(_["fract_transf_vector[2]"]),w[11]=parseFloat(_["fract_transf_vector[3]"]),x.transpose(),h.scale=x}void 0!==h.a?e.unitcell=new Mx(h):e.unitcell=void 0}function ec(e,i,r){var n=e.struct_conn;if(n){Xs(n,"id");for(var o=i.getAtomProxy(),a=i.getAtomProxy(),s={},c=0,u=n.id.length;c<u;++c){var h=n.conn_type_id[c];if("hydrog"!==h&&"mismat"!==h&&"saltbr"!==h&&("1_555"===n.ptnr1_symmetry[c]&&"1_555"===n.ptnr2_symmetry[c])){var l=n.pdbx_ptnr1_PDB_ins_code[c],p=n.pdbx_ptnr1_label_alt_id[c],d=n.ptnr1_auth_seq_id[c]+(qs(l)?"^"+l:"")+":"+r[n.ptnr1_label_asym_id[c]]+"."+n.ptnr1_label_atom_id[c].replace(/"/g,"")+(qs(p)?"%"+p:""),f=s[d];if(!f){var m=new Kd(d);if(m.selection.error){t.Debug&&cf.warn("invalid selection for connection",d);continue}f=i.getAtomIndices(m),s[d]=f}var g=n.pdbx_ptnr2_PDB_ins_code[c],v=n.pdbx_ptnr2_label_alt_id[c],y=n.ptnr2_auth_seq_id[c]+(qs(g)?"^"+g:"")+":"+r[n.ptnr2_label_asym_id[c]]+"."+n.ptnr2_label_atom_id[c].replace(/"/g,"")+(qs(v)?"%"+v:""),b=s[y];if(!b){var x=new Kd(y);if(x.selection.error){t.Debug&&cf.warn("invalid selection for connection",y);continue}b=i.getAtomIndices(x),s[y]=b}var _=f.length,w=b.length;if(_>w){var S=_;_=w,w=S;var A=f;f=b,b=A}if(0!==_&&0!==w)for(var M=0;M<w;++M)o.index=f[M%_],a.index=b[M],o&&a?i.bondStore.addBond(o,a,Zs(n.pdbx_value_order[c])):cf.log("atoms for connection not found");else t.Debug&&cf.warn("no atoms found for",d,y)}}}}function ic(t,e,i){if(t.entity){Xs(t.entity,"id");for(var r=t.entity,n=r.id.length,o=0;o<n;++o){var a=r.pdbx_description[o],s=r.type[o],c=Array.from(i[r.id[o]]);e.entityList[o]=new Sx(e,o,a,s,c)}}}function rc(t,e,i){return e?new t(e.buffer,e.byteOffset,e.byteLength/(i||1)):void 0}function nc(t){return rc(DataView,t)}function oc(t){return rc(Uint8Array,t)}function ac(t){return rc(Int8Array,t)}function sc(t){return rc(Int32Array,t,4)}function cc(t){return rc(Float32Array,t,4)}function uc(t,e){var i=t.length/2;e||(e=new Int16Array(i));for(var r=0,n=0;r<i;++r,n+=2)e[r]=t[n]<<8^t[n+1]<<0;return e}function hc(t,e){var i=t.length/4;e||(e=new Int32Array(i));for(var r=0,n=0;r<i;++r,n+=4)e[r]=t[n]<<24^t[n+1]<<16^t[n+2]<<8^t[n+3]<<0;return e}function lc(t,e){var i=t.length;e||(e=new Float32Array(i/4));for(var r=nc(e),n=nc(t),o=0,a=0,s=i/4;o<s;++o,a+=4)r.setFloat32(a,n.getFloat32(a),!0);return e}function pc(t,e,i){var r=t.length,n=1/e;i||(i=new Float32Array(r));for(var o=0;o<r;++o)i[o]=t[o]*n;return i}function dc(t,e){var i,r;if(!e){var n=0;for(i=0,r=t.length;i<r;i+=2)n+=t[i+1];e=new t.constructor(n)}var o=0;for(i=0,r=t.length;i<r;i+=2)for(var a=t[i],s=t[i+1],c=0;c<s;++c)e[o]=a,++o;return e}function fc(t,e){var i=t.length;e||(e=new t.constructor(i)),i&&(e[0]=t[0]);for(var r=1;r<i;++r)e[r]=t[r]+e[r-1];return e}function mc(t,e){var i,r,n=t instanceof Int8Array?127:32767,o=-n-1,a=t.length;if(!e){var s=0;for(i=0;i<a;++i)t[i]<n&&t[i]>o&&++s;e=new Int32Array(s)}for(i=0,r=0;i<a;){for(var c=0;t[i]===n||t[i]===o;)c+=t[i],++i;c+=t[i],++i,e[r]=c,++r}return e}function gc(t,e){return fc(dc(t),e)}function vc(t,e,i){return pc(dc(t,sc(i)),e,i)}function yc(t,e,i){return pc(fc(t,sc(i)),e,i)}function bc(t,e,i){return pc(mc(t,sc(i)),e,i)}function xc(t,e,i){var r=mc(t,sc(i));return yc(r,e,cc(r))}function _c(t){var e=nc(t),i=e.getInt32(0),r=e.getInt32(4),n=t.subarray(8,12);return[i,t=t.subarray(12),r,n]}function wc(t){function e(t){for(var e={},i=0;i<t;i++)e[o()]=o();return e}function i(e){var i=t.subarray(a,a+e);return a+=e,i}function r(e){var i=t.subarray(a,a+e);a+=e;if(e>65535){for(var r=[],n=0;n<i.length;n+=65535)r.push(String.fromCharCode.apply(null,i.subarray(n,n+65535)));return r.join("")}return String.fromCharCode.apply(null,i)}function n(t){for(var e=new Array(t),i=0;i<t;i++)e[i]=o();return e}function o(){var o,c,u=t[a];if(0==(128&u))return a++,u;if(128==(240&u))return c=15&u,a++,e(c);if(144==(240&u))return c=15&u,a++,n(c);if(160==(224&u))return c=31&u,a++,r(c);if(224==(224&u))return o=s.getInt8(a),a++,o;switch(u){case 192:return a++,null;case 194:return a++,!1;case 195:return a++,!0;case 196:return c=s.getUint8(a+1),a+=2,i(c);case 197:return c=s.getUint16(a+1),a+=3,i(c);case 198:return c=s.getUint32(a+1),a+=5,i(c);case 202:return o=s.getFloat32(a+1),a+=5,o;case 203:return o=s.getFloat64(a+1),a+=9,o;case 204:return o=t[a+1],a+=2,o;case 205:return o=s.getUint16(a+1),a+=3,o;case 206:return o=s.getUint32(a+1),a+=5,o;case 208:return o=s.getInt8(a+1),a+=2,o;case 209:return o=s.getInt16(a+1),a+=3,o;case 210:return o=s.getInt32(a+1),a+=5,o;case 217:return c=s.getUint8(a+1),a+=2,r(c);case 218:return c=s.getUint16(a+1),a+=3,r(c);case 219:return c=s.getUint32(a+1),a+=5,r(c);case 220:return c=s.getUint16(a+1),a+=3,n(c);case 221:return c=s.getUint32(a+1),a+=5,n(c);case 222:return c=s.getUint16(a+1),a+=3,e(c);case 223:return c=s.getUint32(a+1),a+=5,e(c)}throw new Error("Unknown type 0x"+u.toString(16))}var a=0,s=new DataView(t.buffer);return o()}function Sc(t,e,i,r){switch(t){case 1:return lc(e);case 2:return ac(e);case 3:return uc(e);case 4:return hc(e);case 5:return oc(e);case 6:return dc(hc(e),new Uint8Array(i));case 7:return dc(hc(e));case 8:return gc(hc(e));case 9:return vc(hc(e),hc(r)[0]);case 10:return xc(uc(e),hc(r)[0]);case 11:return pc(uc(e),hc(r)[0]);case 12:return bc(uc(e),hc(r)[0]);case 13:return bc(ac(e),hc(r)[0]);case 14:return mc(uc(e));case 15:return mc(ac(e))}}function Ac(t,e){var i=(e=e||{}).ignoreFields,r={};return Nx.forEach(function(e){var n=!!i&&-1!==i.indexOf(e),o=t[e];n||void 0===o||(o instanceof Uint8Array?r[e]=Sc.apply(null,_c(o)):r[e]=o)}),r}function Mc(){this.regexp={vertex_pattern:/^v\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/,normal_pattern:/^vn\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/,uv_pattern:/^vt\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/,face_vertex:/^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/,face_vertex_uv:/^f\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+))?/,face_vertex_uv_normal:/^f\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+)\/(-?\d+))?/,face_vertex_normal:/^f\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)(?:\s+(-?\d+)\/\/(-?\d+))?/,object_pattern:/^[og]\s*(.+)?/,smoothing_pattern:/^s\s+(\d+|on|off)/,material_library_pattern:/^mtllib /,material_use_pattern:/^usemtl /}}function Pc(){this.propertyNameMapping={}}function Tc(t){return t.replace(f_,"")}function Ec(t){function e(){if(o(/^<\?xml\s*/)){for(var t={attributes:{}};!a()&&!s("?>");){var e=n();if(!e)return t;t.attributes[e.name]=e.value}return o(/\?>\s*/),t}}function i(){var t=o(m_);if(t){for(var e={name:t[1],attributes:{},children:[]};!(a()||s(">")||s("?>")||s("/>"));){var c=n();if(!c)return e;e.attributes[c.name]=c.value}if(o(/^\s*\/>\s*/))return e;o(/\??>\s*/),e.content=r();for(var u;u=i();)e.children.push(u);return o(/^<\/[\w-:.]+>\s*/),e}}function r(){var t=o(g_);return t?t[1]:""}function n(){var t=o(v_);if(t)return{name:t[1],value:Tc(t[2])}}function o(e){var i=t.match(e);if(i)return t=t.slice(i[0].length),i}function a(){return 0===t.length}function s(e){return 0===t.indexOf(e)}return t=t.trim().replace(/<!--[\s\S]*?-->/g,""),function(){return{declaration:e(),root:i()}}()}function Cc(t,e,i){var r=t.icode.value,n=t.chain.value,o=t.altcode.value,a=t.resnum.value;return r.trim()&&(a+="^"+r),n.trim()&&(a+=":"+n),e&&(a+="."+e),i&&o.trim()&&(a+="%"+o),a+="/"+(parseInt(t.model.value)-1)}function Ic(t,e,i){void 0===t[e]?t[e]=i:t[e]|=i}function Lc(t,e){return void 0!==t&&t.value===e}function Rc(t){var e=t.inscode,i=t.chainname,r=t.atomname,n=t.altloc,o=t.resno;return e&&(o+="^"+e),i&&(o+=":"+i),r&&(o+="."+r),n&&(o+="%"+n),o+="/"+t.modelIndex}function Oc(t,e,i){for(var r=0,n=e.getElementsByTagName("clash"),o=0,a=n.length;o<a;++o)if(t[n[o].attributes.cid.value]){r+=1;break}return e.getElementsByTagName("angle-outlier").length>0&&(r+=1),e.getElementsByTagName("bond-outlier").length>0&&(r+=1),e.getElementsByTagName("plane-outlier").length>0&&(r+=1),Lc(i.rota,"OUTLIER")&&(r+=1),Lc(i.rama,"OUTLIER")&&(r+=1),Lc(i.RNApucker,"outlier")&&(r+=1),r}function Dc(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var i=e.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(var r in i)i.hasOwnProperty(r)&&(t[r]=i[r])}}return t}function Nc(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)}function kc(t,e,i,r,n){if(e.subarray&&t.subarray)return void t.set(e.subarray(i,i+r),n);for(var o=0;o<r;o++)t[n+o]=e[i+o]}function Bc(t){var e,i,r,n,o,a;for(r=0,e=0,i=t.length;e<i;e++)r+=t[e].length;for(a=new Uint8Array(r),n=0,e=0,i=t.length;e<i;e++)o=t[e],a.set(o,n),n+=o.length;return a}function Fc(t,e,i,r){for(var n=65535&t|0,o=t>>>16&65535|0,a=0;0!==i;){i-=a=i>2e3?2e3:i;do{o=o+(n=n+e[r++]|0)|0}while(--a);n%=65521,o%=65521}return n|o<<16|0}function zc(t,e,i,r){var n=A_,o=r+i;t^=-1;for(var a=r;a<o;a++)t=t>>>8^n[255&(t^e[a])];return-1^t}function Uc(t,e){var i,r,n,o,a,s,c,u,h,l,p,d,f,m,g,v,y,b,x,_,w,S,A,M,P;i=t.state,r=t.next_in,M=t.input,n=r+(t.avail_in-5),o=t.next_out,P=t.output,a=o-(e-t.avail_out),s=o+(t.avail_out-257),c=i.dmax,u=i.wsize,h=i.whave,l=i.wnext,p=i.window,d=i.hold,f=i.bits,m=i.lencode,g=i.distcode,v=(1<<i.lenbits)-1,y=(1<<i.distbits)-1;t:do{f<15&&(d+=M[r++]<<f,f+=8,d+=M[r++]<<f,f+=8),b=m[d&v];e:for(;;){if(x=b>>>24,d>>>=x,f-=x,0===(x=b>>>16&255))P[o++]=65535&b;else{if(!(16&x)){if(0==(64&x)){b=m[(65535&b)+(d&(1<<x)-1)];continue e}if(32&x){i.mode=P_;break t}t.msg="invalid literal/length code",i.mode=M_;break t}_=65535&b,(x&=15)&&(f<x&&(d+=M[r++]<<f,f+=8),_+=d&(1<<x)-1,d>>>=x,f-=x),f<15&&(d+=M[r++]<<f,f+=8,d+=M[r++]<<f,f+=8),b=g[d&y];i:for(;;){if(x=b>>>24,d>>>=x,f-=x,!(16&(x=b>>>16&255))){if(0==(64&x)){b=g[(65535&b)+(d&(1<<x)-1)];continue i}t.msg="invalid distance code",i.mode=M_;break t}if(w=65535&b,x&=15,f<x&&(d+=M[r++]<<f,(f+=8)<x&&(d+=M[r++]<<f,f+=8)),(w+=d&(1<<x)-1)>c){t.msg="invalid distance too far back",i.mode=M_;break t}if(d>>>=x,f-=x,x=o-a,w>x){if((x=w-x)>h&&i.sane){t.msg="invalid distance too far back",i.mode=M_;break t}if(S=0,A=p,0===l){if(S+=u-x,x<_){_-=x;do{P[o++]=p[S++]}while(--x);S=o-w,A=P}}else if(l<x){if(S+=u+l-x,(x-=l)<_){_-=x;do{P[o++]=p[S++]}while(--x);if(S=0,l<_){_-=x=l;do{P[o++]=p[S++]}while(--x);S=o-w,A=P}}}else if(S+=l-x,x<_){_-=x;do{P[o++]=p[S++]}while(--x);S=o-w,A=P}for(;_>2;)P[o++]=A[S++],P[o++]=A[S++],P[o++]=A[S++],_-=3;_&&(P[o++]=A[S++],_>1&&(P[o++]=A[S++]))}else{S=o-w;do{P[o++]=P[S++],P[o++]=P[S++],P[o++]=P[S++],_-=3}while(_>2);_&&(P[o++]=P[S++],_>1&&(P[o++]=P[S++]))}break}}break}}while(r<n&&o<s);r-=_=f>>3,d&=(1<<(f-=_<<3))-1,t.next_in=r,t.next_out=o,t.avail_in=r<n?n-r+5:5-(r-n),t.avail_out=o<s?s-o+257:257-(o-s),i.hold=d,i.bits=f}function jc(t,e,i,r,n,o,a,s){var c,u,h,l,p,d,f,m,g,v=s.bits,y=0,b=0,x=0,_=0,w=0,S=0,A=0,M=0,P=0,T=0,E=null,C=0,I=new Uint16Array(T_+1),L=new Uint16Array(T_+1),R=null,O=0;for(y=0;y<=T_;y++)I[y]=0;for(b=0;b<r;b++)I[e[i+b]]++;for(w=v,_=T_;_>=1&&0===I[_];_--);if(w>_&&(w=_),0===_)return n[o++]=20971520,n[o++]=20971520,s.bits=1,0;for(x=1;x<_&&0===I[x];x++);for(w<x&&(w=x),M=1,y=1;y<=T_;y++)if(M<<=1,(M-=I[y])<0)return-1;if(M>0&&(t===I_||1!==_))return-1;for(L[1]=0,y=1;y<T_;y++)L[y+1]=L[y]+I[y];for(b=0;b<r;b++)0!==e[i+b]&&(a[L[e[i+b]]++]=b);if(t===I_?(E=R=a,d=19):t===L_?(E=O_,C-=257,R=D_,O-=257,d=256):(E=N_,R=k_,d=-1),T=0,b=0,y=x,p=o,S=w,A=0,h=-1,P=1<<w,l=P-1,t===L_&&P>E_||t===R_&&P>C_)return 1;for(var D=0;;){D++,f=y-A,a[b]<d?(m=0,g=a[b]):a[b]>d?(m=R[O+a[b]],g=E[C+a[b]]):(m=96,g=0),c=1<<y-A,x=u=1<<S;do{n[p+(T>>A)+(u-=c)]=f<<24|m<<16|g|0}while(0!==u);for(c=1<<y-1;T&c;)c>>=1;if(0!==c?(T&=c-1,T+=c):T=0,b++,0==--I[y]){if(y===_)break;y=e[i+a[b]]}if(y>w&&(T&l)!==h){for(0===A&&(A=w),p+=x,M=1<<(S=y-A);S+A<_&&!((M-=I[S+A])<=0);)S++,M<<=1;if(P+=1<<S,t===L_&&P>E_||t===R_&&P>C_)return 1;n[h=T&l]=w<<24|S<<16|p-o|0}}return 0!==T&&(n[p+T]=y-A<<24|64<<16|0),s.bits=w,0}function Gc(t){return(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function Vc(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function $c(t){var e;return t&&t.state?(e=t.state,t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=K_,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(Cw),e.distcode=e.distdyn=new Int32Array(Iw),e.sane=1,e.back=-1,V_):W_}function Hc(t){var e;return t&&t.state?(e=t.state,e.wsize=0,e.whave=0,e.wnext=0,$c(t)):W_}function Wc(t,e){var i,r;return t&&t.state?(r=t.state,e<0?(i=0,e=-e):(i=1+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?W_:(null!==r.window&&r.wbits!==e&&(r.window=null),r.wrap=i,r.wbits=e,Hc(t))):W_}function Xc(t,e){var i,r;return t?(r=new Vc,t.state=r,r.window=null,(i=Wc(t,e))!==V_&&(t.state=null),i):W_}function qc(t){if(Lw){var e;for(w_=new Int32Array(512),S_=new Int32Array(32),e=0;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(jc(F_,t.lens,0,288,w_,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;jc(z_,t.lens,0,32,S_,0,t.work,{bits:5}),Lw=!1}t.lencode=w_,t.lenbits=9,t.distcode=S_,t.distbits=5}function Yc(t,e,i,r){var n,o=t.state;return null===o.window&&(o.wsize=1<<o.wbits,o.wnext=0,o.whave=0,o.window=new Uint8Array(o.wsize)),r>=o.wsize?(kc(o.window,e,i-o.wsize,o.wsize,0),o.wnext=0,o.whave=o.wsize):((n=o.wsize-o.wnext)>r&&(n=r),kc(o.window,e,i-r,n,o.wnext),(r-=n)?(kc(o.window,e,i-r,r,0),o.wnext=r,o.whave=o.wsize):(o.wnext+=n,o.wnext===o.wsize&&(o.wnext=0),o.whave<o.wsize&&(o.whave+=n))),0}function Zc(t,e){var i,r,n,o,a,s,c,u,h,l,p,d,f,m,g,v,y,b,x,_,w,S,A,M,P=0,T=new Uint8Array(4),E=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return W_;(i=t.state).mode===cw&&(i.mode=uw),a=t.next_out,n=t.output,c=t.avail_out,o=t.next_in,r=t.input,s=t.avail_in,u=i.hold,h=i.bits,l=s,p=c,S=V_;t:for(;;)switch(i.mode){case K_:if(0===i.wrap){i.mode=uw;break}for(;h<16;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(2&i.wrap&&35615===u){i.check=0,T[0]=255&u,T[1]=u>>>8&255,i.check=zc(i.check,T,2,0),u=0,h=0,i.mode=Q_;break}if(i.flags=0,i.head&&(i.head.done=!1),!(1&i.wrap)||(((255&u)<<8)+(u>>8))%31){t.msg="incorrect header check",i.mode=Pw;break}if((15&u)!==Z_){t.msg="unknown compression method",i.mode=Pw;break}if(u>>>=4,h-=4,w=8+(15&u),0===i.wbits)i.wbits=w;else if(w>i.wbits){t.msg="invalid window size",i.mode=Pw;break}i.dmax=1<<w,t.adler=i.check=1,i.mode=512&u?aw:cw,u=0,h=0;break;case Q_:for(;h<16;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(i.flags=u,(255&i.flags)!==Z_){t.msg="unknown compression method",i.mode=Pw;break}if(57344&i.flags){t.msg="unknown header flags set",i.mode=Pw;break}i.head&&(i.head.text=u>>8&1),512&i.flags&&(T[0]=255&u,T[1]=u>>>8&255,i.check=zc(i.check,T,2,0)),u=0,h=0,i.mode=J_;case J_:for(;h<32;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}i.head&&(i.head.time=u),512&i.flags&&(T[0]=255&u,T[1]=u>>>8&255,T[2]=u>>>16&255,T[3]=u>>>24&255,i.check=zc(i.check,T,4,0)),u=0,h=0,i.mode=tw;case tw:for(;h<16;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}i.head&&(i.head.xflags=255&u,i.head.os=u>>8),512&i.flags&&(T[0]=255&u,T[1]=u>>>8&255,i.check=zc(i.check,T,2,0)),u=0,h=0,i.mode=ew;case ew:if(1024&i.flags){for(;h<16;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}i.length=u,i.head&&(i.head.extra_len=u),512&i.flags&&(T[0]=255&u,T[1]=u>>>8&255,i.check=zc(i.check,T,2,0)),u=0,h=0}else i.head&&(i.head.extra=null);i.mode=iw;case iw:if(1024&i.flags&&((d=i.length)>s&&(d=s),d&&(i.head&&(w=i.head.extra_len-i.length,i.head.extra||(i.head.extra=new Array(i.head.extra_len)),kc(i.head.extra,r,o,d,w)),512&i.flags&&(i.check=zc(i.check,r,d,o)),s-=d,o+=d,i.length-=d),i.length))break t;i.length=0,i.mode=rw;case rw:if(2048&i.flags){if(0===s)break t;d=0;do{w=r[o+d++],i.head&&w&&i.length<65536&&(i.head.name+=String.fromCharCode(w))}while(w&&d<s);if(512&i.flags&&(i.check=zc(i.check,r,d,o)),s-=d,o+=d,w)break t}else i.head&&(i.head.name=null);i.length=0,i.mode=nw;case nw:if(4096&i.flags){if(0===s)break t;d=0;do{w=r[o+d++],i.head&&w&&i.length<65536&&(i.head.comment+=String.fromCharCode(w))}while(w&&d<s);if(512&i.flags&&(i.check=zc(i.check,r,d,o)),s-=d,o+=d,w)break t}else i.head&&(i.head.comment=null);i.mode=ow;case ow:if(512&i.flags){for(;h<16;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(u!==(65535&i.check)){t.msg="header crc mismatch",i.mode=Pw;break}u=0,h=0}i.head&&(i.head.hcrc=i.flags>>9&1,i.head.done=!0),t.adler=i.check=0,i.mode=cw;break;case aw:for(;h<32;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}t.adler=i.check=Gc(u),u=0,h=0,i.mode=sw;case sw:if(0===i.havedict)return t.next_out=a,t.avail_out=c,t.next_in=o,t.avail_in=s,i.hold=u,i.bits=h,H_;t.adler=i.check=1,i.mode=cw;case cw:if(e===j_||e===G_)break t;case uw:if(i.last){u>>>=7&h,h-=7&h,i.mode=Sw;break}for(;h<3;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}switch(i.last=1&u,u>>>=1,h-=1,3&u){case 0:i.mode=hw;break;case 1:if(qc(i),i.mode=gw,e===G_){u>>>=2,h-=2;break t}break;case 2:i.mode=dw;break;case 3:t.msg="invalid block type",i.mode=Pw}u>>>=2,h-=2;break;case hw:for(u>>>=7&h,h-=7&h;h<32;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if((65535&u)!=(u>>>16^65535)){t.msg="invalid stored block lengths",i.mode=Pw;break}if(i.length=65535&u,u=0,h=0,i.mode=lw,e===G_)break t;case lw:i.mode=pw;case pw:if(d=i.length){if(d>s&&(d=s),d>c&&(d=c),0===d)break t;kc(n,r,o,d,a),s-=d,o+=d,c-=d,a+=d,i.length-=d;break}i.mode=cw;break;case dw:for(;h<14;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(i.nlen=257+(31&u),u>>>=5,h-=5,i.ndist=1+(31&u),u>>>=5,h-=5,i.ncode=4+(15&u),u>>>=4,h-=4,i.nlen>286||i.ndist>30){t.msg="too many length or distance symbols",i.mode=Pw;break}i.have=0,i.mode=fw;case fw:for(;i.have<i.ncode;){for(;h<3;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}i.lens[E[i.have++]]=7&u,u>>>=3,h-=3}for(;i.have<19;)i.lens[E[i.have++]]=0;if(i.lencode=i.lendyn,i.lenbits=7,A={bits:i.lenbits},S=jc(B_,i.lens,0,19,i.lencode,0,i.work,A),i.lenbits=A.bits,S){t.msg="invalid code lengths set",i.mode=Pw;break}i.have=0,i.mode=mw;case mw:for(;i.have<i.nlen+i.ndist;){for(;P=i.lencode[u&(1<<i.lenbits)-1],g=P>>>24,v=P>>>16&255,y=65535&P,!(g<=h);){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(y<16)u>>>=g,h-=g,i.lens[i.have++]=y;else{if(16===y){for(M=g+2;h<M;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(u>>>=g,h-=g,0===i.have){t.msg="invalid bit length repeat",i.mode=Pw;break}w=i.lens[i.have-1],d=3+(3&u),u>>>=2,h-=2}else if(17===y){for(M=g+3;h<M;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}h-=g,w=0,d=3+(7&(u>>>=g)),u>>>=3,h-=3}else{for(M=g+7;h<M;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}h-=g,w=0,d=11+(127&(u>>>=g)),u>>>=7,h-=7}if(i.have+d>i.nlen+i.ndist){t.msg="invalid bit length repeat",i.mode=Pw;break}for(;d--;)i.lens[i.have++]=w}}if(i.mode===Pw)break;if(0===i.lens[256]){t.msg="invalid code -- missing end-of-block",i.mode=Pw;break}if(i.lenbits=9,A={bits:i.lenbits},S=jc(F_,i.lens,0,i.nlen,i.lencode,0,i.work,A),i.lenbits=A.bits,S){t.msg="invalid literal/lengths set",i.mode=Pw;break}if(i.distbits=6,i.distcode=i.distdyn,A={bits:i.distbits},S=jc(z_,i.lens,i.nlen,i.ndist,i.distcode,0,i.work,A),i.distbits=A.bits,S){t.msg="invalid distances set",i.mode=Pw;break}if(i.mode=gw,e===G_)break t;case gw:i.mode=vw;case vw:if(s>=6&&c>=258){t.next_out=a,t.avail_out=c,t.next_in=o,t.avail_in=s,i.hold=u,i.bits=h,Uc(t,p),a=t.next_out,n=t.output,c=t.avail_out,o=t.next_in,r=t.input,s=t.avail_in,u=i.hold,h=i.bits,i.mode===cw&&(i.back=-1);break}for(i.back=0;P=i.lencode[u&(1<<i.lenbits)-1],g=P>>>24,v=P>>>16&255,y=65535&P,!(g<=h);){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(v&&0==(240&v)){for(b=g,x=v,_=y;P=i.lencode[_+((u&(1<<b+x)-1)>>b)],g=P>>>24,v=P>>>16&255,y=65535&P,!(b+g<=h);){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}u>>>=b,h-=b,i.back+=b}if(u>>>=g,h-=g,i.back+=g,i.length=y,0===v){i.mode=ww;break}if(32&v){i.back=-1,i.mode=cw;break}if(64&v){t.msg="invalid literal/length code",i.mode=Pw;break}i.extra=15&v,i.mode=yw;case yw:if(i.extra){for(M=i.extra;h<M;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}i.length+=u&(1<<i.extra)-1,u>>>=i.extra,h-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=bw;case bw:for(;P=i.distcode[u&(1<<i.distbits)-1],g=P>>>24,v=P>>>16&255,y=65535&P,!(g<=h);){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(0==(240&v)){for(b=g,x=v,_=y;P=i.distcode[_+((u&(1<<b+x)-1)>>b)],g=P>>>24,v=P>>>16&255,y=65535&P,!(b+g<=h);){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}u>>>=b,h-=b,i.back+=b}if(u>>>=g,h-=g,i.back+=g,64&v){t.msg="invalid distance code",i.mode=Pw;break}i.offset=y,i.extra=15&v,i.mode=xw;case xw:if(i.extra){for(M=i.extra;h<M;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}i.offset+=u&(1<<i.extra)-1,u>>>=i.extra,h-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){t.msg="invalid distance too far back",i.mode=Pw;break}i.mode=_w;case _w:if(0===c)break t;if(d=p-c,i.offset>d){if((d=i.offset-d)>i.whave&&i.sane){t.msg="invalid distance too far back",i.mode=Pw;break}d>i.wnext?(d-=i.wnext,f=i.wsize-d):f=i.wnext-d,d>i.length&&(d=i.length),m=i.window}else m=n,f=a-i.offset,d=i.length;d>c&&(d=c),c-=d,i.length-=d;do{n[a++]=m[f++]}while(--d);0===i.length&&(i.mode=vw);break;case ww:if(0===c)break t;n[a++]=i.length,c--,i.mode=vw;break;case Sw:if(i.wrap){for(;h<32;){if(0===s)break t;s--,u|=r[o++]<<h,h+=8}if(p-=c,t.total_out+=p,i.total+=p,p&&(t.adler=i.check=i.flags?zc(i.check,n,p,a-p):Fc(i.check,n,p,a-p)),p=c,(i.flags?u:Gc(u))!==i.check){t.msg="incorrect data check",i.mode=Pw;break}u=0,h=0}i.mode=Aw;case Aw:if(i.wrap&&i.flags){for(;h<32;){if(0===s)break t;s--,u+=r[o++]<<h,h+=8}if(u!==(4294967295&i.total)){t.msg="incorrect length check",i.mode=Pw;break}u=0,h=0}i.mode=Mw;case Mw:S=$_;break t;case Pw:S=X_;break t;case Tw:return q_;case Ew:default:return W_}return t.next_out=a,t.avail_out=c,t.next_in=o,t.avail_in=s,i.hold=u,i.bits=h,(i.wsize||p!==t.avail_out&&i.mode<Pw&&(i.mode<Sw||e!==U_))&&Yc(t,t.output,t.next_out,p-t.avail_out)?(i.mode=Tw,q_):(l-=t.avail_in,p-=t.avail_out,t.total_in+=l,t.total_out+=p,i.total+=p,i.wrap&&p&&(t.adler=i.check=i.flags?zc(i.check,n,p,t.next_out-p):Fc(i.check,n,p,t.next_out-p)),t.data_type=i.bits+(i.last?64:0)+(i.mode===cw?128:0)+(i.mode===gw||i.mode===lw?256:0),(0===l&&0===p||e===U_)&&S===V_&&(S=Y_),S)}function Kc(t){if(!t||!t.state)return W_;var e=t.state;return e.window&&(e.window=null),t.state=null,V_}function Qc(t,e){var i;return t&&t.state?0==(2&(i=t.state).wrap)?W_:(i.head=e,e.done=!1,V_):W_}function Jc(t,e){var i,r,n=e.length;return t&&t.state?0!==(i=t.state).wrap&&i.mode!==sw?W_:i.mode===sw&&(r=1,(r=Fc(r,e,n,0))!==i.check)?X_:Yc(t,e,n,n)?(i.mode=Tw,q_):(i.havedict=1,V_):W_}function tu(t){var e,i,r,n,o,a=t.length,s=0;for(n=0;n<a;n++)55296==(64512&(i=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(r=t.charCodeAt(n+1)))&&(i=65536+(i-55296<<10)+(r-56320),n++),s+=i<128?1:i<2048?2:i<65536?3:4;for(e=new Uint8Array(s),o=0,n=0;o<s;n++)55296==(64512&(i=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(r=t.charCodeAt(n+1)))&&(i=65536+(i-55296<<10)+(r-56320),n++),i<128?e[o++]=i:i<2048?(e[o++]=192|i>>>6,e[o++]=128|63&i):i<65536?(e[o++]=224|i>>>12,e[o++]=128|i>>>6&63,e[o++]=128|63&i):(e[o++]=240|i>>>18,e[o++]=128|i>>>12&63,e[o++]=128|i>>>6&63,e[o++]=128|63&i);return e}function eu(t,e){if(e<65537&&(t.subarray&&Ow||!t.subarray&&Rw))return String.fromCharCode.apply(null,Nc(t,e));for(var i="",r=0;r<e;r++)i+=String.fromCharCode(t[r]);return i}function iu(t){for(var e=new Uint8Array(t.length),i=0,r=e.length;i<r;i++)e[i]=t.charCodeAt(i);return e}function ru(t,e){var i,r,n,o,a=e||t.length,s=new Array(2*a);for(r=0,i=0;i<a;)if((n=t[i++])<128)s[r++]=n;else if((o=Dw[n])>4)s[r++]=65533,i+=o-1;else{for(n&=2===o?31:3===o?15:7;o>1&&i<a;)n=n<<6|63&t[i++],o--;o>1?s[r++]=65533:n<65536?s[r++]=n:(n-=65536,s[r++]=55296|n>>10&1023,s[r++]=56320|1023&n)}return eu(s,r)}function nu(t,e){var i;for((e=e||t.length)>t.length&&(e=t.length),i=e-1;i>=0&&128==(192&t[i]);)i--;return i<0?e:0===i?e:i+Dw[t[i]]>e?i:e}function ou(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}function au(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}function su(t){if(!(this instanceof su))return new su(t);this.options=Dc({chunkSize:16384,windowBits:0,to:""},t||{});var e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new ou,this.strm.avail_out=0;var i=Xc(this.strm,e.windowBits);if(i!==kw)throw new Error(Bw[i]);this.header=new au,Qc(this.strm,this.header)}function cu(t,e){var i=new su(e);if(i.push(t,!0),i.err)throw i.msg;return i.result}function uu(t){var e;t instanceof ArrayBuffer&&(t=new Uint8Array(t));try{e=cu(t)}catch(i){e=t}return e}function hu(){this.getUrl=function(t){var e,i=yn(t),r=i.name.substr(0,4);return!["pdb","cif"].includes(i.ext)||!1!==i.compressed&&"gz"!==i.compressed?"mmtf"===i.ext?e=i.base.endsWith(".bb")?jw+r:Uw+r:i.ext?(cf.warn("unsupported ext",i.ext),e=Uw+r):e=Uw+r:e=zw+i.path,fn()+e},this.getExt=function(t){var e=yn(t);if("mmtf"===e.ext||!e.ext)return"mmtf"}}function lu(){this.getUrl=function(t){var e,i=yn(t),r=i.name;return i.ext&&"sdf"!==i.ext?(cf.warn("unsupported ext",i.ext),e=Gw+r+Vw):e=Gw+r+Vw,fn()+e},this.getExt=function(t){var e=yn(t);if(!e.ext||"sdf"===e.ext)return"sdf"}}function pu(){this.getUrl=function(t){return t}}function du(t){t=t||"",this.getUrl=function(e){var i=yn(e),r=t+i.path;return $w.test(t)||(r=gn(r)),r}}"undefined"!=typeof window&&function(){window.console=window.console||{};for(var t,e,i=window.console,r={},n=function(){},o="memory".split(","),a="assert,clear,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn".split(",");t=o.pop();)i[t]||(i[t]=r);for(;e=a.pop();)i[e]||(i[e]=n)}(),"undefined"==typeof HTMLCanvasElement||HTMLCanvasElement.prototype.toBlob||Object.defineProperty(HTMLCanvasElement.prototype,"toBlob",{value:function(t,e,i){for(var r=window.atob(this.toDataURL(e,i).split(",")[1]),n=r.length,o=n>>2,a=new Uint8Array(n),s=new Uint32Array(a.buffer,0,o),c=0,u=0;c<o;c++)s[c]=r.charCodeAt(u++)|r.charCodeAt(u++)<<8|r.charCodeAt(u++)<<16|r.charCodeAt(u++)<<24;for(var h=3&n;h--;)a[u]=r.charCodeAt(u++);t(new Blob([a],{type:e||"image/png"}))}}),Math.cbrt=Math.cbrt||function(t){var e=Math.pow(Math.abs(t),1/3);return t<0?-e:e},Math.sign||(Math.sign=function(t){return t=+t,0===t||isNaN(t)?Number(t):t>0?1:-1}),Number.isInteger||(Number.isInteger=function(t){return"number"==typeof t&&isFinite(t)&&t>-9007199254740992&&t<9007199254740992&&Math.floor(t)===t}),Number.isNaN||(Number.isNaN=function(t){return t!==t}),Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(t){var e=arguments;if(void 0===t||null===t)throw new TypeError("Cannot convert first argument to object");for(var i,r=Object(t),n=!1,o=1;o<arguments.length;o++){var a=e[o];if(void 0!==a&&null!==a){for(var s=Object.keys(Object(a)),c=0,u=s.length;c<u;c++){var h=s[c];try{var l=Object.getOwnPropertyDescriptor(a,h);void 0!==l&&l.enumerable&&(r[h]=a[h])}catch(t){n||(n=!0,i=t)}}if(n)throw i}}return r}}),String.prototype.startsWith||function(){var t=function(){var t;try{var e={},i=Object.defineProperty;t=i(e,e,e)&&i}catch(t){}return t}(),e={}.toString,i=function(t){if(null===this)throw TypeError();var i=String(this);if(t&&"[object RegExp]"==e.call(t))throw TypeError();var r=i.length,n=String(t),o=n.length,a=arguments.length>1?arguments[1]:void 0,s=a?Number(a):0;s!=s&&(s=0);var c=Math.min(Math.max(s,0),r);if(o+c>r)return!1;for(var u=-1;++u<o;)if(i.charCodeAt(c+u)!=n.charCodeAt(u))return!1;return!0};t?t(String.prototype,"startsWith",{value:i,configurable:!0,writable:!0}):String.prototype.startsWith=i}(),String.prototype.endsWith||(String.prototype.endsWith=function(t,e){var i=this.toString();("number"!=typeof e||!isFinite(e)||Math.floor(e)!==e||e>i.length)&&(e=i.length),e-=t.length;var r=i.indexOf(t,e);return-1!==r&&r===e}),String.prototype.includes||(String.prototype.includes=function(t,e){return"number"!=typeof e&&(e=0),!(e+t.length>this.length)&&-1!==this.indexOf(t,e)}),Array.prototype.includes||(Array.prototype.includes=function(t){if(null==this)throw new TypeError("Array.prototype.includes called on null or undefined");var e=Object(this),i=parseInt(e.length,10)||0;if(0===i)return!1;var r,n=parseInt(arguments[1],10)||0;n>=0?r=n:(r=i+n)<0&&(r=0);for(var o;r<i;){if(o=e[r],t===o||t!==t&&o!==o)return!0;r++}return!1}),Array.from||(Array.from=function(){var t=Object.prototype.toString,e=function(e){return"function"==typeof e||"[object Function]"===t.call(e)},i=function(t){var e=Number(t);return isNaN(e)?0:0!==e&&isFinite(e)?(e>0?1:-1)*Math.floor(Math.abs(e)):e},r=Math.pow(2,53)-1,n=function(t){var e=i(t);return Math.min(Math.max(e,0),r)};return function(t){var i=this,r=Object(t);if(null==t)throw new TypeError("Array.from requires an array-like object - not null or undefined");var o,a=arguments.length>1?arguments[1]:void 0;if(void 0!==a){if(!e(a))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(o=arguments[2])}for(var s,c=n(r.length),u=e(i)?Object(new i(c)):new Array(c),h=0;h<c;)s=r[h],u[h]=a?void 0===o?a(s,h):a.call(o,s,h):s,h+=1;return u.length=c,u}}()),"undefined"!=typeof window&&function(){for(var t=0,e=["ms","moz","webkit","o"],i=0;i<e.length&&!window.requestAnimationFrame;++i)window.requestAnimationFrame=window[e[i]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[i]+"CancelAnimationFrame"]||window[e[i]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e){var i=(new Date).getTime(),r=Math.max(0,16-(i-t)),n=window.setTimeout(function(){e(i+r)},r);return t=i+r,n}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)})}(),void 0===Function.prototype.name&&void 0!==Object.defineProperty&&Object.defineProperty(Function.prototype,"name",{get:function(){return this.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]}}),"undefined"!=typeof window&&(void 0===window.performance&&(self.performance={}),void 0===window.performance.now&&function(){var t=Date.now();window.performance.now=function(){return Date.now()-t}}());var fu=setTimeout,mu="function"==typeof setImmediate&&setImmediate||function(t){fu(t,0)},gu=function(t){"undefined"!=typeof console&&console&&console.warn("Possible Unhandled Promise Rejection:",t)};r.prototype.catch=function(t){return this.then(null,t)},r.prototype.then=function(t,i){var r=new this.constructor(e);return n(this,new c(t,i,r)),r},r.all=function(t){var e=Array.prototype.slice.call(t);return new r(function(t,i){function r(o,a){try{if(a&&("object"==typeof a||"function"==typeof a)){var s=a.then;if("function"==typeof s)return void s.call(a,function(t){r(o,t)},i)}e[o]=a,0==--n&&t(e)}catch(t){i(t)}}if(0===e.length)return t([]);for(var n=e.length,o=0;o<e.length;o++)r(o,e[o])})},r.resolve=function(t){return t&&"object"==typeof t&&t.constructor===r?t:new r(function(e){e(t)})},r.reject=function(t){return new r(function(e,i){i(t)})},r.race=function(t){return new r(function(e,i){for(var r=0,n=t.length;r<n;r++)t[r].then(e,i)})},r._setImmediateFn=function(t){mu=t},r._setUnhandledRejectionFn=function(t){gu=t},void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52)),void 0===Number.isInteger&&(Number.isInteger=function(t){return"number"==typeof t&&isFinite(t)&&Math.floor(t)===t}),void 0===Math.sign&&(Math.sign=function(t){return t<0?-1:t>0?1:+t}),void 0===Function.prototype.name&&Object.defineProperty(Function.prototype,"name",{get:function(){return this.toString().match(/^\s*function\s*([^\(\s]*)/)[1]}}),void 0===Object.assign&&function(){Object.assign=function(t){var e=arguments;if(void 0===t||null===t)throw new TypeError("Cannot convert undefined or null to object");for(var i=Object(t),r=1;r<arguments.length;r++){var n=e[r];if(void 0!==n&&null!==n)for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(i[o]=n[o])}return i}}(),Object.assign(h.prototype,{addEventListener:function(t,e){void 0===this._listeners&&(this._listeners={});var i=this._listeners;void 0===i[t]&&(i[t]=[]),-1===i[t].indexOf(e)&&i[t].push(e)},hasEventListener:function(t,e){if(void 0===this._listeners)return!1;var i=this._listeners;return void 0!==i[t]&&-1!==i[t].indexOf(e)},removeEventListener:function(t,e){if(void 0!==this._listeners){var i=this._listeners[t];if(void 0!==i){var r=i.indexOf(e);-1!==r&&i.splice(r,1)}}},dispatchEvent:function(t){var e=this;if(void 0!==this._listeners){var i=this._listeners[t.type];if(void 0!==i){t.target=this;var r=[],n=0,o=i.length;for(n=0;n<o;n++)r[n]=i[n];for(n=0;n<o;n++)r[n].call(e,t)}}}});var vu="85",yu=0,bu=1,xu=2,_u=0,wu=1,Su=2,Au=0,Mu=1,Pu=2,Tu=1,Eu=2,Cu=0,Iu=1,Lu=2,Ru=0,Ou=1,Du=2,Nu=3,ku=4,Bu=5,Fu=100,zu=101,Uu=102,ju=103,Gu=104,Vu=200,$u=201,Hu=202,Wu=203,Xu=204,qu=205,Yu=206,Zu=207,Ku=208,Qu=209,Ju=210,th=0,eh=1,ih=2,rh=3,nh=4,oh=5,ah=6,sh=7,ch=0,uh=1,hh=2,lh=0,ph=1,dh=2,fh=3,mh=4,gh=301,vh=302,yh=303,bh=304,xh=305,_h=306,wh=307,Sh=1e3,Ah=1001,Mh=1002,Ph=1003,Th=1004,Eh=1005,Ch=1006,Ih=1007,Lh=1008,Rh=1009,Oh=1010,Dh=1011,Nh=1012,kh=1013,Bh=1014,Fh=1015,zh=1016,Uh=1017,jh=1018,Gh=1019,Vh=1020,$h=1021,Hh=1022,Wh=1023,Xh=1024,qh=1025,Yh=1026,Zh=1027,Kh=2001,Qh=2002,Jh=2003,tl=2004,el=2100,il=2101,rl=2102,nl=2103,ol=2151,al=2201,sl=2400,cl=0,ul=1,hl=2,ll=3e3,pl=3001,dl=3007,fl=3002,ml=3004,gl=3005,vl=3006,yl=3200,bl=3201,xl={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var t,e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),i=new Array(36),r=0;return function(){for(var n=0;n<36;n++)8===n||13===n||18===n||23===n?i[n]="-":14===n?i[n]="4":(r<=2&&(r=33554432+16777216*Math.random()|0),t=15&r,r>>=4,i[n]=e[19===n?3&t|8:t]);return i.join("")}}(),clamp:function(t,e,i){return Math.max(e,Math.min(i,t))},euclideanModulo:function(t,e){return(t%e+e)%e},mapLinear:function(t,e,i,r,n){return r+(t-e)*(n-r)/(i-e)},lerp:function(t,e,i){return(1-i)*t+i*e},smoothstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*(3-2*t)},smootherstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*t*(t*(6*t-15)+10)},randInt:function(t,e){return t+Math.floor(Math.random()*(e-t+1))},randFloat:function(t,e){return t+Math.random()*(e-t)},randFloatSpread:function(t){return t*(.5-Math.random())},degToRad:function(t){return t*xl.DEG2RAD},radToDeg:function(t){return t*xl.RAD2DEG},isPowerOfTwo:function(t){return 0==(t&t-1)&&0!==t},nearestPowerOfTwo:function(t){return Math.pow(2,Math.round(Math.log(t)/Math.LN2))},nextPowerOfTwo:function(t){return t--,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t}};Object.defineProperties(l.prototype,{width:{get:function(){return this.x},set:function(t){this.x=t}},height:{get:function(){return this.y},set:function(t){this.y=t}}}),Object.assign(l.prototype,{isVector2:!0,set:function(t,e){return this.x=t,this.y=e,this},setScalar:function(t){return this.x=t,this.y=t,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setComponent:function(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;default:throw new Error("index is out of range: "+t)}return this},getComponent:function(t){switch(t){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+t)}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(t){return this.x=t.x,this.y=t.y,this},add:function(t,e){return void 0!==e?(console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(t,e)):(this.x+=t.x,this.y+=t.y,this)},addScalar:function(t){return this.x+=t,this.y+=t,this},addVectors:function(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this},addScaledVector:function(t,e){return this.x+=t.x*e,this.y+=t.y*e,this},sub:function(t,e){return void 0!==e?(console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(t,e)):(this.x-=t.x,this.y-=t.y,this)},subScalar:function(t){return this.x-=t,this.y-=t,this},subVectors:function(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this},multiply:function(t){return this.x*=t.x,this.y*=t.y,this},multiplyScalar:function(t){return this.x*=t,this.y*=t,this},divide:function(t){return this.x/=t.x,this.y/=t.y,this},divideScalar:function(t){return this.multiplyScalar(1/t)},min:function(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this},max:function(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this},clamp:function(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this},clampScalar:function(){var t=new l,e=new l;return function(i,r){return t.set(i,i),e.set(r,r),this.clamp(t,e)}}(),clampLength:function(t,e){var i=this.length();return this.multiplyScalar(Math.max(t,Math.min(e,i))/i)},floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},roundToZero:function(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this},negate:function(){return this.x=-this.x,this.y=-this.y,this},dot:function(t){return this.x*t.x+this.y*t.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length())},angle:function(){var t=Math.atan2(this.y,this.x);return t<0&&(t+=2*Math.PI),t},distanceTo:function(t){return Math.sqrt(this.distanceToSquared(t))},distanceToSquared:function(t){var e=this.x-t.x,i=this.y-t.y;return e*e+i*i},distanceToManhattan:function(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)},setLength:function(t){return this.multiplyScalar(t/this.length())},lerp:function(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this},lerpVectors:function(t,e,i){return this.subVectors(e,t).multiplyScalar(i).add(t)},equals:function(t){return t.x===this.x&&t.y===this.y},fromArray:function(t,e){return void 0===e&&(e=0),this.x=t[e],this.y=t[e+1],this},toArray:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=0),t[e]=this.x,t[e+1]=this.y,t},fromBufferAttribute:function(t,e,i){return void 0!==i&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute()."),this.x=t.getX(e),this.y=t.getY(e),this},rotateAround:function(t,e){var i=Math.cos(e),r=Math.sin(e),n=this.x-t.x,o=this.y-t.y;return this.x=n*i-o*r+t.x,this.y=n*r+o*i+t.y,this}});var _l=0;p.DEFAULT_IMAGE=void 0,p.DEFAULT_MAPPING=300,Object.defineProperty(p.prototype,"needsUpdate",{set:function(t){!0===t&&this.version++}}),Object.assign(p.prototype,h.prototype,{constructor:p,isTexture:!0,clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.name=t.name,this.image=t.image,this.mipmaps=t.mipmaps.slice(0),this.mapping=t.mapping,this.wrapS=t.wrapS,this.wrapT=t.wrapT,this.magFilter=t.magFilter,this.minFilter=t.minFilter,this.anisotropy=t.anisotropy,this.format=t.format,this.type=t.type,this.offset.copy(t.offset),this.repeat.copy(t.repeat),this.generateMipmaps=t.generateMipmaps,this.premultiplyAlpha=t.premultiplyAlpha,this.flipY=t.flipY,this.unpackAlignment=t.unpackAlignment,this.encoding=t.encoding,this},toJSON:function(t){if(void 0!==t.textures[this.uuid])return t.textures[this.uuid];var e={metadata:{version:4.5,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,mapping:this.mapping,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],wrap:[this.wrapS,this.wrapT],minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY};if(void 0!==this.image){var i=this.image;void 0===i.uuid&&(i.uuid=xl.generateUUID()),void 0===t.images[i.uuid]&&(t.images[i.uuid]={uuid:i.uuid,url:function(t){var e;return void 0!==t.toDataURL?e=t:((e=document.createElementNS("http://www.w3.org/1999/xhtml","canvas")).width=t.width,e.height=t.height,e.getContext("2d").drawImage(t,0,0,t.width,t.height)),e.width>2048||e.height>2048?e.toDataURL("image/jpeg",.6):e.toDataURL("image/png")}(i)}),e.image=i.uuid}return t.textures[this.uuid]=e,e},dispose:function(){this.dispatchEvent({type:"dispose"})},transformUv:function(t){if(300===this.mapping){if(t.multiply(this.repeat),t.add(this.offset),t.x<0||t.x>1)switch(this.wrapS){case Sh:t.x=t.x-Math.floor(t.x);break;case Ah:t.x=t.x<0?0:1;break;case Mh:1===Math.abs(Math.floor(t.x)%2)?t.x=Math.ceil(t.x)-t.x:t.x=t.x-Math.floor(t.x)}if(t.y<0||t.y>1)switch(this.wrapT){case Sh:t.y=t.y-Math.floor(t.y);break;case Ah:t.y=t.y<0?0:1;break;case Mh:1===Math.abs(Math.floor(t.y)%2)?t.y=Math.ceil(t.y)-t.y:t.y=t.y-Math.floor(t.y)}this.flipY&&(t.y=1-t.y)}}}),Object.assign(d.prototype,{isVector4:!0,set:function(t,e,i,r){return this.x=t,this.y=e,this.z=i,this.w=r,this},setScalar:function(t){return this.x=t,this.y=t,this.z=t,this.w=t,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setZ:function(t){return this.z=t,this},setW:function(t){return this.w=t,this},setComponent:function(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;case 3:this.w=e;break;default:throw new Error("index is out of range: "+t)}return this},getComponent:function(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+t)}},clone:function(){return new this.constructor(this.x,this.y,this.z,this.w)},copy:function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=void 0!==t.w?t.w:1,this},add:function(t,e){return void 0!==e?(console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(t,e)):(this.x+=t.x,this.y+=t.y,this.z+=t.z,this.w+=t.w,this)},addScalar:function(t){return this.x+=t,this.y+=t,this.z+=t,this.w+=t,this},addVectors:function(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this.w=t.w+e.w,this},addScaledVector:function(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this.w+=t.w*e,this},sub:function(t,e){return void 0!==e?(console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(t,e)):(this.x-=t.x,this.y-=t.y,this.z-=t.z,this.w-=t.w,this)},subScalar:function(t){return this.x-=t,this.y-=t,this.z-=t,this.w-=t,this},subVectors:function(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this.w=t.w-e.w,this},multiplyScalar:function(t){return this.x*=t,this.y*=t,this.z*=t,this.w*=t,this},applyMatrix4:function(t){var e=this.x,i=this.y,r=this.z,n=this.w,o=t.elements;return this.x=o[0]*e+o[4]*i+o[8]*r+o[12]*n,this.y=o[1]*e+o[5]*i+o[9]*r+o[13]*n,this.z=o[2]*e+o[6]*i+o[10]*r+o[14]*n,this.w=o[3]*e+o[7]*i+o[11]*r+o[15]*n,this},divideScalar:function(t){return this.multiplyScalar(1/t)},setAxisAngleFromQuaternion:function(t){this.w=2*Math.acos(t.w);var e=Math.sqrt(1-t.w*t.w);return e<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=t.x/e,this.y=t.y/e,this.z=t.z/e),this},setAxisAngleFromRotationMatrix:function(t){var e,i,r,n,o=t.elements,a=o[0],s=o[4],c=o[8],u=o[1],h=o[5],l=o[9],p=o[2],d=o[6],f=o[10];if(Math.abs(s-u)<.01&&Math.abs(c-p)<.01&&Math.abs(l-d)<.01){if(Math.abs(s+u)<.1&&Math.abs(c+p)<.1&&Math.abs(l+d)<.1&&Math.abs(a+h+f-3)<.1)return this.set(1,0,0,0),this;e=Math.PI;var m=(a+1)/2,g=(h+1)/2,v=(f+1)/2,y=(s+u)/4,b=(c+p)/4,x=(l+d)/4;return m>g&&m>v?m<.01?(i=0,r=.707106781,n=.707106781):(r=y/(i=Math.sqrt(m)),n=b/i):g>v?g<.01?(i=.707106781,r=0,n=.707106781):(i=y/(r=Math.sqrt(g)),n=x/r):v<.01?(i=.707106781,r=.707106781,n=0):(i=b/(n=Math.sqrt(v)),r=x/n),this.set(i,r,n,e),this}var _=Math.sqrt((d-l)*(d-l)+(c-p)*(c-p)+(u-s)*(u-s));return Math.abs(_)<.001&&(_=1),this.x=(d-l)/_,this.y=(c-p)/_,this.z=(u-s)/_,this.w=Math.acos((a+h+f-1)/2),this},min:function(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this.w=Math.min(this.w,t.w),this},max:function(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this.w=Math.max(this.w,t.w),this},clamp:function(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this.z=Math.max(t.z,Math.min(e.z,this.z)),this.w=Math.max(t.w,Math.min(e.w,this.w)),this},clampScalar:function(){var t=new d,e=new d;return function(i,r){return t.set(i,i,i,i),e.set(r,r,r,r),this.clamp(t,e)}}(),floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this.w=Math.floor(this.w),this},ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this.w=Math.ceil(this.w),this},round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this.w=Math.round(this.w),this},roundToZero:function(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this.w=this.w<0?Math.ceil(this.w):Math.floor(this.w),this},negate:function(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this.w=-this.w,this},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z+this.w*t.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(t){return this.multiplyScalar(t/this.length())},lerp:function(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this.w+=(t.w-this.w)*e,this},lerpVectors:function(t,e,i){return this.subVectors(e,t).multiplyScalar(i).add(t)},equals:function(t){return t.x===this.x&&t.y===this.y&&t.z===this.z&&t.w===this.w},fromArray:function(t,e){return void 0===e&&(e=0),this.x=t[e],this.y=t[e+1],this.z=t[e+2],this.w=t[e+3],this},toArray:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=0),t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t[e+3]=this.w,t},fromBufferAttribute:function(t,e,i){return void 0!==i&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute()."),this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this.w=t.getW(e),this}}),Object.assign(f.prototype,h.prototype,{isWebGLRenderTarget:!0,setSize:function(t,e){this.width===t&&this.height===e||(this.width=t,this.height=e,this.dispose()),this.viewport.set(0,0,t,e),this.scissor.set(0,0,t,e)},clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.width=t.width,this.height=t.height,this.viewport.copy(t.viewport),this.texture=t.texture.clone(),this.depthBuffer=t.depthBuffer,this.stencilBuffer=t.stencilBuffer,this.depthTexture=t.depthTexture,this},dispose:function(){this.dispatchEvent({type:"dispose"})}}),Object.assign(m,{slerp:function(t,e,i,r){return i.copy(t).slerp(e,r)},slerpFlat:function(t,e,i,r,n,o,a){var s=i[r+0],c=i[r+1],u=i[r+2],h=i[r+3],l=n[o+0],p=n[o+1],d=n[o+2],f=n[o+3];if(h!==f||s!==l||c!==p||u!==d){var m=1-a,g=s*l+c*p+u*d+h*f,v=g>=0?1:-1,y=1-g*g;if(y>Number.EPSILON){var b=Math.sqrt(y),x=Math.atan2(b,g*v);m=Math.sin(m*x)/b,a=Math.sin(a*x)/b}var _=a*v;if(s=s*m+l*_,c=c*m+p*_,u=u*m+d*_,h=h*m+f*_,m===1-a){var w=1/Math.sqrt(s*s+c*c+u*u+h*h);s*=w,c*=w,u*=w,h*=w}}t[e]=s,t[e+1]=c,t[e+2]=u,t[e+3]=h}}),Object.defineProperties(m.prototype,{x:{get:function(){return this._x},set:function(t){this._x=t,this.onChangeCallback()}},y:{get:function(){return this._y},set:function(t){this._y=t,this.onChangeCallback()}},z:{get:function(){return this._z},set:function(t){this._z=t,this.onChangeCallback()}},w:{get:function(){return this._w},set:function(t){this._w=t,this.onChangeCallback()}}}),Object.assign(m.prototype,{set:function(t,e,i,r){return this._x=t,this._y=e,this._z=i,this._w=r,this.onChangeCallback(),this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(t){return this._x=t.x,this._y=t.y,this._z=t.z,this._w=t.w,this.onChangeCallback(),this},setFromEuler:function(t,e){if(!1===(t&&t.isEuler))throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var i=t._x,r=t._y,n=t._z,o=t.order,a=Math.cos,s=Math.sin,c=a(i/2),u=a(r/2),h=a(n/2),l=s(i/2),p=s(r/2),d=s(n/2);return"XYZ"===o?(this._x=l*u*h+c*p*d,this._y=c*p*h-l*u*d,this._z=c*u*d+l*p*h,this._w=c*u*h-l*p*d):"YXZ"===o?(this._x=l*u*h+c*p*d,this._y=c*p*h-l*u*d,this._z=c*u*d-l*p*h,this._w=c*u*h+l*p*d):"ZXY"===o?(this._x=l*u*h-c*p*d,this._y=c*p*h+l*u*d,this._z=c*u*d+l*p*h,this._w=c*u*h-l*p*d):"ZYX"===o?(this._x=l*u*h-c*p*d,this._y=c*p*h+l*u*d,this._z=c*u*d-l*p*h,this._w=c*u*h+l*p*d):"YZX"===o?(this._x=l*u*h+c*p*d,this._y=c*p*h+l*u*d,this._z=c*u*d-l*p*h,this._w=c*u*h-l*p*d):"XZY"===o&&(this._x=l*u*h-c*p*d,this._y=c*p*h-l*u*d,this._z=c*u*d+l*p*h,this._w=c*u*h+l*p*d),!1!==e&&this.onChangeCallback(),this},setFromAxisAngle:function(t,e){var i=e/2,r=Math.sin(i);return this._x=t.x*r,this._y=t.y*r,this._z=t.z*r,this._w=Math.cos(i),this.onChangeCallback(),this},setFromRotationMatrix:function(t){var e,i=t.elements,r=i[0],n=i[4],o=i[8],a=i[1],s=i[5],c=i[9],u=i[2],h=i[6],l=i[10],p=r+s+l;return p>0?(e=.5/Math.sqrt(p+1),this._w=.25/e,this._x=(h-c)*e,this._y=(o-u)*e,this._z=(a-n)*e):r>s&&r>l?(e=2*Math.sqrt(1+r-s-l),this._w=(h-c)/e,this._x=.25*e,this._y=(n+a)/e,this._z=(o+u)/e):s>l?(e=2*Math.sqrt(1+s-r-l),this._w=(o-u)/e,this._x=(n+a)/e,this._y=.25*e,this._z=(c+h)/e):(e=2*Math.sqrt(1+l-r-s),this._w=(a-n)/e,this._x=(o+u)/e,this._y=(c+h)/e,this._z=.25*e),this.onChangeCallback(),this},setFromUnitVectors:function(){var t,e=new g;return function(i,r){return void 0===e&&(e=new g),t=i.dot(r)+1,t<1e-6?(t=0,Math.abs(i.x)>Math.abs(i.z)?e.set(-i.y,i.x,0):e.set(0,-i.z,i.y)):e.crossVectors(i,r),this._x=e.x,this._y=e.y,this._z=e.z,this._w=t,this.normalize()}}(),inverse:function(){return this.conjugate().normalize()},conjugate:function(){return this._x*=-1,this._y*=-1,this._z*=-1,this.onChangeCallback(),this},dot:function(t){return this._x*t._x+this._y*t._y+this._z*t._z+this._w*t._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var t=this.length();return 0===t?(this._x=0,this._y=0,this._z=0,this._w=1):(t=1/t,this._x=this._x*t,this._y=this._y*t,this._z=this._z*t,this._w=this._w*t),this.onChangeCallback(),this},multiply:function(t,e){return void 0!==e?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(t,e)):this.multiplyQuaternions(this,t)},premultiply:function(t){return this.multiplyQuaternions(t,this)},multiplyQuaternions:function(t,e){var i=t._x,r=t._y,n=t._z,o=t._w,a=e._x,s=e._y,c=e._z,u=e._w;return this._x=i*u+o*a+r*c-n*s,this._y=r*u+o*s+n*a-i*c,this._z=n*u+o*c+i*s-r*a,this._w=o*u-i*a-r*s-n*c,this.onChangeCallback(),this},slerp:function(t,e){if(0===e)return this;if(1===e)return this.copy(t);var i=this._x,r=this._y,n=this._z,o=this._w,a=o*t._w+i*t._x+r*t._y+n*t._z;if(a<0?(this._w=-t._w,this._x=-t._x,this._y=-t._y,this._z=-t._z,a=-a):this.copy(t),a>=1)return this._w=o,this._x=i,this._y=r,this._z=n,this;var s=Math.sqrt(1-a*a);if(Math.abs(s)<.001)return this._w=.5*(o+this._w),this._x=.5*(i+this._x),this._y=.5*(r+this._y),this._z=.5*(n+this._z),this;var c=Math.atan2(s,a),u=Math.sin((1-e)*c)/s,h=Math.sin(e*c)/s;return this._w=o*u+this._w*h,this._x=i*u+this._x*h,this._y=r*u+this._y*h,this._z=n*u+this._z*h,this.onChangeCallback(),this},equals:function(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._w===this._w},fromArray:function(t,e){return void 0===e&&(e=0),this._x=t[e],this._y=t[e+1],this._z=t[e+2],this._w=t[e+3],this.onChangeCallback(),this},toArray:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=0),t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._w,t},onChange:function(t){return this.onChangeCallback=t,this},onChangeCallback:function(){}}),Object.assign(g.prototype,{isVector3:!0,set:function(t,e,i){return this.x=t,this.y=e,this.z=i,this},setScalar:function(t){return this.x=t,this.y=t,this.z=t,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setZ:function(t){return this.z=t,this},setComponent:function(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;default:throw new Error("index is out of range: "+t)}return this},getComponent:function(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+t)}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this},add:function(t,e){return void 0!==e?(console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(t,e)):(this.x+=t.x,this.y+=t.y,this.z+=t.z,this)},addScalar:function(t){return this.x+=t,this.y+=t,this.z+=t,this},addVectors:function(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this},addScaledVector:function(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this},sub:function(t,e){return void 0!==e?(console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(t,e)):(this.x-=t.x,this.y-=t.y,this.z-=t.z,this)},subScalar:function(t){return this.x-=t,this.y-=t,this.z-=t,this},subVectors:function(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this},multiply:function(t,e){return void 0!==e?(console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(t,e)):(this.x*=t.x,this.y*=t.y,this.z*=t.z,this)},multiplyScalar:function(t){return this.x*=t,this.y*=t,this.z*=t,this},multiplyVectors:function(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this},applyEuler:function(){var t=new m;return function(e){return!1===(e&&e.isEuler)&&console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order."),this.applyQuaternion(t.setFromEuler(e))}}(),applyAxisAngle:function(){var t=new m;return function(e,i){return this.applyQuaternion(t.setFromAxisAngle(e,i))}}(),applyMatrix3:function(t){var e=this.x,i=this.y,r=this.z,n=t.elements;return this.x=n[0]*e+n[3]*i+n[6]*r,this.y=n[1]*e+n[4]*i+n[7]*r,this.z=n[2]*e+n[5]*i+n[8]*r,this},applyMatrix4:function(t){var e=this.x,i=this.y,r=this.z,n=t.elements;this.x=n[0]*e+n[4]*i+n[8]*r+n[12],this.y=n[1]*e+n[5]*i+n[9]*r+n[13],this.z=n[2]*e+n[6]*i+n[10]*r+n[14];var o=n[3]*e+n[7]*i+n[11]*r+n[15];return this.divideScalar(o)},applyQuaternion:function(t){var e=this.x,i=this.y,r=this.z,n=t.x,o=t.y,a=t.z,s=t.w,c=s*e+o*r-a*i,u=s*i+a*e-n*r,h=s*r+n*i-o*e,l=-n*e-o*i-a*r;return this.x=c*s+l*-n+u*-a-h*-o,this.y=u*s+l*-o+h*-n-c*-a,this.z=h*s+l*-a+c*-o-u*-n,this},project:function(){var t=new v;return function(e){return t.multiplyMatrices(e.projectionMatrix,t.getInverse(e.matrixWorld)),this.applyMatrix4(t)}}(),unproject:function(){var t=new v;return function(e){return t.multiplyMatrices(e.matrixWorld,t.getInverse(e.projectionMatrix)),this.applyMatrix4(t)}}(),transformDirection:function(t){var e=this.x,i=this.y,r=this.z,n=t.elements;return this.x=n[0]*e+n[4]*i+n[8]*r,this.y=n[1]*e+n[5]*i+n[9]*r,this.z=n[2]*e+n[6]*i+n[10]*r,this.normalize()},divide:function(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this},divideScalar:function(t){return this.multiplyScalar(1/t)},min:function(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this},max:function(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this},clamp:function(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this.z=Math.max(t.z,Math.min(e.z,this.z)),this},clampScalar:function(){var t=new g,e=new g;return function(i,r){return t.set(i,i,i),e.set(r,r,r),this.clamp(t,e)}}(),clampLength:function(t,e){var i=this.length();return this.multiplyScalar(Math.max(t,Math.min(e,i))/i)},floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this},ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this},round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this},roundToZero:function(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this},negate:function(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(t){return this.multiplyScalar(t/this.length())},lerp:function(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this},lerpVectors:function(t,e,i){return this.subVectors(e,t).multiplyScalar(i).add(t)},cross:function(t,e){if(void 0!==e)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(t,e);var i=this.x,r=this.y,n=this.z;return this.x=r*t.z-n*t.y,this.y=n*t.x-i*t.z,this.z=i*t.y-r*t.x,this},crossVectors:function(t,e){var i=t.x,r=t.y,n=t.z,o=e.x,a=e.y,s=e.z;return this.x=r*s-n*a,this.y=n*o-i*s,this.z=i*a-r*o,this},projectOnVector:function(t){var e=t.dot(this)/t.lengthSq();return this.copy(t).multiplyScalar(e)},projectOnPlane:function(){var t=new g;return function(e){return t.copy(this).projectOnVector(e),this.sub(t)}}(),reflect:function(){var t=new g;return function(e){return this.sub(t.copy(e).multiplyScalar(2*this.dot(e)))}}(),angleTo:function(t){var e=this.dot(t)/Math.sqrt(this.lengthSq()*t.lengthSq());return Math.acos(xl.clamp(e,-1,1))},distanceTo:function(t){return Math.sqrt(this.distanceToSquared(t))},distanceToSquared:function(t){var e=this.x-t.x,i=this.y-t.y,r=this.z-t.z;return e*e+i*i+r*r},distanceToManhattan:function(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)+Math.abs(this.z-t.z)},setFromSpherical:function(t){var e=Math.sin(t.phi)*t.radius;return this.x=e*Math.sin(t.theta),this.y=Math.cos(t.phi)*t.radius,this.z=e*Math.cos(t.theta),this},setFromCylindrical:function(t){return this.x=t.radius*Math.sin(t.theta),this.y=t.y,this.z=t.radius*Math.cos(t.theta),this},setFromMatrixPosition:function(t){return this.setFromMatrixColumn(t,3)},setFromMatrixScale:function(t){var e=this.setFromMatrixColumn(t,0).length(),i=this.setFromMatrixColumn(t,1).length(),r=this.setFromMatrixColumn(t,2).length();return this.x=e,this.y=i,this.z=r,this},setFromMatrixColumn:function(t,e){return this.fromArray(t.elements,4*e)},equals:function(t){return t.x===this.x&&t.y===this.y&&t.z===this.z},fromArray:function(t,e){return void 0===e&&(e=0),this.x=t[e],this.y=t[e+1],this.z=t[e+2],this},toArray:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=0),t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t},fromBufferAttribute:function(t,e,i){return void 0!==i&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute()."),this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}}),Object.assign(v.prototype,{isMatrix4:!0,set:function(t,e,i,r,n,o,a,s,c,u,h,l,p,d,f,m){var g=this.elements;return g[0]=t,g[4]=e,g[8]=i,g[12]=r,g[1]=n,g[5]=o,g[9]=a,g[13]=s,g[2]=c,g[6]=u,g[10]=h,g[14]=l,g[3]=p,g[7]=d,g[11]=f,g[15]=m,this},identity:function(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this},clone:function(){return(new v).fromArray(this.elements)},copy:function(t){var e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],e[9]=i[9],e[10]=i[10],e[11]=i[11],e[12]=i[12],e[13]=i[13],e[14]=i[14],e[15]=i[15],this},copyPosition:function(t){var e=this.elements,i=t.elements;return e[12]=i[12],e[13]=i[13],e[14]=i[14],this},extractBasis:function(t,e,i){return t.setFromMatrixColumn(this,0),e.setFromMatrixColumn(this,1),i.setFromMatrixColumn(this,2),this},makeBasis:function(t,e,i){return this.set(t.x,e.x,i.x,0,t.y,e.y,i.y,0,t.z,e.z,i.z,0,0,0,0,1),this},extractRotation:function(){var t=new g;return function(e){var i=this.elements,r=e.elements,n=1/t.setFromMatrixColumn(e,0).length(),o=1/t.setFromMatrixColumn(e,1).length(),a=1/t.setFromMatrixColumn(e,2).length();return i[0]=r[0]*n,i[1]=r[1]*n,i[2]=r[2]*n,i[4]=r[4]*o,i[5]=r[5]*o,i[6]=r[6]*o,i[8]=r[8]*a,i[9]=r[9]*a,i[10]=r[10]*a,this}}(),makeRotationFromEuler:function(t){!1===(t&&t.isEuler)&&console.error("THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var e=this.elements,i=t.x,r=t.y,n=t.z,o=Math.cos(i),a=Math.sin(i),s=Math.cos(r),c=Math.sin(r),u=Math.cos(n),h=Math.sin(n);if("XYZ"===t.order){var l=o*u,p=o*h,d=a*u,f=a*h;e[0]=s*u,e[4]=-s*h,e[8]=c,e[1]=p+d*c,e[5]=l-f*c,e[9]=-a*s,e[2]=f-l*c,e[6]=d+p*c,e[10]=o*s}else if("YXZ"===t.order){var m=s*u,g=s*h,v=c*u,y=c*h;e[0]=m+y*a,e[4]=v*a-g,e[8]=o*c,e[1]=o*h,e[5]=o*u,e[9]=-a,e[2]=g*a-v,e[6]=y+m*a,e[10]=o*s}else if("ZXY"===t.order){var m=s*u,g=s*h,v=c*u,y=c*h;e[0]=m-y*a,e[4]=-o*h,e[8]=v+g*a,e[1]=g+v*a,e[5]=o*u,e[9]=y-m*a,e[2]=-o*c,e[6]=a,e[10]=o*s}else if("ZYX"===t.order){var l=o*u,p=o*h,d=a*u,f=a*h;e[0]=s*u,e[4]=d*c-p,e[8]=l*c+f,e[1]=s*h,e[5]=f*c+l,e[9]=p*c-d,e[2]=-c,e[6]=a*s,e[10]=o*s}else if("YZX"===t.order){var b=o*s,x=o*c,_=a*s,w=a*c;e[0]=s*u,e[4]=w-b*h,e[8]=_*h+x,e[1]=h,e[5]=o*u,e[9]=-a*u,e[2]=-c*u,e[6]=x*h+_,e[10]=b-w*h}else if("XZY"===t.order){var b=o*s,x=o*c,_=a*s,w=a*c;e[0]=s*u,e[4]=-h,e[8]=c*u,e[1]=b*h+w,e[5]=o*u,e[9]=x*h-_,e[2]=_*h-x,e[6]=a*u,e[10]=w*h+b}return e[3]=0,e[7]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this},makeRotationFromQuaternion:function(t){var e=this.elements,i=t._x,r=t._y,n=t._z,o=t._w,a=i+i,s=r+r,c=n+n,u=i*a,h=i*s,l=i*c,p=r*s,d=r*c,f=n*c,m=o*a,g=o*s,v=o*c;return e[0]=1-(p+f),e[4]=h-v,e[8]=l+g,e[1]=h+v,e[5]=1-(u+f),e[9]=d-m,e[2]=l-g,e[6]=d+m,e[10]=1-(u+p),e[3]=0,e[7]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this},lookAt:function(){var t=new g,e=new g,i=new g;return function(r,n,o){var a=this.elements;return i.subVectors(r,n),0===i.lengthSq()&&(i.z=1),i.normalize(),t.crossVectors(o,i),0===t.lengthSq()&&(i.z+=1e-4,t.crossVectors(o,i)),t.normalize(),e.crossVectors(i,t),a[0]=t.x,a[4]=e.x,a[8]=i.x,a[1]=t.y,a[5]=e.y,a[9]=i.y,a[2]=t.z,a[6]=e.z,a[10]=i.z,this}}(),multiply:function(t,e){return void 0!==e?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(t,e)):this.multiplyMatrices(this,t)},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.elements,r=e.elements,n=this.elements,o=i[0],a=i[4],s=i[8],c=i[12],u=i[1],h=i[5],l=i[9],p=i[13],d=i[2],f=i[6],m=i[10],g=i[14],v=i[3],y=i[7],b=i[11],x=i[15],_=r[0],w=r[4],S=r[8],A=r[12],M=r[1],P=r[5],T=r[9],E=r[13],C=r[2],I=r[6],L=r[10],R=r[14],O=r[3],D=r[7],N=r[11],k=r[15];return n[0]=o*_+a*M+s*C+c*O,n[4]=o*w+a*P+s*I+c*D,n[8]=o*S+a*T+s*L+c*N,n[12]=o*A+a*E+s*R+c*k,n[1]=u*_+h*M+l*C+p*O,n[5]=u*w+h*P+l*I+p*D,n[9]=u*S+h*T+l*L+p*N,n[13]=u*A+h*E+l*R+p*k,n[2]=d*_+f*M+m*C+g*O,n[6]=d*w+f*P+m*I+g*D,n[10]=d*S+f*T+m*L+g*N,n[14]=d*A+f*E+m*R+g*k,n[3]=v*_+y*M+b*C+x*O,n[7]=v*w+y*P+b*I+x*D,n[11]=v*S+y*T+b*L+x*N,n[15]=v*A+y*E+b*R+x*k,this},multiplyScalar:function(t){var e=this.elements;return e[0]*=t,e[4]*=t,e[8]*=t,e[12]*=t,e[1]*=t,e[5]*=t,e[9]*=t,e[13]*=t,e[2]*=t,e[6]*=t,e[10]*=t,e[14]*=t,e[3]*=t,e[7]*=t,e[11]*=t,e[15]*=t,this},applyToBufferAttribute:function(){var t=new g;return function(e){for(var i=this,r=0,n=e.count;r<n;r++)t.x=e.getX(r),t.y=e.getY(r),t.z=e.getZ(r),t.applyMatrix4(i),e.setXYZ(r,t.x,t.y,t.z);return e}}(),determinant:function(){var t=this.elements,e=t[0],i=t[4],r=t[8],n=t[12],o=t[1],a=t[5],s=t[9],c=t[13],u=t[2],h=t[6],l=t[10],p=t[14];return t[3]*(+n*s*h-r*c*h-n*a*l+i*c*l+r*a*p-i*s*p)+t[7]*(+e*s*p-e*c*l+n*o*l-r*o*p+r*c*u-n*s*u)+t[11]*(+e*c*h-e*a*p-n*o*h+i*o*p+n*a*u-i*c*u)+t[15]*(-r*a*u-e*s*h+e*a*l+r*o*h-i*o*l+i*s*u)},transpose:function(){var t,e=this.elements;return t=e[1],e[1]=e[4],e[4]=t,t=e[2],e[2]=e[8],e[8]=t,t=e[6],e[6]=e[9],e[9]=t,t=e[3],e[3]=e[12],e[12]=t,t=e[7],e[7]=e[13],e[13]=t,t=e[11],e[11]=e[14],e[14]=t,this},setPosition:function(t){var e=this.elements;return e[12]=t.x,e[13]=t.y,e[14]=t.z,this},getInverse:function(t,e){var i=this.elements,r=t.elements,n=r[0],o=r[1],a=r[2],s=r[3],c=r[4],u=r[5],h=r[6],l=r[7],p=r[8],d=r[9],f=r[10],m=r[11],g=r[12],v=r[13],y=r[14],b=r[15],x=d*y*l-v*f*l+v*h*m-u*y*m-d*h*b+u*f*b,_=g*f*l-p*y*l-g*h*m+c*y*m+p*h*b-c*f*b,w=p*v*l-g*d*l+g*u*m-c*v*m-p*u*b+c*d*b,S=g*d*h-p*v*h-g*u*f+c*v*f+p*u*y-c*d*y,A=n*x+o*_+a*w+s*S;if(0===A){var M="THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0";if(!0===e)throw new Error(M);return console.warn(M),this.identity()}var P=1/A;return i[0]=x*P,i[1]=(v*f*s-d*y*s-v*a*m+o*y*m+d*a*b-o*f*b)*P,i[2]=(u*y*s-v*h*s+v*a*l-o*y*l-u*a*b+o*h*b)*P,i[3]=(d*h*s-u*f*s-d*a*l+o*f*l+u*a*m-o*h*m)*P,i[4]=_*P,i[5]=(p*y*s-g*f*s+g*a*m-n*y*m-p*a*b+n*f*b)*P,i[6]=(g*h*s-c*y*s-g*a*l+n*y*l+c*a*b-n*h*b)*P,i[7]=(c*f*s-p*h*s+p*a*l-n*f*l-c*a*m+n*h*m)*P,i[8]=w*P,i[9]=(g*d*s-p*v*s-g*o*m+n*v*m+p*o*b-n*d*b)*P,i[10]=(c*v*s-g*u*s+g*o*l-n*v*l-c*o*b+n*u*b)*P,i[11]=(p*u*s-c*d*s-p*o*l+n*d*l+c*o*m-n*u*m)*P,i[12]=S*P,i[13]=(p*v*a-g*d*a+g*o*f-n*v*f-p*o*y+n*d*y)*P,i[14]=(g*u*a-c*v*a-g*o*h+n*v*h+c*o*y-n*u*y)*P,i[15]=(c*d*a-p*u*a+p*o*h-n*d*h-c*o*f+n*u*f)*P,this},scale:function(t){var e=this.elements,i=t.x,r=t.y,n=t.z;return e[0]*=i,e[4]*=r,e[8]*=n,e[1]*=i,e[5]*=r,e[9]*=n,e[2]*=i,e[6]*=r,e[10]*=n,e[3]*=i,e[7]*=r,e[11]*=n,this},getMaxScaleOnAxis:function(){var t=this.elements,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],r=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,r))},makeTranslation:function(t,e,i){return this.set(1,0,0,t,0,1,0,e,0,0,1,i,0,0,0,1),this},makeRotationX:function(t){var e=Math.cos(t),i=Math.sin(t);return this.set(1,0,0,0,0,e,-i,0,0,i,e,0,0,0,0,1),this},makeRotationY:function(t){var e=Math.cos(t),i=Math.sin(t);return this.set(e,0,i,0,0,1,0,0,-i,0,e,0,0,0,0,1),this},makeRotationZ:function(t){var e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1),this},makeRotationAxis:function(t,e){var i=Math.cos(e),r=Math.sin(e),n=1-i,o=t.x,a=t.y,s=t.z,c=n*o,u=n*a;return this.set(c*o+i,c*a-r*s,c*s+r*a,0,c*a+r*s,u*a+i,u*s-r*o,0,c*s-r*a,u*s+r*o,n*s*s+i,0,0,0,0,1),this},makeScale:function(t,e,i){return this.set(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1),this},makeShear:function(t,e,i){return this.set(1,e,i,0,t,1,i,0,t,e,1,0,0,0,0,1),this},compose:function(t,e,i){return this.makeRotationFromQuaternion(e),this.scale(i),this.setPosition(t),this},decompose:function(){var t=new g,e=new v;return function(i,r,n){var o=this.elements,a=t.set(o[0],o[1],o[2]).length(),s=t.set(o[4],o[5],o[6]).length(),c=t.set(o[8],o[9],o[10]).length();this.determinant()<0&&(a=-a),i.x=o[12],i.y=o[13],i.z=o[14],e.copy(this);var u=1/a,h=1/s,l=1/c;return e.elements[0]*=u,e.elements[1]*=u,e.elements[2]*=u,e.elements[4]*=h,e.elements[5]*=h,e.elements[6]*=h,e.elements[8]*=l,e.elements[9]*=l,e.elements[10]*=l,r.setFromRotationMatrix(e),n.x=a,n.y=s,n.z=c,this}}(),makePerspective:function(t,e,i,r,n,o){void 0===o&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.");var a=this.elements,s=2*n/(e-t),c=2*n/(i-r),u=(e+t)/(e-t),h=(i+r)/(i-r),l=-(o+n)/(o-n),p=-2*o*n/(o-n);return a[0]=s,a[4]=0,a[8]=u,a[12]=0,a[1]=0,a[5]=c,a[9]=h,a[13]=0,a[2]=0,a[6]=0,a[10]=l,a[14]=p,a[3]=0,a[7]=0,a[11]=-1,a[15]=0,this},makeOrthographic:function(t,e,i,r,n,o){var a=this.elements,s=1/(e-t),c=1/(i-r),u=1/(o-n),h=(e+t)*s,l=(i+r)*c,p=(o+n)*u;return a[0]=2*s,a[4]=0,a[8]=0,a[12]=-h,a[1]=0,a[5]=2*c,a[9]=0,a[13]=-l,a[2]=0,a[6]=0,a[10]=-2*u,a[14]=-p,a[3]=0,a[7]=0,a[11]=0,a[15]=1,this},equals:function(t){for(var e=this.elements,i=t.elements,r=0;r<16;r++)if(e[r]!==i[r])return!1;return!0},fromArray:function(t,e){var i=this;void 0===e&&(e=0);for(var r=0;r<16;r++)i.elements[r]=t[r+e];return this},toArray:function(t,e){void 0===t&&(t=[]),void 0===e&&(e=0);var i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t[e+9]=i[9],t[e+10]=i[10],t[e+11]=i[11],t[e+12]=i[12],t[e+13]=i[13],t[e+14]=i[14],t[e+15]=i[15],t}}),y.prototype=Object.create(p.prototype),y.prototype.constructor=y,y.prototype.isDataTexture=!0,b.prototype=Object.create(p.prototype),b.prototype.constructor=b,b.prototype.isCubeTexture=!0,Object.defineProperty(b.prototype,"images",{get:function(){return this.image},set:function(t){this.image=t}});var wl=new p,Sl=new b,Al=[],Ml=[],Pl=new Float32Array(16),Tl=new Float32Array(9);Z.prototype.setValue=function(t,e){for(var i=this.seq,r=0,n=i.length;r!==n;++r){var o=i[r];o.setValue(t,e[o.id])}};var El=/([\w\d_]+)(\])?(\[|\.)?/g;J.prototype.setValue=function(t,e,i){var r=this.map[e];void 0!==r&&r.setValue(t,i,this.renderer)},J.prototype.setOptional=function(t,e,i){var r=e[i];void 0!==r&&this.setValue(t,i,r)},J.upload=function(t,e,i,r){for(var n=0,o=e.length;n!==o;++n){var a=e[n],s=i[a.id];!1!==s.needsUpdate&&a.setValue(t,s.value,r)}},J.seqWithValue=function(t,e){for(var i=[],r=0,n=t.length;r!==n;++r){var o=t[r];o.id in e&&i.push(o)}return i};var Cl={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Object.assign(tt.prototype,{isColor:!0,r:1,g:1,b:1,set:function(t){return t&&t.isColor?this.copy(t):"number"==typeof t?this.setHex(t):"string"==typeof t&&this.setStyle(t),this},setScalar:function(t){return this.r=t,this.g=t,this.b=t,this},setHex:function(t){return t=Math.floor(t),this.r=(t>>16&255)/255,this.g=(t>>8&255)/255,this.b=(255&t)/255,this},setRGB:function(t,e,i){return this.r=t,this.g=e,this.b=i,this},setHSL:function(){function t(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+6*(e-t)*(2/3-i):t}return function(e,i,r){if(e=xl.euclideanModulo(e,1),i=xl.clamp(i,0,1),r=xl.clamp(r,0,1),0===i)this.r=this.g=this.b=r;else{var n=r<=.5?r*(1+i):r+i-r*i,o=2*r-n;this.r=t(o,n,e+1/3),this.g=t(o,n,e),this.b=t(o,n,e-1/3)}return this}}(),setStyle:function(t){function e(e){void 0!==e&&parseFloat(e)<1&&console.warn("THREE.Color: Alpha component of "+t+" will be ignored.")}var i;if(i=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(t)){var r,n=i[1],o=i[2];switch(n){case"rgb":case"rgba":if(r=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(o))return this.r=Math.min(255,parseInt(r[1],10))/255,this.g=Math.min(255,parseInt(r[2],10))/255,this.b=Math.min(255,parseInt(r[3],10))/255,e(r[5]),this;if(r=/^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(o))return this.r=Math.min(100,parseInt(r[1],10))/100,this.g=Math.min(100,parseInt(r[2],10))/100,this.b=Math.min(100,parseInt(r[3],10))/100,e(r[5]),this;break;case"hsl":case"hsla":if(r=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(o)){var a=parseFloat(r[1])/360,s=parseInt(r[2],10)/100,c=parseInt(r[3],10)/100;return e(r[5]),this.setHSL(a,s,c)}}}else if(i=/^\#([A-Fa-f0-9]+)$/.exec(t)){var u=(h=i[1]).length;if(3===u)return this.r=parseInt(h.charAt(0)+h.charAt(0),16)/255,this.g=parseInt(h.charAt(1)+h.charAt(1),16)/255,this.b=parseInt(h.charAt(2)+h.charAt(2),16)/255,this;if(6===u)return this.r=parseInt(h.charAt(0)+h.charAt(1),16)/255,this.g=parseInt(h.charAt(2)+h.charAt(3),16)/255,this.b=parseInt(h.charAt(4)+h.charAt(5),16)/255,this}if(t&&t.length>0){var h=Cl[t];void 0!==h?this.setHex(h):console.warn("THREE.Color: Unknown color "+t)}return this},clone:function(){return new this.constructor(this.r,this.g,this.b)},copy:function(t){return this.r=t.r,this.g=t.g,this.b=t.b,this},copyGammaToLinear:function(t,e){return void 0===e&&(e=2),this.r=Math.pow(t.r,e),this.g=Math.pow(t.g,e),this.b=Math.pow(t.b,e),this},copyLinearToGamma:function(t,e){void 0===e&&(e=2);var i=e>0?1/e:1;return this.r=Math.pow(t.r,i),this.g=Math.pow(t.g,i),this.b=Math.pow(t.b,i),this},convertGammaToLinear:function(){var t=this.r,e=this.g,i=this.b;return this.r=t*t,this.g=e*e,this.b=i*i,this},convertLinearToGamma:function(){return this.r=Math.sqrt(this.r),this.g=Math.sqrt(this.g),this.b=Math.sqrt(this.b),this},getHex:function(){return 255*this.r<<16^255*this.g<<8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(t){var e,i,r=t||{h:0,s:0,l:0},n=this.r,o=this.g,a=this.b,s=Math.max(n,o,a),c=Math.min(n,o,a),u=(c+s)/2;if(c===s)e=0,i=0;else{var h=s-c;switch(i=u<=.5?h/(s+c):h/(2-s-c),s){case n:e=(o-a)/h+(o<a?6:0);break;case o:e=(a-n)/h+2;break;case a:e=(n-o)/h+4}e/=6}return r.h=e,r.s=i,r.l=u,r},getStyle:function(){return"rgb("+(255*this.r|0)+","+(255*this.g|0)+","+(255*this.b|0)+")"},offsetHSL:function(t,e,i){var r=this.getHSL();return r.h+=t,r.s+=e,r.l+=i,this.setHSL(r.h,r.s,r.l),this},add:function(t){return this.r+=t.r,this.g+=t.g,this.b+=t.b,this},addColors:function(t,e){return this.r=t.r+e.r,this.g=t.g+e.g,this.b=t.b+e.b,this},addScalar:function(t){return this.r+=t,this.g+=t,this.b+=t,this},sub:function(t){return this.r=Math.max(0,this.r-t.r),this.g=Math.max(0,this.g-t.g),this.b=Math.max(0,this.b-t.b),this},multiply:function(t){return this.r*=t.r,this.g*=t.g,this.b*=t.b,this},multiplyScalar:function(t){return this.r*=t,this.g*=t,this.b*=t,this},lerp:function(t,e){return this.r+=(t.r-this.r)*e,this.g+=(t.g-this.g)*e,this.b+=(t.b-this.b)*e,this},equals:function(t){return t.r===this.r&&t.g===this.g&&t.b===this.b},fromArray:function(t,e){return void 0===e&&(e=0),this.r=t[e],this.g=t[e+1],this.b=t[e+2],this},toArray:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=0),t[e]=this.r,t[e+1]=this.g,t[e+2]=this.b,t},toJSON:function(){return this.getHex()}});var Il={common:{diffuse:{value:new tt(15658734)},opacity:{value:1},map:{value:null},offsetRepeat:{value:new d(0,0,1,1)},specularMap:{value:null},alphaMap:{value:null},envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalScale:{value:new l(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new tt(16777215)}},lights:{ambientLightColor:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new tt(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},offsetRepeat:{value:new d(0,0,1,1)}}},Ll={merge:function(t){for(var e=this,i={},r=0;r<t.length;r++){var n=e.clone(t[r]);for(var o in n)i[o]=n[o]}return i},clone:function(t){var e={};for(var i in t){e[i]={};for(var r in t[i]){var n=t[i][r];n&&(n.isColor||n.isMatrix3||n.isMatrix4||n.isVector2||n.isVector3||n.isVector4||n.isTexture)?e[i][r]=n.clone():Array.isArray(n)?e[i][r]=n.slice():e[i][r]=n}}return e}},Rl={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n",aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"\nvec3 transformed = vec3( position );\n",beginnormal_vertex:"\nvec3 objectNormal = vec3( normal );\n",bsdfs:"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t\t}\n\t\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 ltcTextureCoords( const in GeometricContext geometry, const in float roughness ) {\n\tconst float LUT_SIZE  = 64.0;\n\tconst float LUT_SCALE = (LUT_SIZE - 1.0)/LUT_SIZE;\n\tconst float LUT_BIAS  = 0.5/LUT_SIZE;\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 P = geometry.position;\n\tfloat theta = acos( dot( N, V ) );\n\tvec2 uv = vec2(\n\t\tsqrt( saturate( roughness ) ),\n\t\tsaturate( theta / ( 0.5 * PI ) ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nvoid clipQuadToHorizon( inout vec3 L[5], out int n ) {\n\tint config = 0;\n\tif ( L[0].z > 0.0 ) config += 1;\n\tif ( L[1].z > 0.0 ) config += 2;\n\tif ( L[2].z > 0.0 ) config += 4;\n\tif ( L[3].z > 0.0 ) config += 8;\n\tn = 0;\n\tif ( config == 0 ) {\n\t} else if ( config == 1 ) {\n\t\tn = 3;\n\t\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\n\t\tL[2] = -L[3].z * L[0] + L[0].z * L[3];\n\t} else if ( config == 2 ) {\n\t\tn = 3;\n\t\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\n\t\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\n\t} else if ( config == 3 ) {\n\t\tn = 4;\n\t\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\n\t\tL[3] = -L[3].z * L[0] + L[0].z * L[3];\n\t} else if ( config == 4 ) {\n\t\tn = 3;\n\t\tL[0] = -L[3].z * L[2] + L[2].z * L[3];\n\t\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\n\t} else if ( config == 5 ) {\n\t\tn = 0;\n\t} else if ( config == 6 ) {\n\t\tn = 4;\n\t\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\n\t\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\n\t} else if ( config == 7 ) {\n\t\tn = 5;\n\t\tL[4] = -L[3].z * L[0] + L[0].z * L[3];\n\t\tL[3] = -L[3].z * L[2] + L[2].z * L[3];\n\t} else if ( config == 8 ) {\n\t\tn = 3;\n\t\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\n\t\tL[1] = -L[2].z * L[3] + L[3].z * L[2];\n\t\tL[2] =  L[3];\n\t} else if ( config == 9 ) {\n\t\tn = 4;\n\t\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\n\t\tL[2] = -L[2].z * L[3] + L[3].z * L[2];\n\t} else if ( config == 10 ) {\n\t\tn = 0;\n\t} else if ( config == 11 ) {\n\t\tn = 5;\n\t\tL[4] = L[3];\n\t\tL[3] = -L[2].z * L[3] + L[3].z * L[2];\n\t\tL[2] = -L[2].z * L[1] + L[1].z * L[2];\n\t} else if ( config == 12 ) {\n\t\tn = 4;\n\t\tL[1] = -L[1].z * L[2] + L[2].z * L[1];\n\t\tL[0] = -L[0].z * L[3] + L[3].z * L[0];\n\t} else if ( config == 13 ) {\n\t\tn = 5;\n\t\tL[4] = L[3];\n\t\tL[3] = L[2];\n\t\tL[2] = -L[1].z * L[2] + L[2].z * L[1];\n\t\tL[1] = -L[1].z * L[0] + L[0].z * L[1];\n\t} else if ( config == 14 ) {\n\t\tn = 5;\n\t\tL[4] = -L[0].z * L[3] + L[3].z * L[0];\n\t\tL[0] = -L[0].z * L[1] + L[1].z * L[0];\n\t} else if ( config == 15 ) {\n\t\tn = 4;\n\t}\n\tif ( n == 3 )\n\t\tL[3] = L[0];\n\tif ( n == 4 )\n\t\tL[4] = L[0];\n}\nfloat integrateLtcBrdfOverRectEdge( vec3 v1, vec3 v2 ) {\n\tfloat cosTheta = dot( v1, v2 );\n\tfloat theta = acos( cosTheta );\n\tfloat res = cross( v1, v2 ).z * ( ( theta > 0.001 ) ? theta / sin( theta ) : 1.0 );\n\treturn res;\n}\nvoid initRectPoints( const in vec3 pos, const in vec3 halfWidth, const in vec3 halfHeight, out vec3 rectPoints[4] ) {\n\trectPoints[0] = pos - halfWidth - halfHeight;\n\trectPoints[1] = pos + halfWidth - halfHeight;\n\trectPoints[2] = pos + halfWidth + halfHeight;\n\trectPoints[3] = pos - halfWidth + halfHeight;\n}\nvec3 integrateLtcBrdfOverRect( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 P = geometry.position;\n\tvec3 T1, T2;\n\tT1 = normalize(V - N * dot( V, N ));\n\tT2 = - cross( N, T1 );\n\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\n\tvec3 clippedRect[5];\n\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\n\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\n\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\n\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\n\tint n;\n\tclipQuadToHorizon(clippedRect, n);\n\tif ( n == 0 )\n\t\treturn vec3( 0, 0, 0 );\n\tclippedRect[0] = normalize( clippedRect[0] );\n\tclippedRect[1] = normalize( clippedRect[1] );\n\tclippedRect[2] = normalize( clippedRect[2] );\n\tclippedRect[3] = normalize( clippedRect[3] );\n\tclippedRect[4] = normalize( clippedRect[4] );\n\tfloat sum = 0.0;\n\tsum += integrateLtcBrdfOverRectEdge( clippedRect[0], clippedRect[1] );\n\tsum += integrateLtcBrdfOverRectEdge( clippedRect[1], clippedRect[2] );\n\tsum += integrateLtcBrdfOverRectEdge( clippedRect[2], clippedRect[3] );\n\tif (n >= 4)\n\t\tsum += integrateLtcBrdfOverRectEdge( clippedRect[3], clippedRect[4] );\n\tif (n == 5)\n\t\tsum += integrateLtcBrdfOverRectEdge( clippedRect[4], clippedRect[0] );\n\tsum = max( 0.0, sum );\n\tvec3 Lo_i = vec3( sum, sum, sum );\n\treturn Lo_i/(2.0 * PI);\n}\nfloat ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length(f);\n\treturn max((l*l + f.z)/(l+1.0), 0.0);\n}\nvec3 EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot(v1, v2);\n\tfloat y = abs(x);\n\tfloat a = 0.86267 + (0.49788 + 0.01436*y)*y;\n\tfloat b = 3.45068 + (4.18814 + y)*y;\n\tfloat v = a/b;\n\tfloat theta_sintheta = (x > 0.0) ? v : 0.5*inversesqrt(1.0 - x*x) - v;\n\treturn cross(v1, v2)*theta_sintheta;\n}\nvec3 integrateLtcBrdfOverRectOptimized( const in GeometricContext geometry, const in mat3 brdfMat, const in vec3 rectPoints[4] ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 P = geometry.position;\n\tvec3 T1, T2;\n\tT1 = normalize(V - N * dot( V, N ));\n\tT2 = - cross( N, T1 );\n\tmat3 brdfWrtSurface = brdfMat * transpose( mat3( T1, T2, N ) );\n\tvec3 clippedRect[4];\n\tclippedRect[0] = brdfWrtSurface * ( rectPoints[0] - P );\n\tclippedRect[1] = brdfWrtSurface * ( rectPoints[1] - P );\n\tclippedRect[2] = brdfWrtSurface * ( rectPoints[2] - P );\n\tclippedRect[3] = brdfWrtSurface * ( rectPoints[3] - P );\n\tvec3 v1 = clippedRect[1] - clippedRect[0];\n\tvec3 v2 = clippedRect[3] - clippedRect[0];\n\tvec3 lightNormal = cross(v1, v2);\n\tbool bSameSide = dot(lightNormal, clippedRect[0]) > 0.0;\n\tif( !bSameSide )\n\t\treturn vec3(0.0);\n\tclippedRect[0] = normalize( clippedRect[0] );\n\tclippedRect[1] = normalize( clippedRect[1] );\n\tclippedRect[2] = normalize( clippedRect[2] );\n\tclippedRect[3] = normalize( clippedRect[3] );\n\tvec3 edgeVectorFormFactor = vec3(0.0);\n\tedgeVectorFormFactor += EdgeVectorFormFactor( clippedRect[0], clippedRect[1] );\n\tedgeVectorFormFactor += EdgeVectorFormFactor( clippedRect[1], clippedRect[2] );\n\tedgeVectorFormFactor += EdgeVectorFormFactor( clippedRect[2], clippedRect[3] );\n\tedgeVectorFormFactor += EdgeVectorFormFactor( clippedRect[3], clippedRect[0] );\n\tvec3 Lo_i = vec3( ClippedSphereFormFactor( edgeVectorFormFactor ) );\n\treturn Lo_i;\n}\nvec3 Rect_Area_Light_Specular_Reflectance(\n\t\tconst in GeometricContext geometry,\n\t\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight,\n\t\tconst in float roughness,\n\t\tconst in sampler2D ltcMat, const in sampler2D ltcMag ) {\n\tvec3 rectPoints[4];\n\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\n\tvec2 uv = ltcTextureCoords( geometry, roughness );\n\tvec4 brdfLtcApproxParams, t;\n\tbrdfLtcApproxParams = texture2D( ltcMat, uv );\n\tt = texture2D( ltcMat, uv );\n\tfloat brdfLtcScalar = texture2D( ltcMag, uv ).a;\n\tmat3 brdfLtcApproxMat = mat3(\n\t\tvec3(   1,   0, t.y ),\n\t\tvec3(   0, t.z,   0 ),\n\t\tvec3( t.w,   0, t.x )\n\t);\n\tvec3 specularReflectance = integrateLtcBrdfOverRectOptimized( geometry, brdfLtcApproxMat, rectPoints );\n\tspecularReflectance *= brdfLtcScalar;\n\treturn specularReflectance;\n}\nvec3 Rect_Area_Light_Diffuse_Reflectance(\n\t\tconst in GeometricContext geometry,\n\t\tconst in vec3 lightPos, const in vec3 lightHalfWidth, const in vec3 lightHalfHeight ) {\n\tvec3 rectPoints[4];\n\tinitRectPoints( lightPos, lightHalfWidth, lightHalfHeight, rectPoints );\n\tmat3 diffuseBrdfMat = mat3(1);\n\tvec3 diffuseReflectance = integrateLtcBrdfOverRectOptimized( geometry, diffuseBrdfMat, rectPoints );\n\treturn diffuseReflectance;\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n",bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = dFdx( surf_pos );\n\t\tvec3 vSigmaY = dFdy( surf_pos );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n",clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\n\t\tvec4 plane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t\t\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\n\t\t\tvec4 plane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t\n\t#endif\n#endif\n",clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n",color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transpose( const in mat3 v ) {\n\tmat3 tmp;\n\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\n\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\n\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\n\treturn tmp;\n}\n",cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1  (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale =  bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n",defaultnormal_vertex:"#ifdef FLIP_SIDED\n\tobjectNormal = -objectNormal;\n#endif\nvec3 transformedNormal = normalMatrix * objectNormal;\n",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n",encodings_fragment:"  gl_FragColor = linearToOutputTexel( gl_FragColor );\n",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat M      = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM            = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat D      = max( maxRange / maxRGB, 1.0 );\n\tD            = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value )  {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract(Le);\n\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max(vRGB, 0.0), 1.0 );\n}\n",envmap_fragment:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n",envmap_pars_fragment:"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n",envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n",envmap_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n",fog_vertex:"\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n  varying float fogDepth;\n#endif\n",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n",gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n",lights_pars:"uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight  ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltcMat;\tuniform sampler2D ltcMag;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n",lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 matDiffColor = material.diffuseColor;\n\t\tvec3 matSpecColor = material.specularColor;\n\t\tvec3 lightColor   = rectAreaLight.color;\n\t\tfloat roughness = BlinnExponentToGGXRoughness( material.specularShininess );\n\t\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\n\t\t\t\troughness,\n\t\t\t\tltcMat, ltcMag );\n\t\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\n\t\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\n\t\treflectedLight.directDiffuse  += lightColor * matDiffColor * diff;\n\t}\n#endif\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n",lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n",lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 matDiffColor = material.diffuseColor;\n\t\tvec3 matSpecColor = material.specularColor;\n\t\tvec3 lightColor   = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 spec = Rect_Area_Light_Specular_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,\n\t\t\t\troughness,\n\t\t\t\tltcMat, ltcMag );\n\t\tvec3 diff = Rect_Area_Light_Diffuse_Reflectance(\n\t\t\t\tgeometry,\n\t\t\t\trectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );\n\t\treflectedLight.directSpecular += lightColor * matSpecColor * spec;\n\t\treflectedLight.directDiffuse  += lightColor * matDiffColor * diff;\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material )   GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material )   GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n",lights_template:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n\t#ifndef STANDARD\n\t\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\n\t#else\n\t\tvec3 clearCoatRadiance = vec3( 0.0 );\n\t#endif\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n",logdepthbuf_fragment:"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n",logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\t#endif\n#endif\n",map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n",map_particle_fragment:"#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n#endif\n",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n",normal_flip:"#ifdef DOUBLE_SIDED\n\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n#else\n\tfloat flipNormal = 1.0;\n#endif\n",normal_fragment:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal ) * flipNormal;\n#endif\n#ifdef USE_NORMALMAP\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n",normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n",premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n",project_vertex:"#ifdef USE_SKINNING\n\tvec4 mvPosition = modelViewMatrix * skinned;\n#else\n\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;\n",dithering_fragment:"#if defined( DITHERING )\n  gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n",dithering_pars_fragment:"#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\treturn (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn 1.0;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n",shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n",shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n",shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n",skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n",skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned  = bindMatrixInverse * skinned;\n#endif\n",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix  = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n",specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n  gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n",tonemapping_pars_fragment:"#define saturate(a) clamp( a, 0.0, 1.0 )\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n",uv_pars_fragment:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n#endif\n",uv_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif",uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\t#ifdef USE_SKINNING\n\t\tvec4 worldPosition = modelMatrix * skinned;\n\t#else\n\t\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n\t#endif\n#endif\n",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n",cube_vert:"varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n",depth_vert:"#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n}\n",distanceRGBA_frag:"uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include <common>\n#include <packing>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n",distanceRGBA_vert:"varying vec4 vWorldPosition;\n#include <common>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition;\n}\n",equirect_frag:"uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n",equirect_vert:"varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n",linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}\n",meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n",meshbasic_vert:"#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}\n",meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n",meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n",meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",meshphysical_frag:"#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n",meshphysical_vert:"#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n",normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <displacementmap_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n",points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n",points_vert:"uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",shadow_frag:"uniform float opacity;\n#include <common>\n#include <packing>\n#include <bsdfs>\n#include <lights_pars>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n",shadow_vert:"#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n}\n"},Ol={basic:{uniforms:Ll.merge([Il.common,Il.aomap,Il.lightmap,Il.fog]),vertexShader:Rl.meshbasic_vert,fragmentShader:Rl.meshbasic_frag},lambert:{uniforms:Ll.merge([Il.common,Il.aomap,Il.lightmap,Il.emissivemap,Il.fog,Il.lights,{emissive:{value:new tt(0)}}]),vertexShader:Rl.meshlambert_vert,fragmentShader:Rl.meshlambert_frag},phong:{uniforms:Ll.merge([Il.common,Il.aomap,Il.lightmap,Il.emissivemap,Il.bumpmap,Il.normalmap,Il.displacementmap,Il.gradientmap,Il.fog,Il.lights,{emissive:{value:new tt(0)},specular:{value:new tt(1118481)},shininess:{value:30}}]),vertexShader:Rl.meshphong_vert,fragmentShader:Rl.meshphong_frag},standard:{uniforms:Ll.merge([Il.common,Il.aomap,Il.lightmap,Il.emissivemap,Il.bumpmap,Il.normalmap,Il.displacementmap,Il.roughnessmap,Il.metalnessmap,Il.fog,Il.lights,{emissive:{value:new tt(0)},roughness:{value:.5},metalness:{value:.5},envMapIntensity:{value:1}}]),vertexShader:Rl.meshphysical_vert,fragmentShader:Rl.meshphysical_frag},points:{uniforms:Ll.merge([Il.points,Il.fog]),vertexShader:Rl.points_vert,fragmentShader:Rl.points_frag},dashed:{uniforms:Ll.merge([Il.common,Il.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:Rl.linedashed_vert,fragmentShader:Rl.linedashed_frag},depth:{uniforms:Ll.merge([Il.common,Il.displacementmap]),vertexShader:Rl.depth_vert,fragmentShader:Rl.depth_frag},normal:{uniforms:Ll.merge([Il.common,Il.bumpmap,Il.normalmap,Il.displacementmap,{opacity:{value:1}}]),vertexShader:Rl.normal_vert,fragmentShader:Rl.normal_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:Rl.cube_vert,fragmentShader:Rl.cube_frag},equirect:{uniforms:{tEquirect:{value:null},tFlip:{value:-1}},vertexShader:Rl.equirect_vert,fragmentShader:Rl.equirect_frag},distanceRGBA:{uniforms:{lightPos:{value:new g}},vertexShader:Rl.distanceRGBA_vert,fragmentShader:Rl.distanceRGBA_frag}};Ol.physical={uniforms:Ll.merge([Ol.standard.uniforms,{clearCoat:{value:0},clearCoatRoughness:{value:0}}]),vertexShader:Rl.meshphysical_vert,fragmentShader:Rl.meshphysical_frag},Object.assign(et.prototype,{set:function(t,e){return this.min.copy(t),this.max.copy(e),this},setFromPoints:function(t){var e=this;this.makeEmpty();for(var i=0,r=t.length;i<r;i++)e.expandByPoint(t[i]);return this},setFromCenterAndSize:function(){var t=new l;return function(e,i){var r=t.copy(i).multiplyScalar(.5);return this.min.copy(e).sub(r),this.max.copy(e).add(r),this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.min.copy(t.min),this.max.copy(t.max),this},makeEmpty:function(){return this.min.x=this.min.y=1/0,this.max.x=this.max.y=-1/0,this},isEmpty:function(){return this.max.x<this.min.x||this.max.y<this.min.y},getCenter:function(t){var e=t||new l;return this.isEmpty()?e.set(0,0):e.addVectors(this.min,this.max).multiplyScalar(.5)},getSize:function(t){var e=t||new l;return this.isEmpty()?e.set(0,0):e.subVectors(this.max,this.min)},expandByPoint:function(t){return this.min.min(t),this.max.max(t),this},expandByVector:function(t){return this.min.sub(t),this.max.add(t),this},expandByScalar:function(t){return this.min.addScalar(-t),this.max.addScalar(t),this},containsPoint:function(t){return!(t.x<this.min.x||t.x>this.max.x||t.y<this.min.y||t.y>this.max.y)},containsBox:function(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y},getParameter:function(t,e){return(e||new l).set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(t){return!(t.max.x<this.min.x||t.min.x>this.max.x||t.max.y<this.min.y||t.min.y>this.max.y)},clampPoint:function(t,e){return(e||new l).copy(t).clamp(this.min,this.max)},distanceToPoint:function(){var t=new l;return function(e){return t.copy(e).clamp(this.min,this.max).sub(e).length()}}(),intersect:function(t){return this.min.max(t.min),this.max.min(t.max),this},union:function(t){return this.min.min(t.min),this.max.max(t.max),this},translate:function(t){return this.min.add(t),this.max.add(t),this},equals:function(t){return t.min.equals(this.min)&&t.max.equals(this.max)}});var Dl=0;Object.assign(nt.prototype,h.prototype,{isMaterial:!0,setValues:function(t){var e=this;if(void 0!==t)for(var i in t){var r=t[i];if(void 0!==r){var n=e[i];void 0!==n?n&&n.isColor?n.set(r):n&&n.isVector3&&r&&r.isVector3?n.copy(r):e[i]="overdraw"===i?Number(r):r:console.warn("THREE."+e.type+": '"+i+"' is not a property of this material.")}else console.warn("THREE.Material: '"+i+"' parameter is undefined.")}},toJSON:function(t){function e(t){var e=[];for(var i in t){var r=t[i];delete r.metadata,e.push(r)}return e}var i=void 0===t;i&&(t={textures:{},images:{}});var r={metadata:{version:4.5,type:"Material",generator:"Material.toJSON"}};if(r.uuid=this.uuid,r.type=this.type,""!==this.name&&(r.name=this.name),this.color&&this.color.isColor&&(r.color=this.color.getHex()),void 0!==this.roughness&&(r.roughness=this.roughness),void 0!==this.metalness&&(r.metalness=this.metalness),this.emissive&&this.emissive.isColor&&(r.emissive=this.emissive.getHex()),this.specular&&this.specular.isColor&&(r.specular=this.specular.getHex()),void 0!==this.shininess&&(r.shininess=this.shininess),void 0!==this.clearCoat&&(r.clearCoat=this.clearCoat),void 0!==this.clearCoatRoughness&&(r.clearCoatRoughness=this.clearCoatRoughness),this.map&&this.map.isTexture&&(r.map=this.map.toJSON(t).uuid),this.alphaMap&&this.alphaMap.isTexture&&(r.alphaMap=this.alphaMap.toJSON(t).uuid),this.lightMap&&this.lightMap.isTexture&&(r.lightMap=this.lightMap.toJSON(t).uuid),this.bumpMap&&this.bumpMap.isTexture&&(r.bumpMap=this.bumpMap.toJSON(t).uuid,r.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(r.normalMap=this.normalMap.toJSON(t).uuid,r.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(r.displacementMap=this.displacementMap.toJSON(t).uuid,r.displacementScale=this.displacementScale,r.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(r.roughnessMap=this.roughnessMap.toJSON(t).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(r.metalnessMap=this.metalnessMap.toJSON(t).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(r.emissiveMap=this.emissiveMap.toJSON(t).uuid),this.specularMap&&this.specularMap.isTexture&&(r.specularMap=this.specularMap.toJSON(t).uuid),this.envMap&&this.envMap.isTexture&&(r.envMap=this.envMap.toJSON(t).uuid,r.reflectivity=this.reflectivity),this.gradientMap&&this.gradientMap.isTexture&&(r.gradientMap=this.gradientMap.toJSON(t).uuid),void 0!==this.size&&(r.size=this.size),void 0!==this.sizeAttenuation&&(r.sizeAttenuation=this.sizeAttenuation),this.blending!==Ou&&(r.blending=this.blending),this.shading!==Eu&&(r.shading=this.shading),this.side!==Au&&(r.side=this.side),this.vertexColors!==Cu&&(r.vertexColors=this.vertexColors),this.opacity<1&&(r.opacity=this.opacity),!0===this.transparent&&(r.transparent=this.transparent),r.depthFunc=this.depthFunc,r.depthTest=this.depthTest,r.depthWrite=this.depthWrite,this.alphaTest>0&&(r.alphaTest=this.alphaTest),!0===this.premultipliedAlpha&&(r.premultipliedAlpha=this.premultipliedAlpha),!0===this.wireframe&&(r.wireframe=this.wireframe),this.wireframeLinewidth>1&&(r.wireframeLinewidth=this.wireframeLinewidth),"round"!==this.wireframeLinecap&&(r.wireframeLinecap=this.wireframeLinecap),"round"!==this.wireframeLinejoin&&(r.wireframeLinejoin=this.wireframeLinejoin),r.skinning=this.skinning,r.morphTargets=this.morphTargets,r.dithering=this.dithering,i){var n=e(t.textures),o=e(t.images);n.length>0&&(r.textures=n),o.length>0&&(r.images=o)}return r},clone:function(){return(new this.constructor).copy(this)},copy:function(t){this.name=t.name,this.fog=t.fog,this.lights=t.lights,this.blending=t.blending,this.side=t.side,this.shading=t.shading,this.vertexColors=t.vertexColors,this.opacity=t.opacity,this.transparent=t.transparent,this.blendSrc=t.blendSrc,this.blendDst=t.blendDst,this.blendEquation=t.blendEquation,this.blendSrcAlpha=t.blendSrcAlpha,this.blendDstAlpha=t.blendDstAlpha,this.blendEquationAlpha=t.blendEquationAlpha,this.depthFunc=t.depthFunc,this.depthTest=t.depthTest,this.depthWrite=t.depthWrite,this.colorWrite=t.colorWrite,this.precision=t.precision,this.polygonOffset=t.polygonOffset,this.polygonOffsetFactor=t.polygonOffsetFactor,this.polygonOffsetUnits=t.polygonOffsetUnits,this.dithering=t.dithering,this.alphaTest=t.alphaTest,this.premultipliedAlpha=t.premultipliedAlpha,this.overdraw=t.overdraw,this.visible=t.visible,this.clipShadows=t.clipShadows,this.clipIntersection=t.clipIntersection;var e=t.clippingPlanes,i=null;if(null!==e){var r=e.length;i=new Array(r);for(var n=0;n!==r;++n)i[n]=e[n].clone()}return this.clippingPlanes=i,this},dispose:function(){this.dispatchEvent({type:"dispose"})}}),ot.prototype=Object.create(nt.prototype),ot.prototype.constructor=ot,ot.prototype.isShaderMaterial=!0,ot.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.fragmentShader=t.fragmentShader,this.vertexShader=t.vertexShader,this.uniforms=Ll.clone(t.uniforms),this.defines=t.defines,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.lights=t.lights,this.clipping=t.clipping,this.skinning=t.skinning,this.morphTargets=t.morphTargets,this.morphNormals=t.morphNormals,this.extensions=t.extensions,this},ot.prototype.toJSON=function(t){var e=nt.prototype.toJSON.call(this,t);return e.uniforms=this.uniforms,e.vertexShader=this.vertexShader,e.fragmentShader=this.fragmentShader,e},at.prototype=Object.create(nt.prototype),at.prototype.constructor=at,at.prototype.isMeshDepthMaterial=!0,at.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.depthPacking=t.depthPacking,this.skinning=t.skinning,this.morphTargets=t.morphTargets,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this},Object.assign(st.prototype,{isBox3:!0,set:function(t,e){return this.min.copy(t),this.max.copy(e),this},setFromArray:function(t){for(var e=1/0,i=1/0,r=1/0,n=-1/0,o=-1/0,a=-1/0,s=0,c=t.length;s<c;s+=3){var u=t[s],h=t[s+1],l=t[s+2];u<e&&(e=u),h<i&&(i=h),l<r&&(r=l),u>n&&(n=u),h>o&&(o=h),l>a&&(a=l)}return this.min.set(e,i,r),this.max.set(n,o,a),this},setFromBufferAttribute:function(t){for(var e=1/0,i=1/0,r=1/0,n=-1/0,o=-1/0,a=-1/0,s=0,c=t.count;s<c;s++){var u=t.getX(s),h=t.getY(s),l=t.getZ(s);u<e&&(e=u),h<i&&(i=h),l<r&&(r=l),u>n&&(n=u),h>o&&(o=h),l>a&&(a=l)}return this.min.set(e,i,r),this.max.set(n,o,a),this},setFromPoints:function(t){var e=this;this.makeEmpty();for(var i=0,r=t.length;i<r;i++)e.expandByPoint(t[i]);return this},setFromCenterAndSize:function(){var t=new g;return function(e,i){var r=t.copy(i).multiplyScalar(.5);return this.min.copy(e).sub(r),this.max.copy(e).add(r),this}}(),setFromObject:function(t){return this.makeEmpty(),this.expandByObject(t)},clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.min.copy(t.min),this.max.copy(t.max),this},makeEmpty:function(){return this.min.x=this.min.y=this.min.z=1/0,this.max.x=this.max.y=this.max.z=-1/0,this},isEmpty:function(){return this.max.x<this.min.x||this.max.y<this.min.y||this.max.z<this.min.z},getCenter:function(t){var e=t||new g;return this.isEmpty()?e.set(0,0,0):e.addVectors(this.min,this.max).multiplyScalar(.5)},getSize:function(t){var e=t||new g;return this.isEmpty()?e.set(0,0,0):e.subVectors(this.max,this.min)},expandByPoint:function(t){return this.min.min(t),this.max.max(t),this},expandByVector:function(t){return this.min.sub(t),this.max.add(t),this},expandByScalar:function(t){return this.min.addScalar(-t),this.max.addScalar(t),this},expandByObject:function(){var t=new g;return function(e){var i=this;return e.updateMatrixWorld(!0),e.traverse(function(e){var r,n,o=e.geometry;if(void 0!==o)if(o.isGeometry){var a=o.vertices;for(r=0,n=a.length;r<n;r++)t.copy(a[r]),t.applyMatrix4(e.matrixWorld),i.expandByPoint(t)}else if(o.isBufferGeometry){var s=o.attributes.position;if(void 0!==s)for(r=0,n=s.count;r<n;r++)t.fromBufferAttribute(s,r).applyMatrix4(e.matrixWorld),i.expandByPoint(t)}}),this}}(),containsPoint:function(t){return!(t.x<this.min.x||t.x>this.max.x||t.y<this.min.y||t.y>this.max.y||t.z<this.min.z||t.z>this.max.z)},containsBox:function(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z},getParameter:function(t,e){return(e||new g).set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y),(t.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(t){return!(t.max.x<this.min.x||t.min.x>this.max.x||t.max.y<this.min.y||t.min.y>this.max.y||t.max.z<this.min.z||t.min.z>this.max.z)},intersectsSphere:function(){var t=new g;return function(e){return this.clampPoint(e.center,t),t.distanceToSquared(e.center)<=e.radius*e.radius}}(),intersectsPlane:function(t){var e,i;return t.normal.x>0?(e=t.normal.x*this.min.x,i=t.normal.x*this.max.x):(e=t.normal.x*this.max.x,i=t.normal.x*this.min.x),t.normal.y>0?(e+=t.normal.y*this.min.y,i+=t.normal.y*this.max.y):(e+=t.normal.y*this.max.y,i+=t.normal.y*this.min.y),t.normal.z>0?(e+=t.normal.z*this.min.z,i+=t.normal.z*this.max.z):(e+=t.normal.z*this.max.z,i+=t.normal.z*this.min.z),e<=t.constant&&i>=t.constant},clampPoint:function(t,e){return(e||new g).copy(t).clamp(this.min,this.max)},distanceToPoint:function(){var t=new g;return function(e){return t.copy(e).clamp(this.min,this.max).sub(e).length()}}(),getBoundingSphere:function(){var t=new g;return function(e){var i=e||new ct;return this.getCenter(i.center),i.radius=.5*this.getSize(t).length(),i}}(),intersect:function(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this},union:function(t){return this.min.min(t.min),this.max.max(t.max),this},applyMatrix4:function(){var t=[new g,new g,new g,new g,new g,new g,new g,new g];return function(e){return this.isEmpty()?this:(t[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(e),t[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(e),t[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(e),t[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(e),t[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(e),t[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(e),t[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(e),t[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(e),this.setFromPoints(t),this)}}(),translate:function(t){return this.min.add(t),this.max.add(t),this},equals:function(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}),Object.assign(ct.prototype,{set:function(t,e){return this.center.copy(t),this.radius=e,this},setFromPoints:function(){var t=new st;return function(e,i){var r=this.center;void 0!==i?r.copy(i):t.setFromPoints(e).getCenter(r);for(var n=0,o=0,a=e.length;o<a;o++)n=Math.max(n,r.distanceToSquared(e[o]));return this.radius=Math.sqrt(n),this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.center.copy(t.center),this.radius=t.radius,this},empty:function(){return this.radius<=0},containsPoint:function(t){return t.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(t){return t.distanceTo(this.center)-this.radius},intersectsSphere:function(t){var e=this.radius+t.radius;return t.center.distanceToSquared(this.center)<=e*e},intersectsBox:function(t){return t.intersectsSphere(this)},intersectsPlane:function(t){return Math.abs(this.center.dot(t.normal)-t.constant)<=this.radius},clampPoint:function(t,e){var i=this.center.distanceToSquared(t),r=e||new g;return r.copy(t),i>this.radius*this.radius&&(r.sub(this.center).normalize(),r.multiplyScalar(this.radius).add(this.center)),r},getBoundingBox:function(t){var e=t||new st;return e.set(this.center,this.center),e.expandByScalar(this.radius),e},applyMatrix4:function(t){return this.center.applyMatrix4(t),this.radius=this.radius*t.getMaxScaleOnAxis(),this},translate:function(t){return this.center.add(t),this},equals:function(t){return t.center.equals(this.center)&&t.radius===this.radius}}),Object.assign(ut.prototype,{isMatrix3:!0,set:function(t,e,i,r,n,o,a,s,c){var u=this.elements;return u[0]=t,u[1]=r,u[2]=a,u[3]=e,u[4]=n,u[5]=s,u[6]=i,u[7]=o,u[8]=c,this},identity:function(){return this.set(1,0,0,0,1,0,0,0,1),this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(t){var e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this},setFromMatrix4:function(t){var e=t.elements;return this.set(e[0],e[4],e[8],e[1],e[5],e[9],e[2],e[6],e[10]),this},applyToBufferAttribute:function(){var t=new g;return function(e){for(var i=this,r=0,n=e.count;r<n;r++)t.x=e.getX(r),t.y=e.getY(r),t.z=e.getZ(r),t.applyMatrix3(i),e.setXYZ(r,t.x,t.y,t.z);return e}}(),multiply:function(t){return this.multiplyMatrices(this,t)},premultiply:function(t){return this.multiplyMatrices(t,this)},multiplyMatrices:function(t,e){var i=t.elements,r=e.elements,n=this.elements,o=i[0],a=i[3],s=i[6],c=i[1],u=i[4],h=i[7],l=i[2],p=i[5],d=i[8],f=r[0],m=r[3],g=r[6],v=r[1],y=r[4],b=r[7],x=r[2],_=r[5],w=r[8];return n[0]=o*f+a*v+s*x,n[3]=o*m+a*y+s*_,n[6]=o*g+a*b+s*w,n[1]=c*f+u*v+h*x,n[4]=c*m+u*y+h*_,n[7]=c*g+u*b+h*w,n[2]=l*f+p*v+d*x,n[5]=l*m+p*y+d*_,n[8]=l*g+p*b+d*w,this},multiplyScalar:function(t){var e=this.elements;return e[0]*=t,e[3]*=t,e[6]*=t,e[1]*=t,e[4]*=t,e[7]*=t,e[2]*=t,e[5]*=t,e[8]*=t,this},determinant:function(){var t=this.elements,e=t[0],i=t[1],r=t[2],n=t[3],o=t[4],a=t[5],s=t[6],c=t[7],u=t[8];return e*o*u-e*a*c-i*n*u+i*a*s+r*n*c-r*o*s},getInverse:function(t,e){t&&t.isMatrix4&&console.error("THREE.Matrix3.getInverse no longer takes a Matrix4 argument.");var i=t.elements,r=this.elements,n=i[0],o=i[1],a=i[2],s=i[3],c=i[4],u=i[5],h=i[6],l=i[7],p=i[8],d=p*c-u*l,f=u*h-p*s,m=l*s-c*h,g=n*d+o*f+a*m;if(0===g){var v="THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0";if(!0===e)throw new Error(v);return console.warn(v),this.identity()}var y=1/g;return r[0]=d*y,r[1]=(a*l-p*o)*y,r[2]=(u*o-a*c)*y,r[3]=f*y,r[4]=(p*n-a*h)*y,r[5]=(a*s-u*n)*y,r[6]=m*y,r[7]=(o*h-l*n)*y,r[8]=(c*n-o*s)*y,this},transpose:function(){var t,e=this.elements;return t=e[1],e[1]=e[3],e[3]=t,t=e[2],e[2]=e[6],e[6]=t,t=e[5],e[5]=e[7],e[7]=t,this},getNormalMatrix:function(t){return this.setFromMatrix4(t).getInverse(this).transpose()},transposeIntoArray:function(t){var e=this.elements;return t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],this},equals:function(t){for(var e=this.elements,i=t.elements,r=0;r<9;r++)if(e[r]!==i[r])return!1;return!0},fromArray:function(t,e){var i=this;void 0===e&&(e=0);for(var r=0;r<9;r++)i.elements[r]=t[r+e];return this},toArray:function(t,e){void 0===t&&(t=[]),void 0===e&&(e=0);var i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t}}),Object.assign(ht.prototype,{set:function(t,e){return this.normal.copy(t),this.constant=e,this},setComponents:function(t,e,i,r){return this.normal.set(t,e,i),this.constant=r,this},setFromNormalAndCoplanarPoint:function(t,e){return this.normal.copy(t),this.constant=-e.dot(this.normal),this},setFromCoplanarPoints:function(){var t=new g,e=new g;return function(i,r,n){var o=t.subVectors(n,r).cross(e.subVectors(i,r)).normalize();return this.setFromNormalAndCoplanarPoint(o,i),this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.normal.copy(t.normal),this.constant=t.constant,this},normalize:function(){var t=1/this.normal.length();return this.normal.multiplyScalar(t),this.constant*=t,this},negate:function(){return this.constant*=-1,this.normal.negate(),this},distanceToPoint:function(t){return this.normal.dot(t)+this.constant},distanceToSphere:function(t){return this.distanceToPoint(t.center)-t.radius},projectPoint:function(t,e){return this.orthoPoint(t,e).sub(t).negate()},orthoPoint:function(t,e){var i=this.distanceToPoint(t);return(e||new g).copy(this.normal).multiplyScalar(i)},intersectLine:function(){var t=new g;return function(e,i){var r=i||new g,n=e.delta(t),o=this.normal.dot(n);if(0!==o){var a=-(e.start.dot(this.normal)+this.constant)/o;if(!(a<0||a>1))return r.copy(n).multiplyScalar(a).add(e.start)}else if(0===this.distanceToPoint(e.start))return r.copy(e.start)}}(),intersectsLine:function(t){var e=this.distanceToPoint(t.start),i=this.distanceToPoint(t.end);return e<0&&i>0||i<0&&e>0},intersectsBox:function(t){return t.intersectsPlane(this)},intersectsSphere:function(t){return t.intersectsPlane(this)},coplanarPoint:function(t){return(t||new g).copy(this.normal).multiplyScalar(-this.constant)},applyMatrix4:function(){var t=new g,e=new ut;return function(i,r){var n=this.coplanarPoint(t).applyMatrix4(i),o=r||e.getNormalMatrix(i),a=this.normal.applyMatrix3(o).normalize();return this.constant=-n.dot(a),this}}(),translate:function(t){return this.constant=this.constant-t.dot(this.normal),this},equals:function(t){return t.normal.equals(this.normal)&&t.constant===this.constant}}),Object.assign(lt.prototype,{set:function(t,e,i,r,n,o){var a=this.planes;return a[0].copy(t),a[1].copy(e),a[2].copy(i),a[3].copy(r),a[4].copy(n),a[5].copy(o),this},clone:function(){return(new this.constructor).copy(this)},copy:function(t){for(var e=this.planes,i=0;i<6;i++)e[i].copy(t.planes[i]);return this},setFromMatrix:function(t){var e=this.planes,i=t.elements,r=i[0],n=i[1],o=i[2],a=i[3],s=i[4],c=i[5],u=i[6],h=i[7],l=i[8],p=i[9],d=i[10],f=i[11],m=i[12],g=i[13],v=i[14],y=i[15];return e[0].setComponents(a-r,h-s,f-l,y-m).normalize(),e[1].setComponents(a+r,h+s,f+l,y+m).normalize(),e[2].setComponents(a+n,h+c,f+p,y+g).normalize(),e[3].setComponents(a-n,h-c,f-p,y-g).normalize(),e[4].setComponents(a-o,h-u,f-d,y-v).normalize(),e[5].setComponents(a+o,h+u,f+d,y+v).normalize(),this},intersectsObject:function(){var t=new ct;return function(e){var i=e.geometry;return null===i.boundingSphere&&i.computeBoundingSphere(),t.copy(i.boundingSphere).applyMatrix4(e.matrixWorld),this.intersectsSphere(t)}}(),intersectsSprite:function(){var t=new ct;return function(e){return t.center.set(0,0,0),t.radius=.7071067811865476,t.applyMatrix4(e.matrixWorld),this.intersectsSphere(t)}}(),intersectsSphere:function(t){for(var e=this.planes,i=t.center,r=-t.radius,n=0;n<6;n++)if(e[n].distanceToPoint(i)<r)return!1;return!0},intersectsBox:function(){var t=new g,e=new g;return function(i){for(var r=this.planes,n=0;n<6;n++){var o=r[n];t.x=o.normal.x>0?i.min.x:i.max.x,e.x=o.normal.x>0?i.max.x:i.min.x,t.y=o.normal.y>0?i.min.y:i.max.y,e.y=o.normal.y>0?i.max.y:i.min.y,t.z=o.normal.z>0?i.min.z:i.max.z,e.z=o.normal.z>0?i.max.z:i.min.z;var a=o.distanceToPoint(t),s=o.distanceToPoint(e);if(a<0&&s<0)return!1}return!0}}(),containsPoint:function(t){for(var e=this.planes,i=0;i<6;i++)if(e[i].distanceToPoint(t)<0)return!1;return!0}}),Object.assign(dt.prototype,{set:function(t,e){return this.origin.copy(t),this.direction.copy(e),this},clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.origin.copy(t.origin),this.direction.copy(t.direction),this},at:function(t,e){return(e||new g).copy(this.direction).multiplyScalar(t).add(this.origin)},lookAt:function(t){return this.direction.copy(t).sub(this.origin).normalize(),this},recast:function(){var t=new g;return function(e){return this.origin.copy(this.at(e,t)),this}}(),closestPointToPoint:function(t,e){var i=e||new g;i.subVectors(t,this.origin);var r=i.dot(this.direction);return r<0?i.copy(this.origin):i.copy(this.direction).multiplyScalar(r).add(this.origin)},distanceToPoint:function(t){return Math.sqrt(this.distanceSqToPoint(t))},distanceSqToPoint:function(){var t=new g;return function(e){var i=t.subVectors(e,this.origin).dot(this.direction);return i<0?this.origin.distanceToSquared(e):(t.copy(this.direction).multiplyScalar(i).add(this.origin),t.distanceToSquared(e))}}(),distanceSqToSegment:function(){var t=new g,e=new g,i=new g;return function(r,n,o,a){t.copy(r).add(n).multiplyScalar(.5),e.copy(n).sub(r).normalize(),i.copy(this.origin).sub(t);var s,c,u,h,l=.5*r.distanceTo(n),p=-this.direction.dot(e),d=i.dot(this.direction),f=-i.dot(e),m=i.lengthSq(),g=Math.abs(1-p*p);if(g>0)if(s=p*f-d,c=p*d-f,h=l*g,s>=0)if(c>=-h)if(c<=h){var v=1/g;u=(s*=v)*(s+p*(c*=v)+2*d)+c*(p*s+c+2*f)+m}else c=l,u=-(s=Math.max(0,-(p*c+d)))*s+c*(c+2*f)+m;else c=-l,u=-(s=Math.max(0,-(p*c+d)))*s+c*(c+2*f)+m;else c<=-h?u=-(s=Math.max(0,-(-p*l+d)))*s+(c=s>0?-l:Math.min(Math.max(-l,-f),l))*(c+2*f)+m:c<=h?(s=0,u=(c=Math.min(Math.max(-l,-f),l))*(c+2*f)+m):u=-(s=Math.max(0,-(p*l+d)))*s+(c=s>0?l:Math.min(Math.max(-l,-f),l))*(c+2*f)+m;else c=p>0?-l:l,u=-(s=Math.max(0,-(p*c+d)))*s+c*(c+2*f)+m;return o&&o.copy(this.direction).multiplyScalar(s).add(this.origin),a&&a.copy(e).multiplyScalar(c).add(t),u}}(),intersectSphere:function(){var t=new g;return function(e,i){t.subVectors(e.center,this.origin);var r=t.dot(this.direction),n=t.dot(t)-r*r,o=e.radius*e.radius;if(n>o)return null;var a=Math.sqrt(o-n),s=r-a,c=r+a;return s<0&&c<0?null:s<0?this.at(c,i):this.at(s,i)}}(),intersectsSphere:function(t){return this.distanceToPoint(t.center)<=t.radius},distanceToPlane:function(t){var e=t.normal.dot(this.direction);if(0===e)return 0===t.distanceToPoint(this.origin)?0:null;var i=-(this.origin.dot(t.normal)+t.constant)/e;return i>=0?i:null},intersectPlane:function(t,e){var i=this.distanceToPlane(t);return null===i?null:this.at(i,e)},intersectsPlane:function(t){var e=t.distanceToPoint(this.origin);return 0===e||t.normal.dot(this.direction)*e<0},intersectBox:function(t,e){var i,r,n,o,a,s,c=1/this.direction.x,u=1/this.direction.y,h=1/this.direction.z,l=this.origin;return c>=0?(i=(t.min.x-l.x)*c,r=(t.max.x-l.x)*c):(i=(t.max.x-l.x)*c,r=(t.min.x-l.x)*c),u>=0?(n=(t.min.y-l.y)*u,o=(t.max.y-l.y)*u):(n=(t.max.y-l.y)*u,o=(t.min.y-l.y)*u),i>o||n>r?null:((n>i||i!==i)&&(i=n),(o<r||r!==r)&&(r=o),h>=0?(a=(t.min.z-l.z)*h,s=(t.max.z-l.z)*h):(a=(t.max.z-l.z)*h,s=(t.min.z-l.z)*h),i>s||a>r?null:((a>i||i!==i)&&(i=a),(s<r||r!==r)&&(r=s),r<0?null:this.at(i>=0?i:r,e)))},intersectsBox:function(){var t=new g;return function(e){return null!==this.intersectBox(e,t)}}(),intersectTriangle:function(){var t=new g,e=new g,i=new g,r=new g;return function(n,o,a,s,c){e.subVectors(o,n),i.subVectors(a,n),r.crossVectors(e,i);var u,h=this.direction.dot(r);if(h>0){if(s)return null;u=1}else{if(!(h<0))return null;u=-1,h=-h}t.subVectors(this.origin,n);var l=u*this.direction.dot(i.crossVectors(t,i));if(l<0)return null;var p=u*this.direction.dot(e.cross(t));if(p<0)return null;if(l+p>h)return null;var d=-u*t.dot(r);return d<0?null:this.at(d/h,c)}}(),applyMatrix4:function(t){return this.direction.add(this.origin).applyMatrix4(t),this.origin.applyMatrix4(t),this.direction.sub(this.origin),this.direction.normalize(),this},equals:function(t){return t.origin.equals(this.origin)&&t.direction.equals(this.direction)}}),ft.RotationOrders=["XYZ","YZX","ZXY","XZY","YXZ","ZYX"],ft.DefaultOrder="XYZ",Object.defineProperties(ft.prototype,{x:{get:function(){return this._x},set:function(t){this._x=t,this.onChangeCallback()}},y:{get:function(){return this._y},set:function(t){this._y=t,this.onChangeCallback()}},z:{get:function(){return this._z},set:function(t){this._z=t,this.onChangeCallback()}},order:{get:function(){return this._order},set:function(t){this._order=t,this.onChangeCallback()}}}),Object.assign(ft.prototype,{isEuler:!0,set:function(t,e,i,r){return this._x=t,this._y=e,this._z=i,this._order=r||this._order,this.onChangeCallback(),this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(t){return this._x=t._x,this._y=t._y,this._z=t._z,this._order=t._order,this.onChangeCallback(),this},setFromRotationMatrix:function(t,e,i){var r=xl.clamp,n=t.elements,o=n[0],a=n[4],s=n[8],c=n[1],u=n[5],h=n[9],l=n[2],p=n[6],d=n[10];return e=e||this._order,"XYZ"===e?(this._y=Math.asin(r(s,-1,1)),Math.abs(s)<.99999?(this._x=Math.atan2(-h,d),this._z=Math.atan2(-a,o)):(this._x=Math.atan2(p,u),this._z=0)):"YXZ"===e?(this._x=Math.asin(-r(h,-1,1)),Math.abs(h)<.99999?(this._y=Math.atan2(s,d),this._z=Math.atan2(c,u)):(this._y=Math.atan2(-l,o),this._z=0)):"ZXY"===e?(this._x=Math.asin(r(p,-1,1)),Math.abs(p)<.99999?(this._y=Math.atan2(-l,d),this._z=Math.atan2(-a,u)):(this._y=0,this._z=Math.atan2(c,o))):"ZYX"===e?(this._y=Math.asin(-r(l,-1,1)),Math.abs(l)<.99999?(this._x=Math.atan2(p,d),this._z=Math.atan2(c,o)):(this._x=0,this._z=Math.atan2(-a,u))):"YZX"===e?(this._z=Math.asin(r(c,-1,1)),Math.abs(c)<.99999?(this._x=Math.atan2(-h,u),this._y=Math.atan2(-l,o)):(this._x=0,this._y=Math.atan2(s,d))):"XZY"===e?(this._z=Math.asin(-r(a,-1,1)),Math.abs(a)<.99999?(this._x=Math.atan2(p,u),this._y=Math.atan2(s,o)):(this._x=Math.atan2(-h,d),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+e),this._order=e,!1!==i&&this.onChangeCallback(),this},setFromQuaternion:function(){var t=new v;return function(e,i,r){return t.makeRotationFromQuaternion(e),this.setFromRotationMatrix(t,i,r)}}(),setFromVector3:function(t,e){return this.set(t.x,t.y,t.z,e||this._order)},reorder:function(){var t=new m;return function(e){return t.setFromEuler(this),this.setFromQuaternion(t,e)}}(),equals:function(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._order===this._order},fromArray:function(t){return this._x=t[0],this._y=t[1],this._z=t[2],void 0!==t[3]&&(this._order=t[3]),this.onChangeCallback(),this},toArray:function(t,e){return void 0===t&&(t=[]),void 0===e&&(e=0),t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._order,t},toVector3:function(t){return t?t.set(this._x,this._y,this._z):new g(this._x,this._y,this._z)},onChange:function(t){return this.onChangeCallback=t,this},onChangeCallback:function(){}}),Object.assign(mt.prototype,{set:function(t){this.mask=1<<t|0},enable:function(t){this.mask|=1<<t|0},toggle:function(t){this.mask^=1<<t|0},disable:function(t){this.mask&=~(1<<t|0)},test:function(t){return 0!=(this.mask&t.mask)}});var Nl=0;gt.DefaultUp=new g(0,1,0),gt.DefaultMatrixAutoUpdate=!0,Object.assign(gt.prototype,h.prototype,{isObject3D:!0,applyMatrix:function(t){this.matrix.multiplyMatrices(t,this.matrix),this.matrix.decompose(this.position,this.quaternion,this.scale)},setRotationFromAxisAngle:function(t,e){this.quaternion.setFromAxisAngle(t,e)},setRotationFromEuler:function(t){this.quaternion.setFromEuler(t,!0)},setRotationFromMatrix:function(t){this.quaternion.setFromRotationMatrix(t)},setRotationFromQuaternion:function(t){this.quaternion.copy(t)},rotateOnAxis:function(){var t=new m;return function(e,i){return t.setFromAxisAngle(e,i),this.quaternion.multiply(t),this}}(),rotateX:function(){var t=new g(1,0,0);return function(e){return this.rotateOnAxis(t,e)}}(),rotateY:function(){var t=new g(0,1,0);return function(e){return this.rotateOnAxis(t,e)}}(),rotateZ:function(){var t=new g(0,0,1);return function(e){return this.rotateOnAxis(t,e)}}(),translateOnAxis:function(){var t=new g;return function(e,i){return t.copy(e).applyQuaternion(this.quaternion),this.position.add(t.multiplyScalar(i)),this}}(),translateX:function(){var t=new g(1,0,0);return function(e){return this.translateOnAxis(t,e)}}(),translateY:function(){var t=new g(0,1,0);return function(e){return this.translateOnAxis(t,e)}}(),translateZ:function(){var t=new g(0,0,1);return function(e){return this.translateOnAxis(t,e)}}(),localToWorld:function(t){return t.applyMatrix4(this.matrixWorld)},worldToLocal:function(){var t=new v;return function(e){return e.applyMatrix4(t.getInverse(this.matrixWorld))}}(),lookAt:function(){var t=new v;return function(e){this.isCamera?t.lookAt(this.position,e,this.up):t.lookAt(e,this.position,this.up),this.quaternion.setFromRotationMatrix(t)}}(),add:function(t){var e=arguments,i=this;if(arguments.length>1){for(var r=0;r<arguments.length;r++)i.add(e[r]);return this}return t===this?(console.error("THREE.Object3D.add: object can't be added as a child of itself.",t),this):(t&&t.isObject3D?(null!==t.parent&&t.parent.remove(t),t.parent=this,t.dispatchEvent({type:"added"}),this.children.push(t)):console.error("THREE.Object3D.add: object not an instance of THREE.Object3D.",t),this)},remove:function(t){var e=arguments,i=this;if(arguments.length>1)for(var r=0;r<arguments.length;r++)i.remove(e[r]);var n=this.children.indexOf(t);-1!==n&&(t.parent=null,t.dispatchEvent({type:"removed"}),this.children.splice(n,1))},getObjectById:function(t){return this.getObjectByProperty("id",t)},getObjectByName:function(t){return this.getObjectByProperty("name",t)},getObjectByProperty:function(t,e){var i=this;if(this[t]===e)return this;for(var r=0,n=this.children.length;r<n;r++){var o=i.children[r].getObjectByProperty(t,e);if(void 0!==o)return o}},getWorldPosition:function(t){var e=t||new g;return this.updateMatrixWorld(!0),e.setFromMatrixPosition(this.matrixWorld)},getWorldQuaternion:function(){var t=new g,e=new g;return function(i){var r=i||new m;return this.updateMatrixWorld(!0),this.matrixWorld.decompose(t,r,e),r}}(),getWorldRotation:function(){var t=new m;return function(e){var i=e||new ft;return this.getWorldQuaternion(t),i.setFromQuaternion(t,this.rotation.order,!1)}}(),getWorldScale:function(){var t=new g,e=new m;return function(i){var r=i||new g;return this.updateMatrixWorld(!0),this.matrixWorld.decompose(t,e,r),r}}(),getWorldDirection:function(){var t=new m;return function(e){var i=e||new g;return this.getWorldQuaternion(t),i.set(0,0,1).applyQuaternion(t)}}(),raycast:function(){},traverse:function(t){t(this);for(var e=this.children,i=0,r=e.length;i<r;i++)e[i].traverse(t)},traverseVisible:function(t){if(!1!==this.visible){t(this);for(var e=this.children,i=0,r=e.length;i<r;i++)e[i].traverseVisible(t)}},traverseAncestors:function(t){var e=this.parent;null!==e&&(t(e),e.traverseAncestors(t))},updateMatrix:function(){this.matrix.compose(this.position,this.quaternion,this.scale),this.matrixWorldNeedsUpdate=!0},updateMatrixWorld:function(t){this.matrixAutoUpdate&&this.updateMatrix(),(this.matrixWorldNeedsUpdate||t)&&(null===this.parent?this.matrixWorld.copy(this.matrix):this.matrixWorld.multiplyMatrices(this.parent.matrixWorld,this.matrix),this.matrixWorldNeedsUpdate=!1,t=!0);for(var e=this.children,i=0,r=e.length;i<r;i++)e[i].updateMatrixWorld(t)},toJSON:function(t){function e(e,i){return void 0===e[i.uuid]&&(e[i.uuid]=i.toJSON(t)),i.uuid}function i(t){var e=[];for(var i in t){var r=t[i];delete r.metadata,e.push(r)}return e}var r=this,n=void 0===t||""===t,o={};n&&(t={geometries:{},materials:{},textures:{},images:{}},o.metadata={version:4.5,type:"Object",generator:"Object3D.toJSON"});var a={};if(a.uuid=this.uuid,a.type=this.type,""!==this.name&&(a.name=this.name),"{}"!==JSON.stringify(this.userData)&&(a.userData=this.userData),!0===this.castShadow&&(a.castShadow=!0),!0===this.receiveShadow&&(a.receiveShadow=!0),!1===this.visible&&(a.visible=!1),a.matrix=this.matrix.toArray(),void 0!==this.geometry&&(a.geometry=e(t.geometries,this.geometry)),void 0!==this.material)if(Array.isArray(this.material)){for(var s=[],c=0,u=this.material.length;c<u;c++)s.push(e(t.materials,r.material[c]));a.material=s}else a.material=e(t.materials,this.material);if(this.children.length>0){a.children=[];for(c=0;c<this.children.length;c++)a.children.push(r.children[c].toJSON(t).object)}if(n){var h=i(t.geometries),l=i(t.materials),p=i(t.textures),d=i(t.images);h.length>0&&(o.geometries=h),l.length>0&&(o.materials=l),p.length>0&&(o.textures=p),d.length>0&&(o.images=d)}return o.object=a,o},clone:function(t){return(new this.constructor).copy(this,t)},copy:function(t,e){var i=this;if(void 0===e&&(e=!0),this.name=t.name,this.up.copy(t.up),this.position.copy(t.position),this.quaternion.copy(t.quaternion),this.scale.copy(t.scale),this.matrix.copy(t.matrix),this.matrixWorld.copy(t.matrixWorld),this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrixWorldNeedsUpdate=t.matrixWorldNeedsUpdate,this.layers.mask=t.layers.mask,this.visible=t.visible,this.castShadow=t.castShadow,this.receiveShadow=t.receiveShadow,this.frustumCulled=t.frustumCulled,this.renderOrder=t.renderOrder,this.userData=JSON.parse(JSON.stringify(t.userData)),!0===e)for(var r=0;r<t.children.length;r++){var n=t.children[r];i.add(n.clone())}return this}}),Object.assign(vt.prototype,{set:function(t,e){return this.start.copy(t),this.end.copy(e),this},clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.start.copy(t.start),this.end.copy(t.end),this},getCenter:function(t){return(t||new g).addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(t){return(t||new g).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(t,e){var i=e||new g;return this.delta(i).multiplyScalar(t).add(this.start)},closestPointToPointParameter:function(){var t=new g,e=new g;return function(i,r){t.subVectors(i,this.start),e.subVectors(this.end,this.start);var n=e.dot(e),o=e.dot(t)/n;return r&&(o=xl.clamp(o,0,1)),o}}(),closestPointToPoint:function(t,e,i){var r=this.closestPointToPointParameter(t,e),n=i||new g;return this.delta(n).multiplyScalar(r).add(this.start)},applyMatrix4:function(t){return this.start.applyMatrix4(t),this.end.applyMatrix4(t),this},equals:function(t){return t.start.equals(this.start)&&t.end.equals(this.end)}}),Object.assign(yt,{normal:function(){var t=new g;return function(e,i,r,n){var o=n||new g;o.subVectors(r,i),t.subVectors(e,i),o.cross(t);var a=o.lengthSq();return a>0?o.multiplyScalar(1/Math.sqrt(a)):o.set(0,0,0)}}(),barycoordFromPoint:function(){var t=new g,e=new g,i=new g;return function(r,n,o,a,s){t.subVectors(a,n),e.subVectors(o,n),i.subVectors(r,n);var c=t.dot(t),u=t.dot(e),h=t.dot(i),l=e.dot(e),p=e.dot(i),d=c*l-u*u,f=s||new g;if(0===d)return f.set(-2,-1,-1);var m=1/d,v=(l*h-u*p)*m,y=(c*p-u*h)*m;return f.set(1-v-y,y,v)}}(),containsPoint:function(){var t=new g;return function(e,i,r,n){var o=yt.barycoordFromPoint(e,i,r,n,t);return o.x>=0&&o.y>=0&&o.x+o.y<=1}}()}),Object.assign(yt.prototype,{set:function(t,e,i){return this.a.copy(t),this.b.copy(e),this.c.copy(i),this},setFromPointsAndIndices:function(t,e,i,r){return this.a.copy(t[e]),this.b.copy(t[i]),this.c.copy(t[r]),this},clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.a.copy(t.a),this.b.copy(t.b),this.c.copy(t.c),this},area:function(){var t=new g,e=new g;return function(){return t.subVectors(this.c,this.b),e.subVectors(this.a,this.b),.5*t.cross(e).length()}}(),midpoint:function(t){return(t||new g).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(t){return yt.normal(this.a,this.b,this.c,t)},plane:function(t){return(t||new ht).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(t,e){return yt.barycoordFromPoint(t,this.a,this.b,this.c,e)},containsPoint:function(t){return yt.containsPoint(t,this.a,this.b,this.c)},closestPointToPoint:function(){var t=new ht,e=[new vt,new vt,new vt],i=new g,r=new g;return function(n,o){var a=o||new g,s=1/0;if(t.setFromCoplanarPoints(this.a,this.b,this.c),t.projectPoint(n,i),!0===this.containsPoint(i))a.copy(i);else{e[0].set(this.a,this.b),e[1].set(this.b,this.c),e[2].set(this.c,this.a);for(var c=0;c<e.length;c++){e[c].closestPointToPoint(i,!0,r);var u=i.distanceToSquared(r);u<s&&(s=u,a.copy(r))}}return a}}(),equals:function(t){return t.a.equals(this.a)&&t.b.equals(this.b)&&t.c.equals(this.c)}}),Object.assign(bt.prototype,{clone:function(){return(new this.constructor).copy(this)},copy:function(t){var e=this;this.a=t.a,this.b=t.b,this.c=t.c,this.normal.copy(t.normal),this.color.copy(t.color),this.materialIndex=t.materialIndex;for(var i=0,r=t.vertexNormals.length;i<r;i++)e.vertexNormals[i]=t.vertexNormals[i].clone();for(var i=0,r=t.vertexColors.length;i<r;i++)e.vertexColors[i]=t.vertexColors[i].clone();return this}}),xt.prototype=Object.create(nt.prototype),xt.prototype.constructor=xt,xt.prototype.isMeshBasicMaterial=!0,xt.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.skinning=t.skinning,this.morphTargets=t.morphTargets,this},Object.defineProperty(_t.prototype,"needsUpdate",{set:function(t){!0===t&&this.version++}}),Object.assign(_t.prototype,{isBufferAttribute:!0,setArray:function(t){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.count=void 0!==t?t.length/this.itemSize:0,this.array=t},setDynamic:function(t){return this.dynamic=t,this},copy:function(t){return this.array=new t.array.constructor(t.array),this.itemSize=t.itemSize,this.count=t.count,this.normalized=t.normalized,this.dynamic=t.dynamic,this},copyAt:function(t,e,i){var r=this;t*=this.itemSize,i*=e.itemSize;for(var n=0,o=this.itemSize;n<o;n++)r.array[t+n]=e.array[i+n];return this},copyArray:function(t){return this.array.set(t),this},copyColorsArray:function(t){for(var e=this.array,i=0,r=0,n=t.length;r<n;r++){var o=t[r];void 0===o&&(console.warn("THREE.BufferAttribute.copyColorsArray(): color is undefined",r),o=new tt),e[i++]=o.r,e[i++]=o.g,e[i++]=o.b}return this},copyIndicesArray:function(t){for(var e=this.array,i=0,r=0,n=t.length;r<n;r++){var o=t[r];e[i++]=o.a,e[i++]=o.b,e[i++]=o.c}return this},copyVector2sArray:function(t){for(var e=this.array,i=0,r=0,n=t.length;r<n;r++){var o=t[r];void 0===o&&(console.warn("THREE.BufferAttribute.copyVector2sArray(): vector is undefined",r),o=new l),e[i++]=o.x,e[i++]=o.y}return this},copyVector3sArray:function(t){for(var e=this.array,i=0,r=0,n=t.length;r<n;r++){var o=t[r];void 0===o&&(console.warn("THREE.BufferAttribute.copyVector3sArray(): vector is undefined",r),o=new g),e[i++]=o.x,e[i++]=o.y,e[i++]=o.z}return this},copyVector4sArray:function(t){for(var e=this.array,i=0,r=0,n=t.length;r<n;r++){var o=t[r];void 0===o&&(console.warn("THREE.BufferAttribute.copyVector4sArray(): vector is undefined",r),o=new d),e[i++]=o.x,e[i++]=o.y,e[i++]=o.z,e[i++]=o.w}return this},set:function(t,e){return void 0===e&&(e=0),this.array.set(t,e),this},getX:function(t){return this.array[t*this.itemSize]},setX:function(t,e){return this.array[t*this.itemSize]=e,this},getY:function(t){return this.array[t*this.itemSize+1]},setY:function(t,e){return this.array[t*this.itemSize+1]=e,this},getZ:function(t){return this.array[t*this.itemSize+2]},setZ:function(t,e){return this.array[t*this.itemSize+2]=e,this},getW:function(t){return this.array[t*this.itemSize+3]},setW:function(t,e){return this.array[t*this.itemSize+3]=e,this},setXY:function(t,e,i){return t*=this.itemSize,this.array[t+0]=e,this.array[t+1]=i,this},setXYZ:function(t,e,i,r){return t*=this.itemSize,this.array[t+0]=e,this.array[t+1]=i,this.array[t+2]=r,this},setXYZW:function(t,e,i,r,n){return t*=this.itemSize,this.array[t+0]=e,this.array[t+1]=i,this.array[t+2]=r,this.array[t+3]=n,this},onUpload:function(t){return this.onUploadCallback=t,this},clone:function(){return new this.constructor(this.array,this.itemSize).copy(this)}}),wt.prototype=Object.create(_t.prototype),wt.prototype.constructor=wt,St.prototype=Object.create(_t.prototype),St.prototype.constructor=St,At.prototype=Object.create(_t.prototype),At.prototype.constructor=At,Object.assign(Mt.prototype,{computeGroups:function(t){for(var e,i=[],r=void 0,n=t.faces,o=0;o<n.length;o++){var a=n[o];a.materialIndex!==r&&(r=a.materialIndex,void 0!==e&&(e.count=3*o-e.start,i.push(e)),e={start:3*o,materialIndex:r})}void 0!==e&&(e.count=3*o-e.start,i.push(e)),this.groups=i},fromGeometry:function(t){var e,i=this,r=t.faces,n=t.vertices,o=t.faceVertexUvs,a=o[0]&&o[0].length>0,s=o[1]&&o[1].length>0,c=t.morphTargets,u=c.length;if(u>0){e=[];for(y=0;y<u;y++)e[y]=[];this.morphTargets.position=e}var h,p=t.morphNormals,d=p.length;if(d>0){h=[];for(y=0;y<d;y++)h[y]=[];this.morphTargets.normal=h}for(var f=t.skinIndices,m=t.skinWeights,g=f.length===n.length,v=m.length===n.length,y=0;y<r.length;y++){var b=r[y];i.vertices.push(n[b.a],n[b.b],n[b.c]);var x=b.vertexNormals;if(3===x.length)i.normals.push(x[0],x[1],x[2]);else{var _=b.normal;i.normals.push(_,_,_)}var w=b.vertexColors;if(3===w.length)i.colors.push(w[0],w[1],w[2]);else{var S=b.color;i.colors.push(S,S,S)}if(!0===a&&(void 0!==(A=o[0][y])?i.uvs.push(A[0],A[1],A[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ",y),i.uvs.push(new l,new l,new l))),!0===s){var A=o[1][y];void 0!==A?i.uvs2.push(A[0],A[1],A[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ",y),i.uvs2.push(new l,new l,new l))}for(P=0;P<u;P++){var M=c[P].vertices;e[P].push(M[b.a],M[b.b],M[b.c])}for(var P=0;P<d;P++){var T=p[P].vertexNormals[y];h[P].push(T.a,T.b,T.c)}g&&i.skinIndices.push(f[b.a],f[b.b],f[b.c]),v&&i.skinWeights.push(m[b.a],m[b.b],m[b.c])}return this.computeGroups(t),this.verticesNeedUpdate=t.verticesNeedUpdate,this.normalsNeedUpdate=t.normalsNeedUpdate,this.colorsNeedUpdate=t.colorsNeedUpdate,this.uvsNeedUpdate=t.uvsNeedUpdate,this.groupsNeedUpdate=t.groupsNeedUpdate,this}});var kl=0;Object.assign(Et.prototype,h.prototype,{isGeometry:!0,applyMatrix:function(t){for(var e=this,i=(new ut).getNormalMatrix(t),r=0,n=this.vertices.length;r<n;r++)e.vertices[r].applyMatrix4(t);for(var r=0,n=this.faces.length;r<n;r++){var o=e.faces[r];o.normal.applyMatrix3(i).normalize();for(var a=0,s=o.vertexNormals.length;a<s;a++)o.vertexNormals[a].applyMatrix3(i).normalize()}return null!==this.boundingBox&&this.computeBoundingBox(),null!==this.boundingSphere&&this.computeBoundingSphere(),this.verticesNeedUpdate=!0,this.normalsNeedUpdate=!0,this},rotateX:function(){var t=new v;return function(e){return t.makeRotationX(e),this.applyMatrix(t),this}}(),rotateY:function(){var t=new v;return function(e){return t.makeRotationY(e),this.applyMatrix(t),this}}(),rotateZ:function(){var t=new v;return function(e){return t.makeRotationZ(e),this.applyMatrix(t),this}}(),translate:function(){var t=new v;return function(e,i,r){return t.makeTranslation(e,i,r),this.applyMatrix(t),this}}(),scale:function(){var t=new v;return function(e,i,r){return t.makeScale(e,i,r),this.applyMatrix(t),this}}(),lookAt:function(){var t=new gt;return function(e){t.lookAt(e),t.updateMatrix(),this.applyMatrix(t.matrix)}}(),fromBufferGeometry:function(t){function e(t,e,r,n){var o=new bt(t,e,r,void 0!==a?[h[t].clone(),h[e].clone(),h[r].clone()]:[],void 0!==s?[i.colors[t].clone(),i.colors[e].clone(),i.colors[r].clone()]:[],n);i.faces.push(o),void 0!==c&&i.faceVertexUvs[0].push([p[t].clone(),p[e].clone(),p[r].clone()]),void 0!==u&&i.faceVertexUvs[1].push([d[t].clone(),d[e].clone(),d[r].clone()])}var i=this,r=null!==t.index?t.index.array:void 0,n=t.attributes,o=n.position.array,a=void 0!==n.normal?n.normal.array:void 0,s=void 0!==n.color?n.color.array:void 0,c=void 0!==n.uv?n.uv.array:void 0,u=void 0!==n.uv2?n.uv2.array:void 0;void 0!==u&&(this.faceVertexUvs[1]=[]);for(var h=[],p=[],d=[],f=0,m=0;f<o.length;f+=3,m+=2)i.vertices.push(new g(o[f],o[f+1],o[f+2])),void 0!==a&&h.push(new g(a[f],a[f+1],a[f+2])),void 0!==s&&i.colors.push(new tt(s[f],s[f+1],s[f+2])),void 0!==c&&p.push(new l(c[m],c[m+1])),void 0!==u&&d.push(new l(u[m],u[m+1]));var v=t.groups;if(v.length>0)for(f=0;f<v.length;f++)for(var y=v[f],b=y.start,m=b,x=b+y.count;m<x;m+=3)void 0!==r?e(r[m],r[m+1],r[m+2],y.materialIndex):e(m,m+1,m+2,y.materialIndex);else if(void 0!==r)for(f=0;f<r.length;f+=3)e(r[f],r[f+1],r[f+2]);else for(f=0;f<o.length/3;f+=3)e(f,f+1,f+2);return this.computeFaceNormals(),null!==t.boundingBox&&(this.boundingBox=t.boundingBox.clone()),null!==t.boundingSphere&&(this.boundingSphere=t.boundingSphere.clone()),this},center:function(){this.computeBoundingBox();var t=this.boundingBox.getCenter().negate();return this.translate(t.x,t.y,t.z),t},normalize:function(){this.computeBoundingSphere();var t=this.boundingSphere.center,e=this.boundingSphere.radius,i=0===e?1:1/e,r=new v;return r.set(i,0,0,-i*t.x,0,i,0,-i*t.y,0,0,i,-i*t.z,0,0,0,1),this.applyMatrix(r),this},computeFaceNormals:function(){for(var t=this,e=new g,i=new g,r=0,n=this.faces.length;r<n;r++){var o=t.faces[r],a=t.vertices[o.a],s=t.vertices[o.b],c=t.vertices[o.c];e.subVectors(c,s),i.subVectors(a,s),e.cross(i),e.normalize(),o.normal.copy(e)}},computeVertexNormals:function(t){var e=this;void 0===t&&(t=!0);var i,r,n,o,a,s;for(s=new Array(this.vertices.length),i=0,r=this.vertices.length;i<r;i++)s[i]=new g;if(t){var c,u,h,l=new g,p=new g;for(n=0,o=this.faces.length;n<o;n++)a=e.faces[n],c=e.vertices[a.a],u=e.vertices[a.b],h=e.vertices[a.c],l.subVectors(h,u),p.subVectors(c,u),l.cross(p),s[a.a].add(l),s[a.b].add(l),s[a.c].add(l)}else for(this.computeFaceNormals(),n=0,o=this.faces.length;n<o;n++)s[(a=e.faces[n]).a].add(a.normal),s[a.b].add(a.normal),s[a.c].add(a.normal);for(i=0,r=this.vertices.length;i<r;i++)s[i].normalize();for(n=0,o=this.faces.length;n<o;n++){var d=(a=e.faces[n]).vertexNormals;3===d.length?(d[0].copy(s[a.a]),d[1].copy(s[a.b]),d[2].copy(s[a.c])):(d[0]=s[a.a].clone(),d[1]=s[a.b].clone(),d[2]=s[a.c].clone())}this.faces.length>0&&(this.normalsNeedUpdate=!0)},computeFlatVertexNormals:function(){var t,e,i,r=this;for(this.computeFaceNormals(),t=0,e=this.faces.length;t<e;t++){var n=(i=r.faces[t]).vertexNormals;3===n.length?(n[0].copy(i.normal),n[1].copy(i.normal),n[2].copy(i.normal)):(n[0]=i.normal.clone(),n[1]=i.normal.clone(),n[2]=i.normal.clone())}this.faces.length>0&&(this.normalsNeedUpdate=!0)},computeMorphNormals:function(){var t,e,i,r,n,o=this;for(i=0,r=this.faces.length;i<r;i++)for((n=o.faces[i]).__originalFaceNormal?n.__originalFaceNormal.copy(n.normal):n.__originalFaceNormal=n.normal.clone(),n.__originalVertexNormals||(n.__originalVertexNormals=[]),t=0,e=n.vertexNormals.length;t<e;t++)n.__originalVertexNormals[t]?n.__originalVertexNormals[t].copy(n.vertexNormals[t]):n.__originalVertexNormals[t]=n.vertexNormals[t].clone();var a=new Et;for(a.faces=this.faces,t=0,e=this.morphTargets.length;t<e;t++){if(!o.morphNormals[t]){o.morphNormals[t]={},o.morphNormals[t].faceNormals=[],o.morphNormals[t].vertexNormals=[];var s=o.morphNormals[t].faceNormals,c=o.morphNormals[t].vertexNormals;for(i=0,r=this.faces.length;i<r;i++)h=new g,l={a:new g,b:new g,c:new g},s.push(h),c.push(l)}var u=o.morphNormals[t];a.vertices=o.morphTargets[t].vertices,a.computeFaceNormals(),a.computeVertexNormals();var h,l;for(i=0,r=this.faces.length;i<r;i++)n=o.faces[i],h=u.faceNormals[i],l=u.vertexNormals[i],h.copy(n.normal),l.a.copy(n.vertexNormals[0]),l.b.copy(n.vertexNormals[1]),l.c.copy(n.vertexNormals[2])}for(i=0,r=this.faces.length;i<r;i++)(n=o.faces[i]).normal=n.__originalFaceNormal,n.vertexNormals=n.__originalVertexNormals},computeLineDistances:function(){for(var t=this,e=0,i=this.vertices,r=0,n=i.length;r<n;r++)r>0&&(e+=i[r].distanceTo(i[r-1])),t.lineDistances[r]=e},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new st),this.boundingBox.setFromPoints(this.vertices)},computeBoundingSphere:function(){null===this.boundingSphere&&(this.boundingSphere=new ct),this.boundingSphere.setFromPoints(this.vertices)},merge:function(t,e,i){if(!1===(t&&t.isGeometry))return void console.error("THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.",t);var r,n=this.vertices.length,o=this.vertices,a=t.vertices,s=this.faces,c=t.faces,u=this.faceVertexUvs[0],h=t.faceVertexUvs[0],l=this.colors,p=t.colors;void 0===i&&(i=0),void 0!==e&&(r=(new ut).getNormalMatrix(e));for(var d=0,f=a.length;d<f;d++){var m=a[d].clone();void 0!==e&&m.applyMatrix4(e),o.push(m)}for(var d=0,f=p.length;d<f;d++)l.push(p[d].clone());for(d=0,f=c.length;d<f;d++){var g,v,y,b=c[d],x=b.vertexNormals,_=b.vertexColors;(g=new bt(b.a+n,b.b+n,b.c+n)).normal.copy(b.normal),void 0!==r&&g.normal.applyMatrix3(r).normalize();for(var w=0,S=x.length;w<S;w++)v=x[w].clone(),void 0!==r&&v.applyMatrix3(r).normalize(),g.vertexNormals.push(v);g.color.copy(b.color);for(var w=0,S=_.length;w<S;w++)y=_[w],g.vertexColors.push(y.clone());g.materialIndex=b.materialIndex+i,s.push(g)}for(d=0,f=h.length;d<f;d++){var A=h[d],M=[];if(void 0!==A){for(var w=0,S=A.length;w<S;w++)M.push(A[w].clone());u.push(M)}}},mergeMesh:function(t){if(!1===(t&&t.isMesh))return void console.error("THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.",t);t.matrixAutoUpdate&&t.updateMatrix(),this.merge(t.geometry,t.matrix)},mergeVertices:function(){var t,e,i,r,n,o,a,s,c=this,u={},h=[],l=[],p=Math.pow(10,4);for(i=0,r=this.vertices.length;i<r;i++)t=c.vertices[i],void 0===u[e=Math.round(t.x*p)+"_"+Math.round(t.y*p)+"_"+Math.round(t.z*p)]?(u[e]=i,h.push(c.vertices[i]),l[i]=h.length-1):l[i]=l[u[e]];var d=[];for(i=0,r=this.faces.length;i<r;i++){(n=c.faces[i]).a=l[n.a],n.b=l[n.b],n.c=l[n.c],o=[n.a,n.b,n.c];for(var f=0;f<3;f++)if(o[f]===o[(f+1)%3]){d.push(i);break}}for(i=d.length-1;i>=0;i--){var m=d[i];for(c.faces.splice(m,1),a=0,s=this.faceVertexUvs.length;a<s;a++)c.faceVertexUvs[a].splice(m,1)}var g=this.vertices.length-h.length;return this.vertices=h,g},sortFacesByMaterialIndex:function(){function t(t,e){return t.materialIndex-e.materialIndex}for(var e=this.faces,i=e.length,r=0;r<i;r++)e[r]._id=r;e.sort(t);var n,o,a=this.faceVertexUvs[0],s=this.faceVertexUvs[1];a&&a.length===i&&(n=[]),s&&s.length===i&&(o=[]);for(r=0;r<i;r++){var c=e[r]._id;n&&n.push(a[c]),o&&o.push(s[c])}n&&(this.faceVertexUvs[0]=n),o&&(this.faceVertexUvs[1]=o)},toJSON:function(){function t(t,e,i){return i?t|1<<e:t&~(1<<e)}function e(t){var e=t.x.toString()+t.y.toString()+t.z.toString();return void 0!==d[e]?d[e]:(d[e]=p.length/3,p.push(t.x,t.y,t.z),d[e])}function i(t){var e=t.r.toString()+t.g.toString()+t.b.toString();return void 0!==m[e]?m[e]:(m[e]=f.length,f.push(t.getHex()),m[e])}function r(t){var e=t.x.toString()+t.y.toString();return void 0!==v[e]?v[e]:(v[e]=g.length/2,g.push(t.x,t.y),v[e])}var n=this,o={metadata:{version:4.5,type:"Geometry",generator:"Geometry.toJSON"}};if(o.uuid=this.uuid,o.type=this.type,""!==this.name&&(o.name=this.name),void 0!==this.parameters){var a=this.parameters;for(var s in a)void 0!==a[s]&&(o[s]=a[s]);return o}for(var c=[],u=0;u<this.vertices.length;u++){var h=n.vertices[u];c.push(h.x,h.y,h.z)}for(var l=[],p=[],d={},f=[],m={},g=[],v={},u=0;u<this.faces.length;u++){var y=n.faces[u],b=void 0!==n.faceVertexUvs[0][u],x=y.normal.length()>0,_=y.vertexNormals.length>0,w=1!==y.color.r||1!==y.color.g||1!==y.color.b,S=y.vertexColors.length>0,A=0;if(A=t(A,0,0),A=t(A,1,!0),A=t(A,2,!1),A=t(A,3,b),A=t(A,4,x),A=t(A,5,_),A=t(A,6,w),A=t(A,7,S),l.push(A),l.push(y.a,y.b,y.c),l.push(y.materialIndex),b){var M=n.faceVertexUvs[0][u];l.push(r(M[0]),r(M[1]),r(M[2]))}if(x&&l.push(e(y.normal)),_){var P=y.vertexNormals;l.push(e(P[0]),e(P[1]),e(P[2]))}if(w&&l.push(i(y.color)),S){var T=y.vertexColors;l.push(i(T[0]),i(T[1]),i(T[2]))}}return o.data={},o.data.vertices=c,o.data.normals=p,f.length>0&&(o.data.colors=f),g.length>0&&(o.data.uvs=[g]),o.data.faces=l,o},clone:function(){return(new Et).copy(this)},copy:function(t){var e,i,r,n,o,a,s=this;this.vertices=[],this.colors=[],this.faces=[],this.faceVertexUvs=[[]],this.morphTargets=[],this.morphNormals=[],this.skinWeights=[],this.skinIndices=[],this.lineDistances=[],this.boundingBox=null,this.boundingSphere=null,this.name=t.name;var c=t.vertices;for(e=0,i=c.length;e<i;e++)s.vertices.push(c[e].clone());var u=t.colors;for(e=0,i=u.length;e<i;e++)s.colors.push(u[e].clone());var h=t.faces;for(e=0,i=h.length;e<i;e++)s.faces.push(h[e].clone());for(e=0,i=t.faceVertexUvs.length;e<i;e++){var l=t.faceVertexUvs[e];for(void 0===s.faceVertexUvs[e]&&(s.faceVertexUvs[e]=[]),r=0,n=l.length;r<n;r++){var p=l[r],d=[];for(o=0,a=p.length;o<a;o++){var f=p[o];d.push(f.clone())}s.faceVertexUvs[e].push(d)}}var m=t.morphTargets;for(e=0,i=m.length;e<i;e++){var g={};if(g.name=m[e].name,void 0!==m[e].vertices)for(g.vertices=[],r=0,n=m[e].vertices.length;r<n;r++)g.vertices.push(m[e].vertices[r].clone());if(void 0!==m[e].normals)for(g.normals=[],r=0,n=m[e].normals.length;r<n;r++)g.normals.push(m[e].normals[r].clone());s.morphTargets.push(g)}var v=t.morphNormals;for(e=0,i=v.length;e<i;e++){var y={};if(void 0!==v[e].vertexNormals)for(y.vertexNormals=[],r=0,n=v[e].vertexNormals.length;r<n;r++){var b=v[e].vertexNormals[r],x={};x.a=b.a.clone(),x.b=b.b.clone(),x.c=b.c.clone(),y.vertexNormals.push(x)}if(void 0!==v[e].faceNormals)for(y.faceNormals=[],r=0,n=v[e].faceNormals.length;r<n;r++)y.faceNormals.push(v[e].faceNormals[r].clone());s.morphNormals.push(y)}var _=t.skinWeights;for(e=0,i=_.length;e<i;e++)s.skinWeights.push(_[e].clone());var w=t.skinIndices;for(e=0,i=w.length;e<i;e++)s.skinIndices.push(w[e].clone());var S=t.lineDistances;for(e=0,i=S.length;e<i;e++)s.lineDistances.push(S[e]);var A=t.boundingBox;null!==A&&(this.boundingBox=A.clone());var M=t.boundingSphere;return null!==M&&(this.boundingSphere=M.clone()),this.elementsNeedUpdate=t.elementsNeedUpdate,this.verticesNeedUpdate=t.verticesNeedUpdate,this.uvsNeedUpdate=t.uvsNeedUpdate,this.normalsNeedUpdate=t.normalsNeedUpdate,this.colorsNeedUpdate=t.colorsNeedUpdate,this.lineDistancesNeedUpdate=t.lineDistancesNeedUpdate,this.groupsNeedUpdate=t.groupsNeedUpdate,this},dispose:function(){this.dispatchEvent({type:"dispose"})}}),Ct.MaxIndex=65535,Object.assign(Ct.prototype,h.prototype,{isBufferGeometry:!0,getIndex:function(){return this.index},setIndex:function(t){Array.isArray(t)?this.index=new(Pt(t)>65535?St:wt)(t,1):this.index=t},addAttribute:function(t,e){return!1===(e&&e.isBufferAttribute)&&!1===(e&&e.isInterleavedBufferAttribute)?(console.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),void this.addAttribute(t,new _t(arguments[1],arguments[2]))):"index"===t?(console.warn("THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute."),void this.setIndex(e)):(this.attributes[t]=e,this)},getAttribute:function(t){return this.attributes[t]},removeAttribute:function(t){return delete this.attributes[t],this},addGroup:function(t,e,i){this.groups.push({start:t,count:e,materialIndex:void 0!==i?i:0})},clearGroups:function(){this.groups=[]},setDrawRange:function(t,e){this.drawRange.start=t,this.drawRange.count=e},applyMatrix:function(t){var e=this.attributes.position;void 0!==e&&(t.applyToBufferAttribute(e),e.needsUpdate=!0);var i=this.attributes.normal;return void 0!==i&&((new ut).getNormalMatrix(t).applyToBufferAttribute(i),i.needsUpdate=!0),null!==this.boundingBox&&this.computeBoundingBox(),null!==this.boundingSphere&&this.computeBoundingSphere(),this},rotateX:function(){var t=new v;return function(e){return t.makeRotationX(e),this.applyMatrix(t),this}}(),rotateY:function(){var t=new v;return function(e){return t.makeRotationY(e),this.applyMatrix(t),this}}(),rotateZ:function(){var t=new v;return function(e){return t.makeRotationZ(e),this.applyMatrix(t),this}}(),translate:function(){var t=new v;return function(e,i,r){return t.makeTranslation(e,i,r),this.applyMatrix(t),this}}(),scale:function(){var t=new v;return function(e,i,r){return t.makeScale(e,i,r),this.applyMatrix(t),this}}(),lookAt:function(){var t=new gt;return function(e){t.lookAt(e),t.updateMatrix(),this.applyMatrix(t.matrix)}}(),center:function(){this.computeBoundingBox();var t=this.boundingBox.getCenter().negate();return this.translate(t.x,t.y,t.z),t},setFromObject:function(t){var e=t.geometry;if(t.isPoints||t.isLine){var i=new At(3*e.vertices.length,3),r=new At(3*e.colors.length,3);if(this.addAttribute("position",i.copyVector3sArray(e.vertices)),this.addAttribute("color",r.copyColorsArray(e.colors)),e.lineDistances&&e.lineDistances.length===e.vertices.length){var n=new At(e.lineDistances.length,1);this.addAttribute("lineDistance",n.copyArray(e.lineDistances))}null!==e.boundingSphere&&(this.boundingSphere=e.boundingSphere.clone()),null!==e.boundingBox&&(this.boundingBox=e.boundingBox.clone())}else t.isMesh&&e&&e.isGeometry&&this.fromGeometry(e);return this},updateFromObject:function(t){var e=t.geometry;if(t.isMesh){var i=e.__directGeometry;if(!0===e.elementsNeedUpdate&&(i=void 0,e.elementsNeedUpdate=!1),void 0===i)return this.fromGeometry(e);i.verticesNeedUpdate=e.verticesNeedUpdate,i.normalsNeedUpdate=e.normalsNeedUpdate,i.colorsNeedUpdate=e.colorsNeedUpdate,i.uvsNeedUpdate=e.uvsNeedUpdate,i.groupsNeedUpdate=e.groupsNeedUpdate,e.verticesNeedUpdate=!1,e.normalsNeedUpdate=!1,e.colorsNeedUpdate=!1,e.uvsNeedUpdate=!1,e.groupsNeedUpdate=!1,e=i}var r;return!0===e.verticesNeedUpdate&&(void 0!==(r=this.attributes.position)&&(r.copyVector3sArray(e.vertices),r.needsUpdate=!0),e.verticesNeedUpdate=!1),!0===e.normalsNeedUpdate&&(void 0!==(r=this.attributes.normal)&&(r.copyVector3sArray(e.normals),r.needsUpdate=!0),e.normalsNeedUpdate=!1),!0===e.colorsNeedUpdate&&(void 0!==(r=this.attributes.color)&&(r.copyColorsArray(e.colors),r.needsUpdate=!0),e.colorsNeedUpdate=!1),e.uvsNeedUpdate&&(void 0!==(r=this.attributes.uv)&&(r.copyVector2sArray(e.uvs),r.needsUpdate=!0),e.uvsNeedUpdate=!1),e.lineDistancesNeedUpdate&&(void 0!==(r=this.attributes.lineDistance)&&(r.copyArray(e.lineDistances),r.needsUpdate=!0),e.lineDistancesNeedUpdate=!1),e.groupsNeedUpdate&&(e.computeGroups(t.geometry),this.groups=e.groups,e.groupsNeedUpdate=!1),this},fromGeometry:function(t){return t.__directGeometry=(new Mt).fromGeometry(t),this.fromDirectGeometry(t.__directGeometry)},fromDirectGeometry:function(t){var e=this,i=new Float32Array(3*t.vertices.length);if(this.addAttribute("position",new _t(i,3).copyVector3sArray(t.vertices)),t.normals.length>0){var r=new Float32Array(3*t.normals.length);this.addAttribute("normal",new _t(r,3).copyVector3sArray(t.normals))}if(t.colors.length>0){var n=new Float32Array(3*t.colors.length);this.addAttribute("color",new _t(n,3).copyColorsArray(t.colors))}if(t.uvs.length>0){var o=new Float32Array(2*t.uvs.length);this.addAttribute("uv",new _t(o,2).copyVector2sArray(t.uvs))}if(t.uvs2.length>0){var a=new Float32Array(2*t.uvs2.length);this.addAttribute("uv2",new _t(a,2).copyVector2sArray(t.uvs2))}if(t.indices.length>0){var s=new(Pt(t.indices)>65535?Uint32Array:Uint16Array)(3*t.indices.length);this.setIndex(new _t(s,1).copyIndicesArray(t.indices))}this.groups=t.groups;for(var c in t.morphTargets){for(var u=[],h=t.morphTargets[c],l=0,p=h.length;l<p;l++){var d=h[l],f=new At(3*d.length,3);u.push(f.copyVector3sArray(d))}e.morphAttributes[c]=u}if(t.skinIndices.length>0){var m=new At(4*t.skinIndices.length,4);this.addAttribute("skinIndex",m.copyVector4sArray(t.skinIndices))}if(t.skinWeights.length>0){var g=new At(4*t.skinWeights.length,4);this.addAttribute("skinWeight",g.copyVector4sArray(t.skinWeights))}return null!==t.boundingSphere&&(this.boundingSphere=t.boundingSphere.clone()),null!==t.boundingBox&&(this.boundingBox=t.boundingBox.clone()),this},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new st);var t=this.attributes.position;void 0!==t?this.boundingBox.setFromBufferAttribute(t):this.boundingBox.makeEmpty(),(isNaN(this.boundingBox.min.x)||isNaN(this.boundingBox.min.y)||isNaN(this.boundingBox.min.z))&&console.error('THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.',this)},computeBoundingSphere:function(){var t=new st,e=new g;return function(){null===this.boundingSphere&&(this.boundingSphere=new ct);var i=this.attributes.position;if(i){var r=this.boundingSphere.center;t.setFromBufferAttribute(i),t.getCenter(r);for(var n=0,o=0,a=i.count;o<a;o++)e.x=i.getX(o),e.y=i.getY(o),e.z=i.getZ(o),n=Math.max(n,r.distanceToSquared(e));this.boundingSphere.radius=Math.sqrt(n),isNaN(this.boundingSphere.radius)&&console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.',this)}}}(),computeFaceNormals:function(){},computeVertexNormals:function(){var t=this.index,e=this.attributes,i=this.groups;if(e.position){var r=e.position.array;if(void 0===e.normal)this.addAttribute("normal",new _t(new Float32Array(r.length),3));else for(var n=e.normal.array,o=0,a=n.length;o<a;o++)n[o]=0;var s,c,u,h=e.normal.array,l=new g,p=new g,d=new g,f=new g,m=new g;if(t){var v=t.array;0===i.length&&this.addGroup(0,v.length);for(var y=0,b=i.length;y<b;++y)for(var x=i[y],_=x.start,o=_,a=_+x.count;o<a;o+=3)s=3*v[o+0],c=3*v[o+1],u=3*v[o+2],l.fromArray(r,s),p.fromArray(r,c),d.fromArray(r,u),f.subVectors(d,p),m.subVectors(l,p),f.cross(m),h[s]+=f.x,h[s+1]+=f.y,h[s+2]+=f.z,h[c]+=f.x,h[c+1]+=f.y,h[c+2]+=f.z,h[u]+=f.x,h[u+1]+=f.y,h[u+2]+=f.z}else for(var o=0,a=r.length;o<a;o+=9)l.fromArray(r,o),p.fromArray(r,o+3),d.fromArray(r,o+6),f.subVectors(d,p),m.subVectors(l,p),f.cross(m),h[o]=f.x,h[o+1]=f.y,h[o+2]=f.z,h[o+3]=f.x,h[o+4]=f.y,h[o+5]=f.z,h[o+6]=f.x,h[o+7]=f.y,h[o+8]=f.z;this.normalizeNormals(),e.normal.needsUpdate=!0}},merge:function(t,e){if(!1===(t&&t.isBufferGeometry))return void console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",t);void 0===e&&(e=0);var i=this.attributes;for(var r in i)if(void 0!==t.attributes[r])for(var n=i[r].array,o=t.attributes[r],a=o.array,s=0,c=o.itemSize*e;s<a.length;s++,c++)n[c]=a[s];return this},normalizeNormals:function(){for(var t,e,i,r,n=this.attributes.normal,o=0,a=n.count;o<a;o++)t=n.getX(o),e=n.getY(o),i=n.getZ(o),r=1/Math.sqrt(t*t+e*e+i*i),n.setXYZ(o,t*r,e*r,i*r)},toNonIndexed:function(){if(null===this.index)return console.warn("THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed."),this;var t=new Ct,e=this.index.array,i=this.attributes;for(var r in i){for(var n=i[r],o=n.array,a=n.itemSize,s=new o.constructor(e.length*a),c=0,u=0,h=0,l=e.length;h<l;h++){c=e[h]*a;for(var p=0;p<a;p++)s[u++]=o[c++]}t.addAttribute(r,new _t(s,a))}return t},toJSON:function(){var t={metadata:{version:4.5,type:"BufferGeometry",generator:"BufferGeometry.toJSON"}};if(t.uuid=this.uuid,t.type=this.type,""!==this.name&&(t.name=this.name),void 0!==this.parameters){var e=this.parameters;for(var i in e)void 0!==e[i]&&(t[i]=e[i]);return t}t.data={attributes:{}};var r=this.index;if(null!==r){a=Array.prototype.slice.call(r.array);t.data.index={type:r.array.constructor.name,array:a}}var n=this.attributes;for(var i in n){var o=n[i],a=Array.prototype.slice.call(o.array);t.data.attributes[i]={itemSize:o.itemSize,type:o.array.constructor.name,array:a,normalized:o.normalized}}var s=this.groups;s.length>0&&(t.data.groups=JSON.parse(JSON.stringify(s)));var c=this.boundingSphere;return null!==c&&(t.data.boundingSphere={center:c.center.toArray(),radius:c.radius}),t},clone:function(){return(new Ct).copy(this)},copy:function(t){var e,i,r,n=this;this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null,this.name=t.name;var o=t.index;null!==o&&this.setIndex(o.clone());var a=t.attributes;for(e in a){var s=a[e];n.addAttribute(e,s.clone())}var c=t.morphAttributes;for(e in c){var u=[],h=c[e];for(i=0,r=h.length;i<r;i++)u.push(h[i].clone());n.morphAttributes[e]=u}var l=t.groups;for(i=0,r=l.length;i<r;i++){var p=l[i];n.addGroup(p.start,p.count,p.materialIndex)}var d=t.boundingBox;null!==d&&(this.boundingBox=d.clone());var f=t.boundingSphere;return null!==f&&(this.boundingSphere=f.clone()),this.drawRange.start=t.drawRange.start,this.drawRange.count=t.drawRange.count,this},dispose:function(){this.dispatchEvent({type:"dispose"})}}),It.prototype=Object.assign(Object.create(gt.prototype),{constructor:It,isMesh:!0,setDrawMode:function(t){this.drawMode=t},copy:function(t){return gt.prototype.copy.call(this,t),this.drawMode=t.drawMode,this},updateMorphTargets:function(){var t=this,e=this.geometry.morphTargets;if(void 0!==e&&e.length>0){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(var i=0,r=e.length;i<r;i++)t.morphTargetInfluences.push(0),t.morphTargetDictionary[e[i].name]=i}},raycast:function(){function t(t,e,i,r,n,o,a){return yt.barycoordFromPoint(t,e,i,r,y),n.multiplyScalar(y.x),o.multiplyScalar(y.y),a.multiplyScalar(y.z),n.add(o).add(a),n.clone()}function e(t,e,i,r,n,o,a){var s=t.material;if(null===(s.side===Mu?i.intersectTriangle(o,n,r,!0,a):i.intersectTriangle(r,n,o,s.side!==Pu,a)))return null;x.copy(a),x.applyMatrix4(t.matrixWorld);var c=e.ray.origin.distanceTo(x);return c<e.near||c>e.far?null:{distance:c,point:x.clone(),object:t}}function i(i,r,n,o,u,h,l,p){a.fromBufferAttribute(o,h),s.fromBufferAttribute(o,l),c.fromBufferAttribute(o,p);var g=e(i,r,n,a,s,c,b);return g&&(u&&(d.fromBufferAttribute(u,h),f.fromBufferAttribute(u,l),m.fromBufferAttribute(u,p),g.uv=t(b,a,s,c,d,f,m)),g.face=new bt(h,l,p,yt.normal(a,s,c)),g.faceIndex=h),g}var r=new v,n=new dt,o=new ct,a=new g,s=new g,c=new g,u=new g,h=new g,p=new g,d=new l,f=new l,m=new l,y=new g,b=new g,x=new g;return function(l,g){var v=this,y=this.geometry,x=this.material,_=this.matrixWorld;if(void 0!==x&&(null===y.boundingSphere&&y.computeBoundingSphere(),o.copy(y.boundingSphere),o.applyMatrix4(_),!1!==l.ray.intersectsSphere(o)&&(r.getInverse(_),n.copy(l.ray).applyMatrix4(r),null===y.boundingBox||!1!==n.intersectsBox(y.boundingBox)))){var w;if(y.isBufferGeometry){var S,A,M,P,T,E=y.index,C=y.attributes.position,I=y.attributes.uv;if(null!==E)for(P=0,T=E.count;P<T;P+=3)S=E.getX(P),A=E.getX(P+1),M=E.getX(P+2),(w=i(v,l,n,C,I,S,A,M))&&(w.faceIndex=Math.floor(P/3),g.push(w));else for(P=0,T=C.count;P<T;P+=3)(w=i(v,l,n,C,I,S=P,A=P+1,M=P+2))&&(w.index=S,g.push(w))}else if(y.isGeometry){var L,R,O,D,N=Array.isArray(x),k=y.vertices,B=y.faces,F=y.faceVertexUvs[0];F.length>0&&(D=F);for(var z=0,U=B.length;z<U;z++){var j=B[z],G=N?x[j.materialIndex]:x;if(void 0!==G){if(L=k[j.a],R=k[j.b],O=k[j.c],!0===G.morphTargets){var V=y.morphTargets,$=v.morphTargetInfluences;a.set(0,0,0),s.set(0,0,0),c.set(0,0,0);for(var H=0,W=V.length;H<W;H++){var X=$[H];if(0!==X){var q=V[H].vertices;a.addScaledVector(u.subVectors(q[j.a],L),X),s.addScaledVector(h.subVectors(q[j.b],R),X),c.addScaledVector(p.subVectors(q[j.c],O),X)}}a.add(L),s.add(R),c.add(O),L=a,R=s,O=c}if(w=e(v,l,n,L,R,O,b)){if(D&&D[z]){var Y=D[z];d.copy(Y[0]),f.copy(Y[1]),m.copy(Y[2]),w.uv=t(b,L,R,O,d,f,m)}w.face=j,w.faceIndex=z,g.push(w)}}}}}}}(),clone:function(){return new this.constructor(this.geometry,this.material).copy(this)}}),Lt.prototype=Object.create(Et.prototype),Lt.prototype.constructor=Lt,Rt.prototype=Object.create(Ct.prototype),Rt.prototype.constructor=Rt,Ot.prototype=Object.create(Et.prototype),Ot.prototype.constructor=Ot,Dt.prototype=Object.create(Ct.prototype),Dt.prototype.constructor=Dt,Nt.prototype=Object.assign(Object.create(gt.prototype),{constructor:Nt,isCamera:!0,copy:function(t){return gt.prototype.copy.call(this,t),this.matrixWorldInverse.copy(t.matrixWorldInverse),this.projectionMatrix.copy(t.projectionMatrix),this},getWorldDirection:function(){var t=new m;return function(e){var i=e||new g;return this.getWorldQuaternion(t),i.set(0,0,-1).applyQuaternion(t)}}(),clone:function(){return(new this.constructor).copy(this)}}),kt.prototype=Object.assign(Object.create(Nt.prototype),{constructor:kt,isPerspectiveCamera:!0,copy:function(t){return Nt.prototype.copy.call(this,t),this.fov=t.fov,this.zoom=t.zoom,this.near=t.near,this.far=t.far,this.focus=t.focus,this.aspect=t.aspect,this.view=null===t.view?null:Object.assign({},t.view),this.filmGauge=t.filmGauge,this.filmOffset=t.filmOffset,this},setFocalLength:function(t){var e=.5*this.getFilmHeight()/t;this.fov=2*xl.RAD2DEG*Math.atan(e),this.updateProjectionMatrix()},getFocalLength:function(){var t=Math.tan(.5*xl.DEG2RAD*this.fov);return.5*this.getFilmHeight()/t},getEffectiveFOV:function(){return 2*xl.RAD2DEG*Math.atan(Math.tan(.5*xl.DEG2RAD*this.fov)/this.zoom)},getFilmWidth:function(){return this.filmGauge*Math.min(this.aspect,1)},getFilmHeight:function(){return this.filmGauge/Math.max(this.aspect,1)},setViewOffset:function(t,e,i,r,n,o){this.aspect=t/e,this.view={fullWidth:t,fullHeight:e,offsetX:i,offsetY:r,width:n,height:o},this.updateProjectionMatrix()},clearViewOffset:function(){this.view=null,this.updateProjectionMatrix()},updateProjectionMatrix:function(){var t=this.near,e=t*Math.tan(.5*xl.DEG2RAD*this.fov)/this.zoom,i=2*e,r=this.aspect*i,n=-.5*r,o=this.view;if(null!==o){var a=o.fullWidth,s=o.fullHeight;n+=o.offsetX*r/a,e-=o.offsetY*i/s,r*=o.width/a,i*=o.height/s}var c=this.filmOffset;0!==c&&(n+=t*c/this.getFilmWidth()),this.projectionMatrix.makePerspective(n,n+r,e,e-i,t,this.far)},toJSON:function(t){var e=gt.prototype.toJSON.call(this,t);return e.object.fov=this.fov,e.object.zoom=this.zoom,e.object.near=this.near,e.object.far=this.far,e.object.focus=this.focus,e.object.aspect=this.aspect,null!==this.view&&(e.object.view=Object.assign({},this.view)),e.object.filmGauge=this.filmGauge,e.object.filmOffset=this.filmOffset,e}}),Bt.prototype=Object.assign(Object.create(Nt.prototype),{constructor:Bt,isOrthographicCamera:!0,copy:function(t){return Nt.prototype.copy.call(this,t),this.left=t.left,this.right=t.right,this.top=t.top,this.bottom=t.bottom,this.near=t.near,this.far=t.far,this.zoom=t.zoom,this.view=null===t.view?null:Object.assign({},t.view),this},setViewOffset:function(t,e,i,r,n,o){this.view={fullWidth:t,fullHeight:e,offsetX:i,offsetY:r,width:n,height:o},this.updateProjectionMatrix()},clearViewOffset:function(){this.view=null,this.updateProjectionMatrix()},updateProjectionMatrix:function(){var t=(this.right-this.left)/(2*this.zoom),e=(this.top-this.bottom)/(2*this.zoom),i=(this.right+this.left)/2,r=(this.top+this.bottom)/2,n=i-t,o=i+t,a=r+e,s=r-e;if(null!==this.view){var c=this.zoom/(this.view.width/this.view.fullWidth),u=this.zoom/(this.view.height/this.view.fullHeight),h=(this.right-this.left)/this.view.width,l=(this.top-this.bottom)/this.view.height;o=(n+=h*(this.view.offsetX/c))+h*(this.view.width/c),s=(a-=l*(this.view.offsetY/u))-l*(this.view.height/u)}this.projectionMatrix.makeOrthographic(n,o,a,s,this.near,this.far)},toJSON:function(t){var e=gt.prototype.toJSON.call(this,t);return e.object.zoom=this.zoom,e.object.left=this.left,e.object.right=this.right,e.object.top=this.top,e.object.bottom=this.bottom,e.object.near=this.near,e.object.far=this.far,null!==this.view&&(e.object.view=Object.assign({},this.view)),e}});var Bl=0;ge.prototype.isFogExp2=!0,ge.prototype.clone=function(){return new ge(this.color.getHex(),this.density)},ge.prototype.toJSON=function(t){return{type:"FogExp2",color:this.color.getHex(),density:this.density}},ve.prototype.isFog=!0,ve.prototype.clone=function(){return new ve(this.color.getHex(),this.near,this.far)},ve.prototype.toJSON=function(t){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}},ye.prototype=Object.assign(Object.create(gt.prototype),{constructor:ye,copy:function(t,e){return gt.prototype.copy.call(this,t,e),null!==t.background&&(this.background=t.background.clone()),null!==t.fog&&(this.fog=t.fog.clone()),null!==t.overrideMaterial&&(this.overrideMaterial=t.overrideMaterial.clone()),this.autoUpdate=t.autoUpdate,this.matrixAutoUpdate=t.matrixAutoUpdate,this},toJSON:function(t){var e=gt.prototype.toJSON.call(this,t);return null!==this.background&&(e.object.background=this.background.toJSON(t)),null!==this.fog&&(e.object.fog=this.fog.toJSON()),e}}),be.prototype=Object.assign(Object.create(gt.prototype),{constructor:be,isLensFlare:!0,copy:function(t){var e=this;gt.prototype.copy.call(this,t),this.positionScreen.copy(t.positionScreen),this.customUpdateCallback=t.customUpdateCallback;for(var i=0,r=t.lensFlares.length;i<r;i++)e.lensFlares.push(t.lensFlares[i]);return this},add:function(t,e,i,r,n,o){void 0===e&&(e=-1),void 0===i&&(i=0),void 0===o&&(o=1),void 0===n&&(n=new tt(16777215)),void 0===r&&(r=Ou),i=Math.min(i,Math.max(0,i)),this.lensFlares.push({texture:t,size:e,distance:i,x:0,y:0,z:0,scale:1,rotation:0,opacity:o,color:n,blending:r})},updateLensFlares:function(){var t,e,i=this,r=this.lensFlares.length,n=2*-this.positionScreen.x,o=2*-this.positionScreen.y;for(t=0;t<r;t++)(e=i.lensFlares[t]).x=i.positionScreen.x+n*e.distance,e.y=i.positionScreen.y+o*e.distance,e.wantedRotation=e.x*Math.PI*.25,e.rotation+=.25*(e.wantedRotation-e.rotation)}}),xe.prototype=Object.create(nt.prototype),xe.prototype.constructor=xe,xe.prototype.isSpriteMaterial=!0,xe.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.color.copy(t.color),this.map=t.map,this.rotation=t.rotation,this},_e.prototype=Object.assign(Object.create(gt.prototype),{constructor:_e,isSprite:!0,raycast:function(){var t=new g,e=new g,i=new g;return function(r,n){e.setFromMatrixPosition(this.matrixWorld),r.ray.closestPointToPoint(e,t),i.setFromMatrixScale(this.matrixWorld);var o=i.x*i.y/4;if(!(e.distanceToSquared(t)>o)){var a=r.ray.origin.distanceTo(t);a<r.near||a>r.far||n.push({distance:a,point:t.clone(),face:null,object:this})}}}(),clone:function(){return new this.constructor(this.material).copy(this)}}),we.prototype=Object.assign(Object.create(gt.prototype),{constructor:we,copy:function(t){var e=this;gt.prototype.copy.call(this,t,!1);for(var i=t.levels,r=0,n=i.length;r<n;r++){var o=i[r];e.addLevel(o.object.clone(),o.distance)}return this},addLevel:function(t,e){void 0===e&&(e=0),e=Math.abs(e);for(var i=this.levels,r=0;r<i.length&&!(e<i[r].distance);r++);i.splice(r,0,{distance:e,object:t}),this.add(t)},getObjectForDistance:function(t){for(var e=this.levels,i=1,r=e.length;i<r&&!(t<e[i].distance);i++);return e[i-1].object},raycast:function(){var t=new g;return function(e,i){t.setFromMatrixPosition(this.matrixWorld);var r=e.ray.origin.distanceTo(t);this.getObjectForDistance(r).raycast(e,i)}}(),update:function(){var t=new g,e=new g;return function(i){var r=this.levels;if(r.length>1){t.setFromMatrixPosition(i.matrixWorld),e.setFromMatrixPosition(this.matrixWorld);var n=t.distanceTo(e);r[0].object.visible=!0;for(var o=1,a=r.length;o<a&&n>=r[o].distance;o++)r[o-1].object.visible=!1,r[o].object.visible=!0;for(;o<a;o++)r[o].object.visible=!1}}}(),toJSON:function(t){var e=gt.prototype.toJSON.call(this,t);e.object.levels=[];for(var i=this.levels,r=0,n=i.length;r<n;r++){var o=i[r];e.object.levels.push({object:o.object.uuid,distance:o.distance})}return e}}),Object.assign(Se.prototype,{calculateInverses:function(){var t=this;this.boneInverses=[];for(var e=0,i=this.bones.length;e<i;e++){var r=new v;t.bones[e]&&r.getInverse(t.bones[e].matrixWorld),t.boneInverses.push(r)}},pose:function(){var t,e,i,r=this;for(e=0,i=this.bones.length;e<i;e++)(t=r.bones[e])&&t.matrixWorld.getInverse(r.boneInverses[e]);for(e=0,i=this.bones.length;e<i;e++)(t=r.bones[e])&&(t.parent&&t.parent.isBone?(t.matrix.getInverse(t.parent.matrixWorld),t.matrix.multiply(t.matrixWorld)):t.matrix.copy(t.matrixWorld),t.matrix.decompose(t.position,t.quaternion,t.scale))},update:function(){var t=new v,e=new v;return function(){for(var i=this.bones,r=this.boneInverses,n=this.boneMatrices,o=this.boneTexture,a=0,s=i.length;a<s;a++){var c=i[a]?i[a].matrixWorld:e;t.multiplyMatrices(c,r[a]),t.toArray(n,16*a)}void 0!==o&&(o.needsUpdate=!0)}}(),clone:function(){return new Se(this.bones,this.boneInverses)}}),Ae.prototype=Object.assign(Object.create(gt.prototype),{constructor:Ae,isBone:!0}),Me.prototype=Object.assign(Object.create(It.prototype),{constructor:Me,isSkinnedMesh:!0,initBones:function(){var t,e,i,r,n=this,o=[];if(this.geometry&&void 0!==this.geometry.bones){for(i=0,r=this.geometry.bones.length;i<r;i++)e=n.geometry.bones[i],t=new Ae,o.push(t),t.name=e.name,t.position.fromArray(e.pos),t.quaternion.fromArray(e.rotq),void 0!==e.scl&&t.scale.fromArray(e.scl);for(i=0,r=this.geometry.bones.length;i<r;i++)-1!==(e=n.geometry.bones[i]).parent&&null!==e.parent&&void 0!==o[e.parent]?o[e.parent].add(o[i]):n.add(o[i])}return this.updateMatrixWorld(!0),o},bind:function(t,e){this.skeleton=t,void 0===e&&(this.updateMatrixWorld(!0),this.skeleton.calculateInverses(),e=this.matrixWorld),this.bindMatrix.copy(e),this.bindMatrixInverse.getInverse(e)},pose:function(){this.skeleton.pose()},normalizeSkinWeights:function(){var t,e,i=this;if(this.geometry&&this.geometry.isGeometry)for(e=0;e<this.geometry.skinWeights.length;e++){var r=i.geometry.skinWeights[e];(t=1/r.lengthManhattan())!==1/0?r.multiplyScalar(t):r.set(1,0,0,0)}else if(this.geometry&&this.geometry.isBufferGeometry){var n=new d,o=this.geometry.attributes.skinWeight;for(e=0;e<o.count;e++)n.x=o.getX(e),n.y=o.getY(e),n.z=o.getZ(e),n.w=o.getW(e),(t=1/n.lengthManhattan())!==1/0?n.multiplyScalar(t):n.set(1,0,0,0),o.setXYZW(e,n.x,n.y,n.z,n.w)}},updateMatrixWorld:function(t){It.prototype.updateMatrixWorld.call(this,t),"attached"===this.bindMode?this.bindMatrixInverse.getInverse(this.matrixWorld):"detached"===this.bindMode?this.bindMatrixInverse.getInverse(this.bindMatrix):console.warn("THREE.SkinnedMesh: Unrecognized bindMode: "+this.bindMode)},clone:function(){return new this.constructor(this.geometry,this.material).copy(this)}}),Pe.prototype=Object.create(nt.prototype),Pe.prototype.constructor=Pe,Pe.prototype.isLineBasicMaterial=!0,Pe.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.color.copy(t.color),this.linewidth=t.linewidth,this.linecap=t.linecap,this.linejoin=t.linejoin,this},Te.prototype=Object.assign(Object.create(gt.prototype),{constructor:Te,isLine:!0,raycast:function(){var t=new v,e=new dt,i=new ct;return function(r,n){var o=this,a=r.linePrecision,s=a*a,c=this.geometry,u=this.matrixWorld;if(null===c.boundingSphere&&c.computeBoundingSphere(),i.copy(c.boundingSphere),i.applyMatrix4(u),!1!==r.ray.intersectsSphere(i)){t.getInverse(u),e.copy(r.ray).applyMatrix4(t);var h=new g,l=new g,p=new g,d=new g,f=this&&this.isLineSegments?2:1;if(c.isBufferGeometry){var m=c.index,v=c.attributes.position.array;if(null!==m)for(var y=m.array,b=0,x=y.length-1;b<x;b+=f){var _=y[b],w=y[b+1];h.fromArray(v,3*_),l.fromArray(v,3*w),(M=e.distanceSqToSegment(h,l,d,p))>s||(d.applyMatrix4(o.matrixWorld),(P=r.ray.origin.distanceTo(d))<r.near||P>r.far||n.push({distance:P,point:p.clone().applyMatrix4(o.matrixWorld),index:b,face:null,faceIndex:null,object:o}))}else for(var b=0,x=v.length/3-1;b<x;b+=f)h.fromArray(v,3*b),l.fromArray(v,3*b+3),(M=e.distanceSqToSegment(h,l,d,p))>s||(d.applyMatrix4(o.matrixWorld),(P=r.ray.origin.distanceTo(d))<r.near||P>r.far||n.push({distance:P,point:p.clone().applyMatrix4(o.matrixWorld),index:b,face:null,faceIndex:null,object:o}))}else if(c.isGeometry)for(var S=c.vertices,A=S.length,b=0;b<A-1;b+=f){var M=e.distanceSqToSegment(S[b],S[b+1],d,p);if(!(M>s)){d.applyMatrix4(o.matrixWorld);var P=r.ray.origin.distanceTo(d);P<r.near||P>r.far||n.push({distance:P,point:p.clone().applyMatrix4(o.matrixWorld),index:b,face:null,faceIndex:null,object:o})}}}}}(),clone:function(){return new this.constructor(this.geometry,this.material).copy(this)}}),Ee.prototype=Object.assign(Object.create(Te.prototype),{constructor:Ee,isLineSegments:!0}),Ce.prototype=Object.assign(Object.create(Te.prototype),{constructor:Ce,isLineLoop:!0}),Ie.prototype=Object.create(nt.prototype),Ie.prototype.constructor=Ie,Ie.prototype.isPointsMaterial=!0,Ie.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.color.copy(t.color),this.map=t.map,this.size=t.size,this.sizeAttenuation=t.sizeAttenuation,this},Le.prototype=Object.assign(Object.create(gt.prototype),{constructor:Le,isPoints:!0,raycast:function(){var t=new v,e=new dt,i=new ct;return function(r,n){function o(t,i){var o=e.distanceSqToPoint(t);if(o<l){var s=e.closestPointToPoint(t);s.applyMatrix4(c);var u=r.ray.origin.distanceTo(s);if(u<r.near||u>r.far)return;n.push({distance:u,distanceToRay:Math.sqrt(o),point:s.clone(),index:i,face:null,object:a})}}var a=this,s=this.geometry,c=this.matrixWorld,u=r.params.Points.threshold;if(null===s.boundingSphere&&s.computeBoundingSphere(),i.copy(s.boundingSphere),i.applyMatrix4(c),i.radius+=u,!1!==r.ray.intersectsSphere(i)){t.getInverse(c),e.copy(r.ray).applyMatrix4(t);var h=u/((this.scale.x+this.scale.y+this.scale.z)/3),l=h*h,p=new g;if(s.isBufferGeometry){var d=s.index,f=s.attributes.position.array;if(null!==d)for(var m=d.array,v=0,y=m.length;v<y;v++){var b=m[v];p.fromArray(f,3*b),o(p,b)}else for(var v=0,x=f.length/3;v<x;v++)p.fromArray(f,3*v),o(p,v)}else for(var _=s.vertices,v=0,x=_.length;v<x;v++)o(_[v],v)}}}(),clone:function(){return new this.constructor(this.geometry,this.material).copy(this)}}),Re.prototype=Object.assign(Object.create(gt.prototype),{constructor:Re}),Oe.prototype=Object.create(p.prototype),Oe.prototype.constructor=Oe,Oe.prototype.isCompressedTexture=!0,De.prototype=Object.create(p.prototype),De.prototype.constructor=De,Ne.prototype=Object.create(Ct.prototype),Ne.prototype.constructor=Ne,ke.prototype=Object.create(Et.prototype),ke.prototype.constructor=ke,Be.prototype=Object.create(Ct.prototype),Be.prototype.constructor=Be,Fe.prototype=Object.create(Et.prototype),Fe.prototype.constructor=Fe,ze.prototype=Object.create(Ct.prototype),ze.prototype.constructor=ze,Ue.prototype=Object.create(Et.prototype),Ue.prototype.constructor=Ue,je.prototype=Object.create(ze.prototype),je.prototype.constructor=je,Ge.prototype=Object.create(Et.prototype),Ge.prototype.constructor=Ge,Ve.prototype=Object.create(ze.prototype),Ve.prototype.constructor=Ve,$e.prototype=Object.create(Et.prototype),$e.prototype.constructor=$e,He.prototype=Object.create(ze.prototype),He.prototype.constructor=He,We.prototype=Object.create(Et.prototype),We.prototype.constructor=We,Xe.prototype=Object.create(ze.prototype),Xe.prototype.constructor=Xe,qe.prototype=Object.create(Et.prototype),qe.prototype.constructor=qe,Ye.prototype=Object.create(Ct.prototype),Ye.prototype.constructor=Ye,Ze.prototype=Object.create(Et.prototype),Ze.prototype.constructor=Ze,Ke.prototype=Object.create(Ct.prototype),Ke.prototype.constructor=Ke,Qe.prototype=Object.create(Et.prototype),Qe.prototype.constructor=Qe,Je.prototype=Object.create(Ct.prototype),Je.prototype.constructor=Je;var Fl={area:function(t){for(var e=t.length,i=0,r=e-1,n=0;n<e;r=n++)i+=t[r].x*t[n].y-t[n].x*t[r].y;return.5*i},triangulate:function(){function t(t,e,i,r,n,o){var a,s,c,u,h,l,p,d,f;if(s=t[o[e]].x,c=t[o[e]].y,u=t[o[i]].x,h=t[o[i]].y,l=t[o[r]].x,p=t[o[r]].y,(u-s)*(p-c)-(h-c)*(l-s)<=0)return!1;var m,g,v,y,b,x,_,w,S,A,M,P,T,E,C;for(m=l-u,g=p-h,v=s-l,y=c-p,b=u-s,x=h-c,a=0;a<n;a++)if(d=t[o[a]].x,f=t[o[a]].y,!(d===s&&f===c||d===u&&f===h||d===l&&f===p)&&(_=d-s,w=f-c,S=d-u,A=f-h,M=d-l,P=f-p,C=m*A-g*S,T=b*w-x*_,E=v*P-y*M,C>=-Number.EPSILON&&E>=-Number.EPSILON&&T>=-Number.EPSILON))return!1;return!0}return function(e,i){var r=e.length;if(r<3)return null;var n,o,a,s=[],c=[],u=[];if(Fl.area(e)>0)for(o=0;o<r;o++)c[o]=o;else for(o=0;o<r;o++)c[o]=r-1-o;var h=r,l=2*h;for(o=h-1;h>2;){if(l--<=0)return console.warn("THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()"),i?u:s;if(n=o,h<=n&&(n=0),o=n+1,h<=o&&(o=0),a=o+1,h<=a&&(a=0),t(e,n,o,a,h,c)){var p,d,f,m,g;for(p=c[n],d=c[o],f=c[a],s.push([e[p],e[d],e[f]]),u.push([c[n],c[o],c[a]]),m=o,g=o+1;g<h;m++,g++)c[m]=c[g];l=2*--h}}return i?u:s}}(),triangulateShape:function(t,e){function i(t){var e=t.length;e>2&&t[e-1].equals(t[0])&&t.pop()}function r(t,e,i){return t.x!==e.x?t.x<e.x?t.x<=i.x&&i.x<=e.x:e.x<=i.x&&i.x<=t.x:t.y<e.y?t.y<=i.y&&i.y<=e.y:e.y<=i.y&&i.y<=t.y}function n(t,e,i,n,o){var a=e.x-t.x,s=e.y-t.y,c=n.x-i.x,u=n.y-i.y,h=t.x-i.x,l=t.y-i.y,p=s*c-a*u,d=s*h-a*l;if(Math.abs(p)>Number.EPSILON){var f;if(p>0){if(d<0||d>p)return[];if((f=u*h-c*l)<0||f>p)return[]}else{if(d>0||d<p)return[];if((f=u*h-c*l)>0||f<p)return[]}if(0===f)return!o||0!==d&&d!==p?[t]:[];if(f===p)return!o||0!==d&&d!==p?[e]:[];if(0===d)return[i];if(d===p)return[n];var m=f/p;return[{x:t.x+m*a,y:t.y+m*s}]}if(0!==d||u*h!=c*l)return[];var g=0===a&&0===s,v=0===c&&0===u;if(g&&v)return t.x!==i.x||t.y!==i.y?[]:[t];if(g)return r(i,n,t)?[t]:[];if(v)return r(t,e,i)?[i]:[];var y,b,x,_,w,S,A,M;return 0!==a?(t.x<e.x?(y=t,x=t.x,b=e,_=e.x):(y=e,x=e.x,b=t,_=t.x),i.x<n.x?(w=i,A=i.x,S=n,M=n.x):(w=n,A=n.x,S=i,M=i.x)):(t.y<e.y?(y=t,x=t.y,b=e,_=e.y):(y=e,x=e.y,b=t,_=t.y),i.y<n.y?(w=i,A=i.y,S=n,M=n.y):(w=n,A=n.y,S=i,M=i.y)),x<=A?_<A?[]:_===A?o?[]:[w]:_<=M?[w,b]:[w,S]:x>M?[]:x===M?o?[]:[y]:_<=M?[y,b]:[y,S]}function o(t,e,i,r){var n=e.x-t.x,o=e.y-t.y,a=i.x-t.x,s=i.y-t.y,c=r.x-t.x,u=r.y-t.y,h=n*s-o*a,l=n*u-o*c;if(Math.abs(h)>Number.EPSILON){var p=c*s-u*a;return h>0?l>=0&&p>=0:l>=0||p>=0}return l>0}i(t),e.forEach(i);for(var a,s,c,u,h,l,p={},d=t.concat(),f=0,m=e.length;f<m;f++)Array.prototype.push.apply(d,e[f]);for(a=0,s=d.length;a<s;a++)void 0!==p[h=d[a].x+":"+d[a].y]&&console.warn("THREE.ShapeUtils: Duplicate point",h,a),p[h]=a;var g=function(t,e){for(var i,r,a,s,c,u,h,l,p,d,f,m=t.concat(),g=[],v=[],y=0,b=e.length;y<b;y++)g.push(y);for(var x=0,_=2*g.length;g.length>0;){if(--_<0){console.log("Infinite Loop! Holes left:"+g.length+", Probably Hole outside Shape!");break}for(a=x;a<m.length;a++){s=m[a],r=-1;for(y=0;y<g.length;y++)if(u=g[y],h=s.x+":"+s.y+":"+u,void 0===v[h]){i=e[u];for(var w=0;w<i.length;w++)if(c=i[w],function(t,e){var r=m.length-1,n=t-1;n<0&&(n=r);var a=t+1;a>r&&(a=0);var s=o(m[t],m[n],m[a],i[e]);if(!s)return!1;var c=i.length-1,u=e-1;u<0&&(u=c);var h=e+1;return h>c&&(h=0),!!(s=o(i[e],i[u],i[h],m[t]))}(a,w)&&!function(t,e){var i,r;for(i=0;i<m.length;i++)if(r=i+1,r%=m.length,n(t,e,m[i],m[r],!0).length>0)return!0;return!1}(s,c)&&!function(t,i){var r,o,a,s;for(r=0;r<g.length;r++)for(o=e[g[r]],a=0;a<o.length;a++)if(s=a+1,s%=o.length,n(t,i,o[a],o[s],!0).length>0)return!0;return!1}(s,c)){r=w,g.splice(y,1),l=m.slice(0,a+1),p=m.slice(a),d=i.slice(r),f=i.slice(0,r+1),m=l.concat(d).concat(f).concat(p),x=a;break}if(r>=0)break;v[h]=!0}if(r>=0)break}}return m}(t,e),v=Fl.triangulate(g,!1);for(a=0,s=v.length;a<s;a++)for(u=v[a],c=0;c<3;c++)void 0!==(l=p[h=u[c].x+":"+u[c].y])&&(u[c]=l);return v.concat()},isClockWise:function(t){return Fl.area(t)<0}};ti.prototype=Object.create(Et.prototype),ti.prototype.constructor=ti,ei.prototype=Object.create(Ct.prototype),ei.prototype.constructor=ei,ei.prototype.getArrays=function(){var t=this.getAttribute("position"),e=t?Array.prototype.slice.call(t.array):[],i=this.getAttribute("uv"),r=i?Array.prototype.slice.call(i.array):[],n=this.index;return{position:e,uv:r,index:n?Array.prototype.slice.call(n.array):[]}},ei.prototype.addShapeList=function(t,e){var i=this,r=t.length;e.arrays=this.getArrays();for(var n=0;n<r;n++){var o=t[n];i.addShape(o,e)}this.setIndex(e.arrays.index),this.addAttribute("position",new At(e.arrays.position,3)),this.addAttribute("uv",new At(e.arrays.uv,2))},ei.prototype.addShape=function(t,e){function i(t,e,i){return e||console.error("THREE.ExtrudeGeometry: vec does not exist"),e.clone().multiplyScalar(i).add(t)}function r(t,e,i){var r,n,o=1,a=t.x-e.x,s=t.y-e.y,c=i.x-t.x,u=i.y-t.y,h=a*a+s*s,p=a*u-s*c;if(Math.abs(p)>Number.EPSILON){var d=Math.sqrt(h),f=Math.sqrt(c*c+u*u),m=e.x-s/d,g=e.y+a/d,v=((i.x-u/f-m)*u-(i.y+c/f-g)*c)/(a*u-s*c),y=(r=m+a*v-t.x)*r+(n=g+s*v-t.y)*n;if(y<=2)return new l(r,n);o=Math.sqrt(y/2)}else{var b=!1;a>Number.EPSILON?c>Number.EPSILON&&(b=!0):a<-Number.EPSILON?c<-Number.EPSILON&&(b=!0):Math.sign(s)===Math.sign(u)&&(b=!0),b?(r=-s,n=a,o=Math.sqrt(h)):(r=a,n=s,o=Math.sqrt(h/2))}return new l(r/o,n/o)}function n(t,e){var i,r;for(K=t.length;--K>=0;){i=K,(r=K-1)<0&&(r=t.length-1);var n=0,o=E+2*M;for(n=0;n<o;n++){var a=q*n,c=q*(n+1);s(e+i+a,e+r+a,e+r+c,e+i+c,t,n,o,i,r)}}}function o(t,e,i){_.push(t),_.push(e),_.push(i)}function a(t,e,i){c(t),c(e),c(i);var r=y.length/3,n=L.generateTopUV(N,y,r-3,r-2,r-1);u(n[0]),u(n[1]),u(n[2])}function s(t,e,i,r,n,o,a,s,h){c(t),c(e),c(r),c(e),c(i),c(r);var l=y.length/3,p=L.generateSideWallUV(N,y,l-6,l-3,l-2,l-1);u(p[0]),u(p[1]),u(p[3]),u(p[1]),u(p[2]),u(p[3])}function c(t){b.push(y.length/3),y.push(_[3*t+0]),y.push(_[3*t+1]),y.push(_[3*t+2])}function u(t){x.push(t.x),x.push(t.y)}var h,p,d,f,m,v=e.arrays?e.arrays:this.getArrays(),y=v.position,b=v.index,x=v.uv,_=[],w=void 0!==e.amount?e.amount:100,S=void 0!==e.bevelThickness?e.bevelThickness:6,A=void 0!==e.bevelSize?e.bevelSize:S-2,M=void 0!==e.bevelSegments?e.bevelSegments:3,P=void 0===e.bevelEnabled||e.bevelEnabled,T=void 0!==e.curveSegments?e.curveSegments:12,E=void 0!==e.steps?e.steps:1,C=e.extrudePath,I=!1,L=void 0!==e.UVGenerator?e.UVGenerator:ti.WorldUVGenerator;C&&(h=C.getSpacedPoints(E),I=!0,P=!1,p=void 0!==e.frames?e.frames:C.computeFrenetFrames(E,!1),d=new g,f=new g,m=new g),P||(M=0,S=0,A=0);var R,O,D,N=this,k=t.extractPoints(T),B=k.shape,F=k.holes,z=!Fl.isClockWise(B);if(z){for(B=B.reverse(),O=0,D=F.length;O<D;O++)R=F[O],Fl.isClockWise(R)&&(F[O]=R.reverse());z=!1}var U=Fl.triangulateShape(B,F),j=B;for(O=0,D=F.length;O<D;O++)R=F[O],B=B.concat(R);for(var G,V,$,H,W,X,q=B.length,Y=U.length,Z=[],K=0,Q=j.length,J=Q-1,tt=K+1;K<Q;K++,J++,tt++)J===Q&&(J=0),tt===Q&&(tt=0),Z[K]=r(j[K],j[J],j[tt]);var et,it=[],rt=Z.concat();for(O=0,D=F.length;O<D;O++){for(R=F[O],et=[],K=0,J=(Q=R.length)-1,tt=K+1;K<Q;K++,J++,tt++)J===Q&&(J=0),tt===Q&&(tt=0),et[K]=r(R[K],R[J],R[tt]);it.push(et),rt=rt.concat(et)}for(G=0;G<M;G++){for($=G/M,H=S*Math.cos($*Math.PI/2),V=A*Math.sin($*Math.PI/2),K=0,Q=j.length;K<Q;K++)o((W=i(j[K],Z[K],V)).x,W.y,-H);for(O=0,D=F.length;O<D;O++)for(R=F[O],et=it[O],K=0,Q=R.length;K<Q;K++)o((W=i(R[K],et[K],V)).x,W.y,-H)}for(V=A,K=0;K<q;K++)W=P?i(B[K],rt[K],V):B[K],I?(f.copy(p.normals[0]).multiplyScalar(W.x),d.copy(p.binormals[0]).multiplyScalar(W.y),m.copy(h[0]).add(f).add(d),o(m.x,m.y,m.z)):o(W.x,W.y,0);var nt;for(nt=1;nt<=E;nt++)for(K=0;K<q;K++)W=P?i(B[K],rt[K],V):B[K],I?(f.copy(p.normals[nt]).multiplyScalar(W.x),d.copy(p.binormals[nt]).multiplyScalar(W.y),m.copy(h[nt]).add(f).add(d),o(m.x,m.y,m.z)):o(W.x,W.y,w/E*nt);for(G=M-1;G>=0;G--){for($=G/M,H=S*Math.cos($*Math.PI/2),V=A*Math.sin($*Math.PI/2),K=0,Q=j.length;K<Q;K++)o((W=i(j[K],Z[K],V)).x,W.y,w+H);for(O=0,D=F.length;O<D;O++)for(R=F[O],et=it[O],K=0,Q=R.length;K<Q;K++)W=i(R[K],et[K],V),I?o(W.x,W.y+h[E-1].y,h[E-1].x+H):o(W.x,W.y,w+H)}!function(){var t=y.length/3;if(P){var i=0,r=q*i;for(K=0;K<Y;K++)a((X=U[K])[2]+r,X[1]+r,X[0]+r);for(r=q*(i=E+2*M),K=0;K<Y;K++)a((X=U[K])[0]+r,X[1]+r,X[2]+r)}else{for(K=0;K<Y;K++)a((X=U[K])[2],X[1],X[0]);for(K=0;K<Y;K++)a((X=U[K])[0]+q*E,X[1]+q*E,X[2]+q*E)}N.addGroup(t,y.length/3-t,void 0!==e.material?e.material:0)}(),function(){var t=y.length/3,i=0;for(n(j,i),i+=j.length,O=0,D=F.length;O<D;O++)n(R=F[O],i),i+=R.length;N.addGroup(t,y.length/3-t,void 0!==e.extrudeMaterial?e.extrudeMaterial:1)}(),e.arrays||(this.setIndex(b),this.addAttribute("position",new At(y,3)),this.addAttribute("uv",new At(e.arrays.uv,2)))},ti.WorldUVGenerator={generateTopUV:function(t,e,i,r,n){var o=e[3*i],a=e[3*i+1],s=e[3*r],c=e[3*r+1],u=e[3*n],h=e[3*n+1];return[new l(o,a),new l(s,c),new l(u,h)]},generateSideWallUV:function(t,e,i,r,n,o){var a=e[3*i],s=e[3*i+1],c=e[3*i+2],u=e[3*r],h=e[3*r+1],p=e[3*r+2],d=e[3*n],f=e[3*n+1],m=e[3*n+2],g=e[3*o],v=e[3*o+1],y=e[3*o+2];return Math.abs(s-h)<.01?[new l(a,1-c),new l(u,1-p),new l(d,1-m),new l(g,1-y)]:[new l(s,1-c),new l(h,1-p),new l(f,1-m),new l(v,1-y)]}},ii.prototype=Object.create(Et.prototype),ii.prototype.constructor=ii,ri.prototype=Object.create(ei.prototype),ri.prototype.constructor=ri,ni.prototype=Object.create(Et.prototype),ni.prototype.constructor=ni,oi.prototype=Object.create(Ct.prototype),oi.prototype.constructor=oi,ai.prototype=Object.create(Et.prototype),ai.prototype.constructor=ai,si.prototype=Object.create(Ct.prototype),si.prototype.constructor=si,ci.prototype=Object.create(Et.prototype),ci.prototype.constructor=ci,ui.prototype=Object.create(Ct.prototype),ui.prototype.constructor=ui,hi.prototype=Object.create(Et.prototype),hi.prototype.constructor=hi,li.prototype=Object.create(Ct.prototype),li.prototype.constructor=li,pi.prototype=Object.create(Ct.prototype),pi.prototype.constructor=pi,di.prototype=Object.create(Et.prototype),di.prototype.constructor=di,fi.prototype=Object.create(Ct.prototype),fi.prototype.constructor=fi,mi.prototype=Object.create(di.prototype),mi.prototype.constructor=mi,gi.prototype=Object.create(fi.prototype),gi.prototype.constructor=gi,vi.prototype=Object.create(Et.prototype),vi.prototype.constructor=vi,yi.prototype=Object.create(Ct.prototype),yi.prototype.constructor=yi;var zl=Object.freeze({WireframeGeometry:Ne,ParametricGeometry:ke,ParametricBufferGeometry:Be,TetrahedronGeometry:Ue,TetrahedronBufferGeometry:je,OctahedronGeometry:Ge,OctahedronBufferGeometry:Ve,IcosahedronGeometry:$e,IcosahedronBufferGeometry:He,DodecahedronGeometry:We,DodecahedronBufferGeometry:Xe,PolyhedronGeometry:Fe,PolyhedronBufferGeometry:ze,TubeGeometry:qe,TubeBufferGeometry:Ye,TorusKnotGeometry:Ze,TorusKnotBufferGeometry:Ke,TorusGeometry:Qe,TorusBufferGeometry:Je,TextGeometry:ii,TextBufferGeometry:ri,SphereGeometry:ni,SphereBufferGeometry:oi,RingGeometry:ai,RingBufferGeometry:si,PlaneGeometry:Ot,PlaneBufferGeometry:Dt,LatheGeometry:ci,LatheBufferGeometry:ui,ShapeGeometry:hi,ShapeBufferGeometry:li,ExtrudeGeometry:ti,ExtrudeBufferGeometry:ei,EdgesGeometry:pi,ConeGeometry:mi,ConeBufferGeometry:gi,CylinderGeometry:di,CylinderBufferGeometry:fi,CircleGeometry:vi,CircleBufferGeometry:yi,BoxGeometry:Lt,BoxBufferGeometry:Rt});bi.prototype=Object.create(ot.prototype),bi.prototype.constructor=bi,bi.prototype.isShadowMaterial=!0,xi.prototype=Object.create(ot.prototype),xi.prototype.constructor=xi,xi.prototype.isRawShaderMaterial=!0,_i.prototype=Object.create(nt.prototype),_i.prototype.constructor=_i,_i.prototype.isMeshStandardMaterial=!0,_i.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.defines={STANDARD:""},this.color.copy(t.color),this.roughness=t.roughness,this.metalness=t.metalness,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.roughnessMap=t.roughnessMap,this.metalnessMap=t.metalnessMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapIntensity=t.envMapIntensity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.skinning=t.skinning,this.morphTargets=t.morphTargets,this.morphNormals=t.morphNormals,this},wi.prototype=Object.create(_i.prototype),wi.prototype.constructor=wi,wi.prototype.isMeshPhysicalMaterial=!0,wi.prototype.copy=function(t){return _i.prototype.copy.call(this,t),this.defines={PHYSICAL:""},this.reflectivity=t.reflectivity,this.clearCoat=t.clearCoat,this.clearCoatRoughness=t.clearCoatRoughness,this},Si.prototype=Object.create(nt.prototype),Si.prototype.constructor=Si,Si.prototype.isMeshPhongMaterial=!0,Si.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.color.copy(t.color),this.specular.copy(t.specular),this.shininess=t.shininess,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.skinning=t.skinning,this.morphTargets=t.morphTargets,this.morphNormals=t.morphNormals,this},Ai.prototype=Object.create(Si.prototype),Ai.prototype.constructor=Ai,Ai.prototype.isMeshToonMaterial=!0,Ai.prototype.copy=function(t){return Si.prototype.copy.call(this,t),this.gradientMap=t.gradientMap,this},Mi.prototype=Object.create(nt.prototype),Mi.prototype.constructor=Mi,Mi.prototype.isMeshNormalMaterial=!0,Mi.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.skinning=t.skinning,this.morphTargets=t.morphTargets,this.morphNormals=t.morphNormals,this},Pi.prototype=Object.create(nt.prototype),Pi.prototype.constructor=Pi,Pi.prototype.isMeshLambertMaterial=!0,Pi.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.skinning=t.skinning,this.morphTargets=t.morphTargets,this.morphNormals=t.morphNormals,this},Ti.prototype=Object.create(nt.prototype),Ti.prototype.constructor=Ti,Ti.prototype.isLineDashedMaterial=!0,Ti.prototype.copy=function(t){return nt.prototype.copy.call(this,t),this.color.copy(t.color),this.linewidth=t.linewidth,this.scale=t.scale,this.dashSize=t.dashSize,this.gapSize=t.gapSize,this};var Ul=Object.freeze({ShadowMaterial:bi,SpriteMaterial:xe,RawShaderMaterial:xi,ShaderMaterial:ot,PointsMaterial:Ie,MeshPhysicalMaterial:wi,MeshStandardMaterial:_i,MeshPhongMaterial:Si,MeshToonMaterial:Ai,MeshNormalMaterial:Mi,MeshLambertMaterial:Pi,MeshDepthMaterial:at,MeshBasicMaterial:xt,LineDashedMaterial:Ti,LineBasicMaterial:Pe,Material:nt}),jl={enabled:!1,files:{},add:function(t,e){!1!==this.enabled&&(this.files[t]=e)},get:function(t){if(!1!==this.enabled)return this.files[t]},remove:function(t){delete this.files[t]},clear:function(){this.files={}}},Gl=new Ei;Object.assign(Ci.prototype,{load:function(t,e,i,r){var n=this;void 0===t&&(t=""),void 0!==this.path&&(t=this.path+t);var o=this,a=jl.get(t);if(void 0!==a)return o.manager.itemStart(t),setTimeout(function(){e&&e(a),o.manager.itemEnd(t)},0),a;var s=t.match(/^data:(.*?)(;base64)?,(.*)$/);if(s){var c=s[1],u=!!s[2],h=s[3];h=window.decodeURIComponent(h),u&&(h=window.atob(h));try{var l,p=(this.responseType||"").toLowerCase();switch(p){case"arraybuffer":case"blob":l=new ArrayBuffer(h.length);for(var d=new Uint8Array(l),f=0;f<h.length;f++)d[f]=h.charCodeAt(f);"blob"===p&&(l=new Blob([l],{type:c}));break;case"document":var m=new DOMParser;l=m.parseFromString(h,c);break;case"json":l=JSON.parse(h);break;default:l=h}window.setTimeout(function(){e&&e(l),o.manager.itemEnd(t)},0)}catch(e){window.setTimeout(function(){r&&r(e),o.manager.itemEnd(t),o.manager.itemError(t)},0)}}else{var g=new XMLHttpRequest;g.open("GET",t,!0),g.addEventListener("load",function(i){var n=i.target.response;jl.add(t,n),200===this.status?(e&&e(n),o.manager.itemEnd(t)):0===this.status?(console.warn("THREE.FileLoader: HTTP Status 0 received."),e&&e(n),o.manager.itemEnd(t)):(r&&r(i),o.manager.itemEnd(t),o.manager.itemError(t))},!1),void 0!==i&&g.addEventListener("progress",function(t){i(t)},!1),g.addEventListener("error",function(e){r&&r(e),o.manager.itemEnd(t),o.manager.itemError(t)},!1),void 0!==this.responseType&&(g.responseType=this.responseType),void 0!==this.withCredentials&&(g.withCredentials=this.withCredentials),g.overrideMimeType&&g.overrideMimeType(void 0!==this.mimeType?this.mimeType:"text/plain");for(var v in n.requestHeader)g.setRequestHeader(v,n.requestHeader[v]);g.send(null)}return o.manager.itemStart(t),g},setPath:function(t){return this.path=t,this},setResponseType:function(t){return this.responseType=t,this},setWithCredentials:function(t){return this.withCredentials=t,this},setMimeType:function(t){return this.mimeType=t,this},setRequestHeader:function(t){return this.requestHeader=t,this}}),Object.assign(Ii.prototype,{load:function(t,e,i,r){var n=this,o=[],a=new Oe;a.image=o;var s=new Ci(this.manager);if(s.setPath(this.path),s.setResponseType("arraybuffer"),Array.isArray(t))for(var c=0,u=0,h=t.length;u<h;++u)!function(u){s.load(t[u],function(t){var i=n._parser(t,!0);o[u]={width:i.width,height:i.height,format:i.format,mipmaps:i.mipmaps},6===(c+=1)&&(1===i.mipmapCount&&(a.minFilter=Ch),a.format=i.format,a.needsUpdate=!0,e&&e(a))},i,r)}(u);else s.load(t,function(t){var i=n._parser(t,!0);if(i.isCubemap)for(var r=i.mipmaps.length/i.mipmapCount,s=0;s<r;s++){o[s]={mipmaps:[]};for(var c=0;c<i.mipmapCount;c++)o[s].mipmaps.push(i.mipmaps[s*i.mipmapCount+c]),o[s].format=i.format,o[s].width=i.width,o[s].height=i.height}else a.image.width=i.width,a.image.height=i.height,a.mipmaps=i.mipmaps;1===i.mipmapCount&&(a.minFilter=Ch),a.format=i.format,a.needsUpdate=!0,e&&e(a)},i,r);return a},setPath:function(t){return this.path=t,this}}),Object.assign(Li.prototype,{load:function(t,e,i,r){var n=this,o=new y,a=new Ci(this.manager);return a.setResponseType("arraybuffer"),a.load(t,function(t){var i=n._parser(t);i&&(void 0!==i.image?o.image=i.image:void 0!==i.data&&(o.image.width=i.width,o.image.height=i.height,o.image.data=i.data),o.wrapS=void 0!==i.wrapS?i.wrapS:Ah,o.wrapT=void 0!==i.wrapT?i.wrapT:Ah,o.magFilter=void 0!==i.magFilter?i.magFilter:Ch,o.minFilter=void 0!==i.minFilter?i.minFilter:Lh,o.anisotropy=void 0!==i.anisotropy?i.anisotropy:1,void 0!==i.format&&(o.format=i.format),void 0!==i.type&&(o.type=i.type),void 0!==i.mipmaps&&(o.mipmaps=i.mipmaps),1===i.mipmapCount&&(o.minFilter=Ch),o.needsUpdate=!0,e&&e(o,i))},i,r),o}}),Object.assign(Ri.prototype,{load:function(t,e,i,r){void 0===t&&(t=""),void 0!==this.path&&(t=this.path+t);var n=this,o=jl.get(t);if(void 0!==o)return n.manager.itemStart(t),setTimeout(function(){e&&e(o),n.manager.itemEnd(t)},0),o;var a=document.createElementNS("http://www.w3.org/1999/xhtml","img");return a.addEventListener("load",function(){jl.add(t,this),e&&e(this),n.manager.itemEnd(t)},!1),a.addEventListener("error",function(e){r&&r(e),n.manager.itemEnd(t),n.manager.itemError(t)},!1),"data:"!==t.substr(0,5)&&void 0!==this.crossOrigin&&(a.crossOrigin=this.crossOrigin),n.manager.itemStart(t),a.src=t,a},setCrossOrigin:function(t){return this.crossOrigin=t,this},setPath:function(t){return this.path=t,this}}),Object.assign(Oi.prototype,{load:function(t,e,i,r){var n=new b,o=new Ri(this.manager);o.setCrossOrigin(this.crossOrigin),o.setPath(this.path);for(var a=0,s=0;s<t.length;++s)!function(i){o.load(t[i],function(t){n.images[i]=t,6==++a&&(n.needsUpdate=!0,e&&e(n))},void 0,r)}(s);return n},setCrossOrigin:function(t){return this.crossOrigin=t,this},setPath:function(t){return this.path=t,this}}),Object.assign(Di.prototype,{load:function(t,e,i,r){var n=new Ri(this.manager);n.setCrossOrigin(this.crossOrigin),n.setPath(this.path);var o=new p;return o.image=n.load(t,function(){var i=t.search(/\.(jpg|jpeg)$/)>0||0===t.search(/^data\:image\/jpeg/);o.format=i?Hh:Wh,o.needsUpdate=!0,void 0!==e&&e(o)},i,r),o},setCrossOrigin:function(t){return this.crossOrigin=t,this},setPath:function(t){return this.path=t,this}}),Ni.prototype=Object.assign(Object.create(gt.prototype),{constructor:Ni,isLight:!0,copy:function(t){return gt.prototype.copy.call(this,t),this.color.copy(t.color),this.intensity=t.intensity,this},toJSON:function(t){var e=gt.prototype.toJSON.call(this,t);return e.object.color=this.color.getHex(),e.object.intensity=this.intensity,void 0!==this.groundColor&&(e.object.groundColor=this.groundColor.getHex()),void 0!==this.distance&&(e.object.distance=this.distance),void 0!==this.angle&&(e.object.angle=this.angle),void 0!==this.decay&&(e.object.decay=this.decay),void 0!==this.penumbra&&(e.object.penumbra=this.penumbra),void 0!==this.shadow&&(e.object.shadow=this.shadow.toJSON()),e}}),ki.prototype=Object.assign(Object.create(Ni.prototype),{constructor:ki,isHemisphereLight:!0,copy:function(t){return Ni.prototype.copy.call(this,t),this.groundColor.copy(t.groundColor),this}}),Object.assign(Bi.prototype,{copy:function(t){return this.camera=t.camera.clone(),this.bias=t.bias,this.radius=t.radius,this.mapSize.copy(t.mapSize),this},clone:function(){return(new this.constructor).copy(this)},toJSON:function(){var t={};return 0!==this.bias&&(t.bias=this.bias),1!==this.radius&&(t.radius=this.radius),512===this.mapSize.x&&512===this.mapSize.y||(t.mapSize=this.mapSize.toArray()),t.camera=this.camera.toJSON(!1).object,delete t.camera.matrix,t}}),Fi.prototype=Object.assign(Object.create(Bi.prototype),{constructor:Fi,isSpotLightShadow:!0,update:function(t){var e=this.camera,i=2*xl.RAD2DEG*t.angle,r=this.mapSize.width/this.mapSize.height,n=t.distance||e.far;i===e.fov&&r===e.aspect&&n===e.far||(e.fov=i,e.aspect=r,e.far=n,e.updateProjectionMatrix())}}),zi.prototype=Object.assign(Object.create(Ni.prototype),{constructor:zi,isSpotLight:!0,copy:function(t){return Ni.prototype.copy.call(this,t),this.distance=t.distance,this.angle=t.angle,this.penumbra=t.penumbra,this.decay=t.decay,this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}),Ui.prototype=Object.assign(Object.create(Ni.prototype),{constructor:Ui,isPointLight:!0,copy:function(t){return Ni.prototype.copy.call(this,t),this.distance=t.distance,this.decay=t.decay,this.shadow=t.shadow.clone(),this}}),ji.prototype=Object.assign(Object.create(Bi.prototype),{constructor:ji}),Gi.prototype=Object.assign(Object.create(Ni.prototype),{constructor:Gi,isDirectionalLight:!0,copy:function(t){return Ni.prototype.copy.call(this,t),this.target=t.target.clone(),this.shadow=t.shadow.clone(),this}}),Vi.prototype=Object.assign(Object.create(Ni.prototype),{constructor:Vi,isAmbientLight:!0}),$i.prototype=Object.assign(Object.create(Ni.prototype),{constructor:$i,isRectAreaLight:!0,copy:function(t){return Ni.prototype.copy.call(this,t),this.width=t.width,this.height=t.height,this},toJSON:function(t){var e=Ni.prototype.toJSON.call(this,t);return e.object.width=this.width,e.object.height=this.height,e}});var Vl={arraySlice:function(t,e,i){return Vl.isTypedArray(t)?new t.constructor(t.subarray(e,void 0!==i?i:t.length)):t.slice(e,i)},convertArray:function(t,e,i){return!t||!i&&t.constructor===e?t:"number"==typeof e.BYTES_PER_ELEMENT?new e(t):Array.prototype.slice.call(t)},isTypedArray:function(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)},getKeyframeOrder:function(t){function e(e,i){return t[e]-t[i]}for(var i=t.length,r=new Array(i),n=0;n!==i;++n)r[n]=n;return r.sort(e),r},sortedArray:function(t,e,i){for(var r=t.length,n=new t.constructor(r),o=0,a=0;a!==r;++o)for(var s=i[o]*e,c=0;c!==e;++c)n[a++]=t[s+c];return n},flattenJSON:function(t,e,i,r){for(var n=1,o=t[0];void 0!==o&&void 0===o[r];)o=t[n++];if(void 0!==o){var a=o[r];if(void 0!==a)if(Array.isArray(a))do{void 0!==(a=o[r])&&(e.push(o.time),i.push.apply(i,a)),o=t[n++]}while(void 0!==o);else if(void 0!==a.toArray)do{void 0!==(a=o[r])&&(e.push(o.time),a.toArray(i,i.length)),o=t[n++]}while(void 0!==o);else do{void 0!==(a=o[r])&&(e.push(o.time),i.push(a)),o=t[n++]}while(void 0!==o)}}};Object.assign(Hi.prototype,{evaluate:function(t){var e=this,i=this.parameterPositions,r=this._cachedIndex,n=i[r],o=i[r-1];t:{e:{var a;i:{r:if(!(t<n)){for(c=r+2;;){if(void 0===n){if(t<o)break r;return r=i.length,e._cachedIndex=r,e.afterEnd_(r-1,t,o)}if(r===c)break;if(o=n,n=i[++r],t<n)break e}a=i.length;break i}{if(t>=o)break t;var s=i[1];t<s&&(r=2,o=s);for(var c=r-2;;){if(void 0===o)return e._cachedIndex=0,e.beforeStart_(0,t,n);if(r===c)break;if(n=o,o=i[--r-1],t>=o)break e}a=r,r=0}}for(;r<a;){var u=r+a>>>1;t<i[u]?a=u:r=u+1}if(n=i[r],void 0===(o=i[r-1]))return this._cachedIndex=0,this.beforeStart_(0,t,n);if(void 0===n)return r=i.length,this._cachedIndex=r,this.afterEnd_(r-1,o,t)}this._cachedIndex=r,this.intervalChanged_(r,o,n)}return this.interpolate_(r,o,t,n)},settings:null,DefaultSettings_:{},getSettings_:function(){return this.settings||this.DefaultSettings_},copySampleValue_:function(t){for(var e=this.resultBuffer,i=this.sampleValues,r=this.valueSize,n=t*r,o=0;o!==r;++o)e[o]=i[n+o];return e},interpolate_:function(t,e,i,r){throw new Error("call to abstract method")},intervalChanged_:function(t,e,i){}}),Object.assign(Hi.prototype,{beforeStart_:Hi.prototype.copySampleValue_,afterEnd_:Hi.prototype.copySampleValue_}),Wi.prototype=Object.assign(Object.create(Hi.prototype),{constructor:Wi,DefaultSettings_:{endingStart:sl,endingEnd:sl},intervalChanged_:function(t,e,i){var r=this.parameterPositions,n=t-2,o=t+1,a=r[n],s=r[o];if(void 0===a)switch(this.getSettings_().endingStart){case 2401:n=t,a=2*e-i;break;case 2402:a=e+r[n=r.length-2]-r[n+1];break;default:n=t,a=i}if(void 0===s)switch(this.getSettings_().endingEnd){case 2401:o=t,s=2*i-e;break;case 2402:o=1,s=i+r[1]-r[0];break;default:o=t-1,s=e}var c=.5*(i-e),u=this.valueSize;this._weightPrev=c/(e-a),this._weightNext=c/(s-i),this._offsetPrev=n*u,this._offsetNext=o*u},interpolate_:function(t,e,i,r){for(var n=this.resultBuffer,o=this.sampleValues,a=this.valueSize,s=t*a,c=s-a,u=this._offsetPrev,h=this._offsetNext,l=this._weightPrev,p=this._weightNext,d=(i-e)/(r-e),f=d*d,m=f*d,g=-l*m+2*l*f-l*d,v=(1+l)*m+(-1.5-2*l)*f+(-.5+l)*d+1,y=(-1-p)*m+(1.5+p)*f+.5*d,b=p*m-p*f,x=0;x!==a;++x)n[x]=g*o[u+x]+v*o[c+x]+y*o[s+x]+b*o[h+x];return n}}),Xi.prototype=Object.assign(Object.create(Hi.prototype),{constructor:Xi,interpolate_:function(t,e,i,r){for(var n=this.resultBuffer,o=this.sampleValues,a=this.valueSize,s=t*a,c=s-a,u=(i-e)/(r-e),h=1-u,l=0;l!==a;++l)n[l]=o[c+l]*h+o[s+l]*u;return n}}),qi.prototype=Object.assign(Object.create(Hi.prototype),{constructor:qi,interpolate_:function(t,e,i,r){return this.copySampleValue_(t-1)}});var $l;$l={TimeBufferType:Float32Array,ValueBufferType:Float32Array,DefaultInterpolation:2301,InterpolantFactoryMethodDiscrete:function(t){return new qi(this.times,this.values,this.getValueSize(),t)},InterpolantFactoryMethodLinear:function(t){return new Xi(this.times,this.values,this.getValueSize(),t)},InterpolantFactoryMethodSmooth:function(t){return new Wi(this.times,this.values,this.getValueSize(),t)},setInterpolation:function(t){var e;switch(t){case 2300:e=this.InterpolantFactoryMethodDiscrete;break;case 2301:e=this.InterpolantFactoryMethodLinear;break;case 2302:e=this.InterpolantFactoryMethodSmooth}if(void 0===e){var i="unsupported interpolation for "+this.ValueTypeName+" keyframe track named "+this.name;if(void 0===this.createInterpolant){if(t===this.DefaultInterpolation)throw new Error(i);this.setInterpolation(this.DefaultInterpolation)}return void console.warn(i)}this.createInterpolant=e},getInterpolation:function(){switch(this.createInterpolant){case this.InterpolantFactoryMethodDiscrete:return 2300;case this.InterpolantFactoryMethodLinear:return 2301;case this.InterpolantFactoryMethodSmooth:return 2302}},getValueSize:function(){return this.values.length/this.times.length},shift:function(t){if(0!==t)for(var e=this.times,i=0,r=e.length;i!==r;++i)e[i]+=t;return this},scale:function(t){if(1!==t)for(var e=this.times,i=0,r=e.length;i!==r;++i)e[i]*=t;return this},trim:function(t,e){for(var i=this.times,r=i.length,n=0,o=r-1;n!==r&&i[n]<t;)++n;for(;-1!==o&&i[o]>e;)--o;if(++o,0!==n||o!==r){n>=o&&(n=(o=Math.max(o,1))-1);var a=this.getValueSize();this.times=Vl.arraySlice(i,n,o),this.values=Vl.arraySlice(this.values,n*a,o*a)}return this},validate:function(){var t=this,e=!0,i=this.getValueSize();i-Math.floor(i)!=0&&(console.error("invalid value size in track",this),e=!1);var r=this.times,n=this.values,o=r.length;0===o&&(console.error("track is empty",this),e=!1);for(var a=null,s=0;s!==o;s++){var c=r[s];if("number"==typeof c&&isNaN(c)){console.error("time is not a valid number",t,s,c),e=!1;break}if(null!==a&&a>c){console.error("out of order keys",t,s,c,a),e=!1;break}a=c}if(void 0!==n&&Vl.isTypedArray(n))for(var s=0,u=n.length;s!==u;++s){var h=n[s];if(isNaN(h)){console.error("value is not a valid number",t,s,h),e=!1;break}}return e},optimize:function(){for(var t=this.times,e=this.values,i=this.getValueSize(),r=2302===this.getInterpolation(),n=1,o=t.length-1,a=1;a<o;++a){var s=!1,c=t[a];if(c!==t[a+1]&&(1!==a||c!==c[0]))if(r)s=!0;else for(var u=a*i,h=u-i,l=u+i,p=0;p!==i;++p){var d=e[u+p];if(d!==e[h+p]||d!==e[l+p]){s=!0;break}}if(s){if(a!==n){t[n]=t[a];for(var f=a*i,m=n*i,p=0;p!==i;++p)e[m+p]=e[f+p]}++n}}if(o>0){t[n]=t[o];for(var f=o*i,m=n*i,p=0;p!==i;++p)e[m+p]=e[f+p];++n}return n!==t.length&&(this.times=Vl.arraySlice(t,0,n),this.values=Vl.arraySlice(e,0,n*i)),this}},Zi.prototype=Object.assign(Object.create($l),{constructor:Zi,ValueTypeName:"vector"}),Ki.prototype=Object.assign(Object.create(Hi.prototype),{constructor:Ki,interpolate_:function(t,e,i,r){for(var n=this.resultBuffer,o=this.sampleValues,a=this.valueSize,s=t*a,c=(i-e)/(r-e),u=s+a;s!==u;s+=4)m.slerpFlat(n,0,o,s-a,o,s,c);return n}}),Qi.prototype=Object.assign(Object.create($l),{constructor:Qi,ValueTypeName:"quaternion",DefaultInterpolation:2301,InterpolantFactoryMethodLinear:function(t){return new Ki(this.times,this.values,this.getValueSize(),t)},InterpolantFactoryMethodSmooth:void 0}),Ji.prototype=Object.assign(Object.create($l),{constructor:Ji,ValueTypeName:"number"}),tr.prototype=Object.assign(Object.create($l),{constructor:tr,ValueTypeName:"string",ValueBufferType:Array,DefaultInterpolation:2300,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0}),er.prototype=Object.assign(Object.create($l),{constructor:er,ValueTypeName:"bool",ValueBufferType:Array,DefaultInterpolation:2300,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0}),ir.prototype=Object.assign(Object.create($l),{constructor:ir,ValueTypeName:"color"}),rr.prototype=$l,$l.constructor=rr,Object.assign(rr,{parse:function(t){if(void 0===t.type)throw new Error("track type undefined, can not parse");var e=rr._getTrackTypeForValueTypeName(t.type);if(void 0===t.times){var i=[],r=[];Vl.flattenJSON(t.keys,i,r,"value"),t.times=i,t.values=r}return void 0!==e.parse?e.parse(t):new e(t.name,t.times,t.values,t.interpolation)},toJSON:function(t){var e,i=t.constructor;if(void 0!==i.toJSON)e=i.toJSON(t);else{e={name:t.name,times:Vl.convertArray(t.times,Array),values:Vl.convertArray(t.values,Array)};var r=t.getInterpolation();r!==t.DefaultInterpolation&&(e.interpolation=r)}return e.type=t.ValueTypeName,e},_getTrackTypeForValueTypeName:function(t){switch(t.toLowerCase()){case"scalar":case"double":case"float":case"number":case"integer":return Ji;case"vector":case"vector2":case"vector3":case"vector4":return Zi;case"color":return ir;case"quaternion":return Qi;case"bool":case"boolean":return er;case"string":return tr}throw new Error("Unsupported typeName: "+t)}}),Object.assign(nr,{parse:function(t){for(var e=[],i=t.tracks,r=1/(t.fps||1),n=0,o=i.length;n!==o;++n)e.push(rr.parse(i[n]).scale(r));return new nr(t.name,t.duration,e)},toJSON:function(t){for(var e=[],i=t.tracks,r={name:t.name,duration:t.duration,tracks:e},n=0,o=i.length;n!==o;++n)e.push(rr.toJSON(i[n]));return r},CreateFromMorphTargetSequence:function(t,e,i,r){for(var n=e.length,o=[],a=0;a<n;a++){var s=[],c=[];s.push((a+n-1)%n,a,(a+1)%n),c.push(0,1,0);var u=Vl.getKeyframeOrder(s);s=Vl.sortedArray(s,1,u),c=Vl.sortedArray(c,1,u),r||0!==s[0]||(s.push(n),c.push(c[0])),o.push(new Ji(".morphTargetInfluences["+e[a].name+"]",s,c).scale(1/i))}return new nr(t,-1,o)},findByName:function(t,e){var i=t;if(!Array.isArray(t)){var r=t;i=r.geometry&&r.geometry.animations||r.animations}for(var n=0;n<i.length;n++)if(i[n].name===e)return i[n];return null},CreateClipsFromMorphTargetSequences:function(t,e,i){for(var r={},n=0,o=t.length;n<o;n++){var a=t[n],s=a.name.match(/^([\w-]*?)([\d]+)$/);if(s&&s.length>1){var c=r[h=s[1]];c||(r[h]=c=[]),c.push(a)}}var u=[];for(var h in r)u.push(nr.CreateFromMorphTargetSequence(h,r[h],e,i));return u},parseAnimation:function(t,e){if(!t)return console.error("  no animation in JSONLoader data"),null;for(var i=function(t,e,i,r,n){if(0!==i.length){var o=[],a=[];Vl.flattenJSON(i,o,a,r),0!==o.length&&n.push(new t(e,o,a))}},r=[],n=t.name||"default",o=t.length||-1,a=t.fps||30,s=t.hierarchy||[],c=0;c<s.length;c++){var u=s[c].keys;if(u&&0!==u.length)if(u[0].morphTargets){for(var h={},l=0;l<u.length;l++)if(u[l].morphTargets)for(m=0;m<u[l].morphTargets.length;m++)h[u[l].morphTargets[m]]=-1;for(var p in h){for(var d=[],f=[],m=0;m!==u[l].morphTargets.length;++m){var g=u[l];d.push(g.time),f.push(g.morphTarget===p?1:0)}r.push(new Ji(".morphTargetInfluence["+p+"]",d,f))}o=h.length*(a||1)}else{var v=".bones["+e[c].name+"]";i(Zi,v+".position",u,"pos",r),i(Qi,v+".quaternion",u,"rot",r),i(Zi,v+".scale",u,"scl",r)}}return 0===r.length?null:new nr(n,o,r)}}),Object.assign(nr.prototype,{resetDuration:function(){for(var t=this,e=0,i=0,r=this.tracks.length;i!==r;++i){var n=t.tracks[i];e=Math.max(e,n.times[n.times.length-1])}this.duration=e},trim:function(){for(var t=this,e=0;e<this.tracks.length;e++)t.tracks[e].trim(0,t.duration);return this},optimize:function(){for(var t=this,e=0;e<this.tracks.length;e++)t.tracks[e].optimize();return this}}),Object.assign(or.prototype,{load:function(t,e,i,r){var n=this,o=new Ci(n.manager);o.setResponseType("json"),o.load(t,function(t){e(n.parse(t))},i,r)},setTextures:function(t){this.textures=t},parse:function(t){function e(t){return void 0===r[t]&&console.warn("THREE.MaterialLoader: Undefined texture",t),r[t]}var i=this,r=this.textures,n=new Ul[t.type];if(void 0!==t.uuid&&(n.uuid=t.uuid),void 0!==t.name&&(n.name=t.name),void 0!==t.color&&n.color.setHex(t.color),void 0!==t.roughness&&(n.roughness=t.roughness),void 0!==t.metalness&&(n.metalness=t.metalness),void 0!==t.emissive&&n.emissive.setHex(t.emissive),void 0!==t.specular&&n.specular.setHex(t.specular),void 0!==t.shininess&&(n.shininess=t.shininess),void 0!==t.clearCoat&&(n.clearCoat=t.clearCoat),void 0!==t.clearCoatRoughness&&(n.clearCoatRoughness=t.clearCoatRoughness),void 0!==t.uniforms&&(n.uniforms=t.uniforms),void 0!==t.vertexShader&&(n.vertexShader=t.vertexShader),void 0!==t.fragmentShader&&(n.fragmentShader=t.fragmentShader),void 0!==t.vertexColors&&(n.vertexColors=t.vertexColors),void 0!==t.fog&&(n.fog=t.fog),void 0!==t.shading&&(n.shading=t.shading),void 0!==t.blending&&(n.blending=t.blending),void 0!==t.side&&(n.side=t.side),void 0!==t.opacity&&(n.opacity=t.opacity),void 0!==t.transparent&&(n.transparent=t.transparent),void 0!==t.alphaTest&&(n.alphaTest=t.alphaTest),void 0!==t.depthTest&&(n.depthTest=t.depthTest),void 0!==t.depthWrite&&(n.depthWrite=t.depthWrite),void 0!==t.colorWrite&&(n.colorWrite=t.colorWrite),void 0!==t.wireframe&&(n.wireframe=t.wireframe),void 0!==t.wireframeLinewidth&&(n.wireframeLinewidth=t.wireframeLinewidth),void 0!==t.wireframeLinecap&&(n.wireframeLinecap=t.wireframeLinecap),void 0!==t.wireframeLinejoin&&(n.wireframeLinejoin=t.wireframeLinejoin),void 0!==t.skinning&&(n.skinning=t.skinning),void 0!==t.morphTargets&&(n.morphTargets=t.morphTargets),void 0!==t.size&&(n.size=t.size),void 0!==t.sizeAttenuation&&(n.sizeAttenuation=t.sizeAttenuation),void 0!==t.map&&(n.map=e(t.map)),void 0!==t.alphaMap&&(n.alphaMap=e(t.alphaMap),n.transparent=!0),void 0!==t.bumpMap&&(n.bumpMap=e(t.bumpMap)),void 0!==t.bumpScale&&(n.bumpScale=t.bumpScale),void 0!==t.normalMap&&(n.normalMap=e(t.normalMap)),void 0!==t.normalScale){var o=t.normalScale;!1===Array.isArray(o)&&(o=[o,o]),n.normalScale=(new l).fromArray(o)}if(void 0!==t.displacementMap&&(n.displacementMap=e(t.displacementMap)),void 0!==t.displacementScale&&(n.displacementScale=t.displacementScale),void 0!==t.displacementBias&&(n.displacementBias=t.displacementBias),void 0!==t.roughnessMap&&(n.roughnessMap=e(t.roughnessMap)),void 0!==t.metalnessMap&&(n.metalnessMap=e(t.metalnessMap)),void 0!==t.emissiveMap&&(n.emissiveMap=e(t.emissiveMap)),void 0!==t.emissiveIntensity&&(n.emissiveIntensity=t.emissiveIntensity),void 0!==t.specularMap&&(n.specularMap=e(t.specularMap)),void 0!==t.envMap&&(n.envMap=e(t.envMap)),void 0!==t.reflectivity&&(n.reflectivity=t.reflectivity),void 0!==t.lightMap&&(n.lightMap=e(t.lightMap)),void 0!==t.lightMapIntensity&&(n.lightMapIntensity=t.lightMapIntensity),void 0!==t.aoMap&&(n.aoMap=e(t.aoMap)),void 0!==t.aoMapIntensity&&(n.aoMapIntensity=t.aoMapIntensity),void 0!==t.gradientMap&&(n.gradientMap=e(t.gradientMap)),void 0!==t.materials)for(var a=0,s=t.materials.length;a<s;a++)n.materials.push(i.parse(t.materials[a]));return n}}),Object.assign(ar.prototype,{load:function(t,e,i,r){var n=this,o=new Ci(n.manager);o.setResponseType("json"),o.load(t,function(t){e(n.parse(t))},i,r)},parse:function(t){var e=new Ct,i=t.data.index;if(void 0!==i){a=new Hl[i.type](i.array);e.setIndex(new _t(a,1))}var r=t.data.attributes;for(var n in r){var o=r[n],a=new Hl[o.type](o.array);e.addAttribute(n,new _t(a,o.itemSize,o.normalized))}var s=t.data.groups||t.data.drawcalls||t.data.offsets;if(void 0!==s)for(var c=0,u=s.length;c!==u;++c){var h=s[c];e.addGroup(h.start,h.count,h.materialIndex)}var l=t.data.boundingSphere;if(void 0!==l){var p=new g;void 0!==l.center&&p.fromArray(l.center),e.boundingSphere=new ct(p,l.radius)}return e}});var Hl={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};sr.Handlers={handlers:[],add:function(t,e){this.handlers.push(t,e)},get:function(t){for(var e=this.handlers,i=0,r=e.length;i<r;i+=2){var n=e[i],o=e[i+1];if(n.test(t))return o}return null}},Object.assign(sr.prototype,{crossOrigin:void 0,extractUrlBase:function(t){var e=t.split("/");return 1===e.length?"./":(e.pop(),e.join("/")+"/")},initMaterials:function(t,e,i){for(var r=this,n=[],o=0;o<t.length;++o)n[o]=r.createMaterial(t[o],e,i);return n},createMaterial:function(){var t={NoBlending:Ru,NormalBlending:Ou,AdditiveBlending:Du,SubtractiveBlending:Nu,MultiplyBlending:ku,CustomBlending:Bu},e=new tt,i=new Di,r=new or;return function(n,o,a){function s(t,e,r,n,s){var u,h=o+t,l=sr.Handlers.get(h);null!==l?u=l.load(h):(i.setCrossOrigin(a),u=i.load(h)),void 0!==e&&(u.repeat.fromArray(e),1!==e[0]&&(u.wrapS=Sh),1!==e[1]&&(u.wrapT=Sh)),void 0!==r&&u.offset.fromArray(r),void 0!==n&&("repeat"===n[0]&&(u.wrapS=Sh),"mirror"===n[0]&&(u.wrapS=Mh),"repeat"===n[1]&&(u.wrapT=Sh),"mirror"===n[1]&&(u.wrapT=Mh)),void 0!==s&&(u.anisotropy=s);var p=xl.generateUUID();return c[p]=u,p}var c={},u={uuid:xl.generateUUID(),type:"MeshLambertMaterial"};for(var h in n){var l=n[h];switch(h){case"DbgColor":case"DbgIndex":case"opticalDensity":case"illumination":break;case"DbgName":u.name=l;break;case"blending":u.blending=t[l];break;case"colorAmbient":case"mapAmbient":console.warn("THREE.Loader.createMaterial:",h,"is no longer supported.");break;case"colorDiffuse":u.color=e.fromArray(l).getHex();break;case"colorSpecular":u.specular=e.fromArray(l).getHex();break;case"colorEmissive":u.emissive=e.fromArray(l).getHex();break;case"specularCoef":u.shininess=l;break;case"shading":"basic"===l.toLowerCase()&&(u.type="MeshBasicMaterial"),"phong"===l.toLowerCase()&&(u.type="MeshPhongMaterial"),"standard"===l.toLowerCase()&&(u.type="MeshStandardMaterial");break;case"mapDiffuse":u.map=s(l,n.mapDiffuseRepeat,n.mapDiffuseOffset,n.mapDiffuseWrap,n.mapDiffuseAnisotropy);break;case"mapDiffuseRepeat":case"mapDiffuseOffset":case"mapDiffuseWrap":case"mapDiffuseAnisotropy":break;case"mapEmissive":u.emissiveMap=s(l,n.mapEmissiveRepeat,n.mapEmissiveOffset,n.mapEmissiveWrap,n.mapEmissiveAnisotropy);break;case"mapEmissiveRepeat":case"mapEmissiveOffset":case"mapEmissiveWrap":case"mapEmissiveAnisotropy":break;case"mapLight":u.lightMap=s(l,n.mapLightRepeat,n.mapLightOffset,n.mapLightWrap,n.mapLightAnisotropy);break;case"mapLightRepeat":case"mapLightOffset":case"mapLightWrap":case"mapLightAnisotropy":break;case"mapAO":u.aoMap=s(l,n.mapAORepeat,n.mapAOOffset,n.mapAOWrap,n.mapAOAnisotropy);break;case"mapAORepeat":case"mapAOOffset":case"mapAOWrap":case"mapAOAnisotropy":break;case"mapBump":u.bumpMap=s(l,n.mapBumpRepeat,n.mapBumpOffset,n.mapBumpWrap,n.mapBumpAnisotropy);break;case"mapBumpScale":u.bumpScale=l;break;case"mapBumpRepeat":case"mapBumpOffset":case"mapBumpWrap":case"mapBumpAnisotropy":break;case"mapNormal":u.normalMap=s(l,n.mapNormalRepeat,n.mapNormalOffset,n.mapNormalWrap,n.mapNormalAnisotropy);break;case"mapNormalFactor":u.normalScale=[l,l];break;case"mapNormalRepeat":case"mapNormalOffset":case"mapNormalWrap":case"mapNormalAnisotropy":break;case"mapSpecular":u.specularMap=s(l,n.mapSpecularRepeat,n.mapSpecularOffset,n.mapSpecularWrap,n.mapSpecularAnisotropy);break;case"mapSpecularRepeat":case"mapSpecularOffset":case"mapSpecularWrap":case"mapSpecularAnisotropy":break;case"mapMetalness":u.metalnessMap=s(l,n.mapMetalnessRepeat,n.mapMetalnessOffset,n.mapMetalnessWrap,n.mapMetalnessAnisotropy);break;case"mapMetalnessRepeat":case"mapMetalnessOffset":case"mapMetalnessWrap":case"mapMetalnessAnisotropy":break;case"mapRoughness":u.roughnessMap=s(l,n.mapRoughnessRepeat,n.mapRoughnessOffset,n.mapRoughnessWrap,n.mapRoughnessAnisotropy);break;case"mapRoughnessRepeat":case"mapRoughnessOffset":case"mapRoughnessWrap":case"mapRoughnessAnisotropy":break;case"mapAlpha":u.alphaMap=s(l,n.mapAlphaRepeat,n.mapAlphaOffset,n.mapAlphaWrap,n.mapAlphaAnisotropy);break;case"mapAlphaRepeat":case"mapAlphaOffset":case"mapAlphaWrap":case"mapAlphaAnisotropy":break;case"flipSided":u.side=Mu;break;case"doubleSided":u.side=Pu;break;case"transparency":console.warn("THREE.Loader.createMaterial: transparency has been renamed to opacity"),u.opacity=l;break;case"depthTest":case"depthWrite":case"colorWrite":case"opacity":case"reflectivity":case"transparent":case"visible":case"wireframe":u[h]=l;break;case"vertexColors":!0===l&&(u.vertexColors=Lu),"face"===l&&(u.vertexColors=Iu);break;default:console.error("THREE.Loader.createMaterial: Unsupported",h,l)}}return"MeshBasicMaterial"===u.type&&delete u.emissive,"MeshPhongMaterial"!==u.type&&delete u.specular,u.opacity<1&&(u.transparent=!0),r.setTextures(c),r.parse(u)}}()}),Object.assign(cr.prototype,{load:function(t,e,i,r){var n=this,o=this.texturePath&&"string"==typeof this.texturePath?this.texturePath:sr.prototype.extractUrlBase(t),a=new Ci(this.manager);a.setResponseType("json"),a.setWithCredentials(this.withCredentials),a.load(t,function(i){var r=i.metadata;if(void 0!==r){var a=r.type;if(void 0!==a){if("object"===a.toLowerCase())return void console.error("THREE.JSONLoader: "+t+" should be loaded with THREE.ObjectLoader instead.");if("scene"===a.toLowerCase())return void console.error("THREE.JSONLoader: "+t+" should be loaded with THREE.SceneLoader instead.")}}var s=n.parse(i,o);e(s.geometry,s.materials)},i,r)},setTexturePath:function(t){this.texturePath=t},parse:function(){function t(t,e){function i(t,e){return t&1<<e}var r,n,o,a,s,c,u,h,p,d,f,m,v,y,b,x,_,w,S,A,M,P,T,E,C,I=t.faces,L=t.vertices,R=t.normals,O=t.colors,D=t.scale,N=0;if(void 0!==t.uvs){for(r=0;r<t.uvs.length;r++)t.uvs[r].length&&N++;for(r=0;r<N;r++)e.faceVertexUvs[r]=[]}for(a=0,s=L.length;a<s;)(w=new g).x=L[a++]*D,w.y=L[a++]*D,w.z=L[a++]*D,e.vertices.push(w);for(a=0,s=I.length;a<s;)if(d=I[a++],f=i(d,0),m=i(d,1),v=i(d,3),y=i(d,4),b=i(d,5),x=i(d,6),_=i(d,7),f){if(A=new bt,A.a=I[a],A.b=I[a+1],A.c=I[a+3],M=new bt,M.a=I[a+1],M.b=I[a+2],M.c=I[a+3],a+=4,m&&(p=I[a++],A.materialIndex=p,M.materialIndex=p),o=e.faces.length,v)for(r=0;r<N;r++)for(E=t.uvs[r],e.faceVertexUvs[r][o]=[],e.faceVertexUvs[r][o+1]=[],n=0;n<4;n++)C=new l(E[2*(h=I[a++])],E[2*h+1]),2!==n&&e.faceVertexUvs[r][o].push(C),0!==n&&e.faceVertexUvs[r][o+1].push(C);if(y&&(u=3*I[a++],A.normal.set(R[u++],R[u++],R[u]),M.normal.copy(A.normal)),b)for(r=0;r<4;r++)u=3*I[a++],T=new g(R[u++],R[u++],R[u]),2!==r&&A.vertexNormals.push(T),0!==r&&M.vertexNormals.push(T);if(x&&(P=O[c=I[a++]],A.color.setHex(P),M.color.setHex(P)),_)for(r=0;r<4;r++)P=O[c=I[a++]],2!==r&&A.vertexColors.push(new tt(P)),0!==r&&M.vertexColors.push(new tt(P));e.faces.push(A),e.faces.push(M)}else{if(S=new bt,S.a=I[a++],S.b=I[a++],S.c=I[a++],m&&(p=I[a++],S.materialIndex=p),o=e.faces.length,v)for(r=0;r<N;r++)for(E=t.uvs[r],e.faceVertexUvs[r][o]=[],n=0;n<3;n++)C=new l(E[2*(h=I[a++])],E[2*h+1]),e.faceVertexUvs[r][o].push(C);if(y&&(u=3*I[a++],S.normal.set(R[u++],R[u++],R[u])),b)for(r=0;r<3;r++)u=3*I[a++],T=new g(R[u++],R[u++],R[u]),S.vertexNormals.push(T);if(x&&(c=I[a++],S.color.setHex(O[c])),_)for(r=0;r<3;r++)c=I[a++],S.vertexColors.push(new tt(O[c]));e.faces.push(S)}}function e(t,e){var i=void 0!==t.influencesPerVertex?t.influencesPerVertex:2;if(t.skinWeights)for(var r=0,n=t.skinWeights.length;r<n;r+=i){var o=t.skinWeights[r],a=i>1?t.skinWeights[r+1]:0,s=i>2?t.skinWeights[r+2]:0,c=i>3?t.skinWeights[r+3]:0;e.skinWeights.push(new d(o,a,s,c))}if(t.skinIndices)for(var r=0,n=t.skinIndices.length;r<n;r+=i){var u=t.skinIndices[r],h=i>1?t.skinIndices[r+1]:0,l=i>2?t.skinIndices[r+2]:0,p=i>3?t.skinIndices[r+3]:0;e.skinIndices.push(new d(u,h,l,p))}e.bones=t.bones,e.bones&&e.bones.length>0&&(e.skinWeights.length!==e.skinIndices.length||e.skinIndices.length!==e.vertices.length)&&console.warn("When skinning, number of vertices ("+e.vertices.length+"), skinIndices ("+e.skinIndices.length+"), and skinWeights ("+e.skinWeights.length+") should match.")}function i(t,e){var i=t.scale;if(void 0!==t.morphTargets)for(var r=0,n=t.morphTargets.length;r<n;r++){e.morphTargets[r]={},e.morphTargets[r].name=t.morphTargets[r].name,e.morphTargets[r].vertices=[];for(var o=e.morphTargets[r].vertices,a=t.morphTargets[r].vertices,s=0,c=a.length;s<c;s+=3){var u=new g;u.x=a[s]*i,u.y=a[s+1]*i,u.z=a[s+2]*i,o.push(u)}}if(void 0!==t.morphColors&&t.morphColors.length>0){console.warn('THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.');for(var h=e.faces,l=t.morphColors[0].colors,r=0,n=h.length;r<n;r++)h[r].color.fromArray(l,3*r)}}function r(t,e){var i=[],r=[];void 0!==t.animation&&r.push(t.animation),void 0!==t.animations&&(t.animations.length?r=r.concat(t.animations):r.push(t.animations));for(var n=0;n<r.length;n++){var o=nr.parseAnimation(r[n],e.bones);o&&i.push(o)}if(e.morphTargets){var a=nr.CreateClipsFromMorphTargetSequences(e.morphTargets,10);i=i.concat(a)}i.length>0&&(e.animations=i)}return function(n,o){void 0!==n.data&&(n=n.data),void 0!==n.scale?n.scale=1/n.scale:n.scale=1;var a=new Et;return t(n,a),e(n,a),i(n,a),r(n,a),a.computeFaceNormals(),a.computeBoundingSphere(),void 0===n.materials||0===n.materials.length?{geometry:a}:{geometry:a,materials:sr.prototype.initMaterials(n.materials,o,this.crossOrigin)}}}()}),Object.assign(ur.prototype,{load:function(t,e,i,r){""===this.texturePath&&(this.texturePath=t.substring(0,t.lastIndexOf("/")+1));var n=this;new Ci(n.manager).load(t,function(i){var o=null;try{o=JSON.parse(i)}catch(e){return void 0!==r&&r(e),void console.error("THREE:ObjectLoader: Can't parse "+t+".",e.message)}var a=o.metadata;if(void 0===a||void 0===a.type||"geometry"===a.type.toLowerCase())return void console.error("THREE.ObjectLoader: Can't load "+t+". Use THREE.JSONLoader instead.");n.parse(o,e)},i,r)},setTexturePath:function(t){this.texturePath=t},setCrossOrigin:function(t){this.crossOrigin=t},parse:function(t,e){var i=this.parseGeometries(t.geometries),r=this.parseImages(t.images,function(){void 0!==e&&e(a)}),n=this.parseTextures(t.textures,r),o=this.parseMaterials(t.materials,n),a=this.parseObject(t.object,i,o);return t.animations&&(a.animations=this.parseAnimations(t.animations)),void 0!==t.images&&0!==t.images.length||void 0!==e&&e(a),a},parseGeometries:function(t){var e=this,i={};if(void 0!==t)for(var r=new cr,n=new ar,o=0,a=t.length;o<a;o++){var s,c=t[o];switch(c.type){case"PlaneGeometry":case"PlaneBufferGeometry":s=new zl[c.type](c.width,c.height,c.widthSegments,c.heightSegments);break;case"BoxGeometry":case"BoxBufferGeometry":case"CubeGeometry":s=new zl[c.type](c.width,c.height,c.depth,c.widthSegments,c.heightSegments,c.depthSegments);break;case"CircleGeometry":case"CircleBufferGeometry":s=new zl[c.type](c.radius,c.segments,c.thetaStart,c.thetaLength);break;case"CylinderGeometry":case"CylinderBufferGeometry":s=new zl[c.type](c.radiusTop,c.radiusBottom,c.height,c.radialSegments,c.heightSegments,c.openEnded,c.thetaStart,c.thetaLength);break;case"ConeGeometry":case"ConeBufferGeometry":s=new zl[c.type](c.radius,c.height,c.radialSegments,c.heightSegments,c.openEnded,c.thetaStart,c.thetaLength);break;case"SphereGeometry":case"SphereBufferGeometry":s=new zl[c.type](c.radius,c.widthSegments,c.heightSegments,c.phiStart,c.phiLength,c.thetaStart,c.thetaLength);break;case"DodecahedronGeometry":case"IcosahedronGeometry":case"OctahedronGeometry":case"TetrahedronGeometry":s=new zl[c.type](c.radius,c.detail);break;case"RingGeometry":case"RingBufferGeometry":s=new zl[c.type](c.innerRadius,c.outerRadius,c.thetaSegments,c.phiSegments,c.thetaStart,c.thetaLength);break;case"TorusGeometry":case"TorusBufferGeometry":s=new zl[c.type](c.radius,c.tube,c.radialSegments,c.tubularSegments,c.arc);break;case"TorusKnotGeometry":case"TorusKnotBufferGeometry":s=new zl[c.type](c.radius,c.tube,c.tubularSegments,c.radialSegments,c.p,c.q);break;case"LatheGeometry":case"LatheBufferGeometry":s=new zl[c.type](c.points,c.segments,c.phiStart,c.phiLength);break;case"BufferGeometry":s=n.parse(c);break;case"Geometry":s=r.parse(c,e.texturePath).geometry;break;default:console.warn('THREE.ObjectLoader: Unsupported geometry type "'+c.type+'"');continue}s.uuid=c.uuid,void 0!==c.name&&(s.name=c.name),i[c.uuid]=s}return i},parseMaterials:function(t,e){var i={};if(void 0!==t){var r=new or;r.setTextures(e);for(var n=0,o=t.length;n<o;n++){var a=r.parse(t[n]);i[a.uuid]=a}}return i},parseAnimations:function(t){for(var e=[],i=0;i<t.length;i++){var r=nr.parse(t[i]);e.push(r)}return e},parseImages:function(t,e){var i=this,r={};if(void 0!==t&&t.length>0){var n=new Ri(new Ei(e));n.setCrossOrigin(this.crossOrigin);for(var o=0,a=t.length;o<a;o++){var s=t[o],c=/^(\/\/)|([a-z]+:(\/\/)?)/i.test(s.url)?s.url:i.texturePath+s.url;r[s.uuid]=function(t){return i.manager.itemStart(t),n.load(t,function(){i.manager.itemEnd(t)},void 0,function(){i.manager.itemEnd(t),i.manager.itemError(t)})}(c)}}return r},parseTextures:function(t,e){function i(t,e){return"number"==typeof t?t:(console.warn("THREE.ObjectLoader.parseTexture: Constant should be in numeric form.",t),e[t])}var r={};if(void 0!==t)for(var n=0,o=t.length;n<o;n++){var a=t[n];void 0===a.image&&console.warn('THREE.ObjectLoader: No "image" specified for',a.uuid),void 0===e[a.image]&&console.warn("THREE.ObjectLoader: Undefined image",a.image);var s=new p(e[a.image]);s.needsUpdate=!0,s.uuid=a.uuid,void 0!==a.name&&(s.name=a.name),void 0!==a.mapping&&(s.mapping=i(a.mapping,Wl)),void 0!==a.offset&&s.offset.fromArray(a.offset),void 0!==a.repeat&&s.repeat.fromArray(a.repeat),void 0!==a.wrap&&(s.wrapS=i(a.wrap[0],Xl),s.wrapT=i(a.wrap[1],Xl)),void 0!==a.minFilter&&(s.minFilter=i(a.minFilter,ql)),void 0!==a.magFilter&&(s.magFilter=i(a.magFilter,ql)),void 0!==a.anisotropy&&(s.anisotropy=a.anisotropy),void 0!==a.flipY&&(s.flipY=a.flipY),r[a.uuid]=s}return r},parseObject:function(){var t=new v;return function(e,i,r){function n(t){return void 0===i[t]&&console.warn("THREE.ObjectLoader: Undefined geometry",t),i[t]}function o(t){if(void 0!==t){if(Array.isArray(t)){for(var e=[],i=0,n=t.length;i<n;i++){var o=t[i];void 0===r[o]&&console.warn("THREE.ObjectLoader: Undefined material",o),e.push(r[o])}return e}return void 0===r[t]&&console.warn("THREE.ObjectLoader: Undefined material",t),r[t]}}var a,s=this;switch(e.type){case"Scene":a=new ye,void 0!==e.background&&Number.isInteger(e.background)&&(a.background=new tt(e.background)),void 0!==e.fog&&("Fog"===e.fog.type?a.fog=new ve(e.fog.color,e.fog.near,e.fog.far):"FogExp2"===e.fog.type&&(a.fog=new ge(e.fog.color,e.fog.density)));break;case"PerspectiveCamera":a=new kt(e.fov,e.aspect,e.near,e.far),void 0!==e.focus&&(a.focus=e.focus),void 0!==e.zoom&&(a.zoom=e.zoom),void 0!==e.filmGauge&&(a.filmGauge=e.filmGauge),void 0!==e.filmOffset&&(a.filmOffset=e.filmOffset),void 0!==e.view&&(a.view=Object.assign({},e.view));break;case"OrthographicCamera":a=new Bt(e.left,e.right,e.top,e.bottom,e.near,e.far);break;case"AmbientLight":a=new Vi(e.color,e.intensity);break;case"DirectionalLight":a=new Gi(e.color,e.intensity);break;case"PointLight":a=new Ui(e.color,e.intensity,e.distance,e.decay);break;case"RectAreaLight":a=new $i(e.color,e.intensity,e.width,e.height);break;case"SpotLight":a=new zi(e.color,e.intensity,e.distance,e.angle,e.penumbra,e.decay);break;case"HemisphereLight":a=new ki(e.color,e.groundColor,e.intensity);break;case"SkinnedMesh":console.warn("THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.");case"Mesh":var c=n(e.geometry),u=o(e.material);a=c.bones&&c.bones.length>0?new Me(c,u):new It(c,u);break;case"LOD":a=new we;break;case"Line":a=new Te(n(e.geometry),o(e.material),e.mode);break;case"LineLoop":a=new Ce(n(e.geometry),o(e.material));break;case"LineSegments":a=new Ee(n(e.geometry),o(e.material));break;case"PointCloud":case"Points":a=new Le(n(e.geometry),o(e.material));break;case"Sprite":a=new _e(o(e.material));break;case"Group":a=new Re;break;default:a=new gt}if(a.uuid=e.uuid,void 0!==e.name&&(a.name=e.name),void 0!==e.matrix?(t.fromArray(e.matrix),t.decompose(a.position,a.quaternion,a.scale)):(void 0!==e.position&&a.position.fromArray(e.position),void 0!==e.rotation&&a.rotation.fromArray(e.rotation),void 0!==e.quaternion&&a.quaternion.fromArray(e.quaternion),void 0!==e.scale&&a.scale.fromArray(e.scale)),void 0!==e.castShadow&&(a.castShadow=e.castShadow),void 0!==e.receiveShadow&&(a.receiveShadow=e.receiveShadow),e.shadow&&(void 0!==e.shadow.bias&&(a.shadow.bias=e.shadow.bias),void 0!==e.shadow.radius&&(a.shadow.radius=e.shadow.radius),void 0!==e.shadow.mapSize&&a.shadow.mapSize.fromArray(e.shadow.mapSize),void 0!==e.shadow.camera&&(a.shadow.camera=this.parseObject(e.shadow.camera))),void 0!==e.visible&&(a.visible=e.visible),void 0!==e.userData&&(a.userData=e.userData),void 0!==e.children)for(var h in e.children)a.add(s.parseObject(e.children[h],i,r));if("LOD"===e.type)for(var l=e.levels,p=0;p<l.length;p++){var d=l[p];void 0!==(h=a.getObjectByProperty("uuid",d.object))&&a.addLevel(h,d.distance)}return a}}()});var Wl={UVMapping:300,CubeReflectionMapping:gh,CubeRefractionMapping:vh,EquirectangularReflectionMapping:yh,EquirectangularRefractionMapping:bh,SphericalReflectionMapping:xh,CubeUVReflectionMapping:_h,CubeUVRefractionMapping:wh},Xl={RepeatWrapping:Sh,ClampToEdgeWrapping:Ah,MirroredRepeatWrapping:Mh},ql={NearestFilter:Ph,NearestMipMapNearestFilter:Th,NearestMipMapLinearFilter:Eh,LinearFilter:Ch,LinearMipMapNearestFilter:Ih,LinearMipMapLinearFilter:Lh};Object.assign(xr.prototype,{getPoint:function(){return console.warn("THREE.Curve: .getPoint() not implemented."),null},getPointAt:function(t){var e=this.getUtoTmapping(t);return this.getPoint(e)},getPoints:function(t){var e=this;void 0===t&&(t=5);for(var i=[],r=0;r<=t;r++)i.push(e.getPoint(r/t));return i},getSpacedPoints:function(t){var e=this;void 0===t&&(t=5);for(var i=[],r=0;r<=t;r++)i.push(e.getPointAt(r/t));return i},getLength:function(){var t=this.getLengths();return t[t.length-1]},getLengths:function(t){var e=this;if(void 0===t&&(t=this.arcLengthDivisions),this.cacheArcLengths&&this.cacheArcLengths.length===t+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;var i,r,n=[],o=this.getPoint(0),a=0;for(n.push(0),r=1;r<=t;r++)a+=(i=e.getPoint(r/t)).distanceTo(o),n.push(a),o=i;return this.cacheArcLengths=n,n},updateArcLengths:function(){this.needsUpdate=!0,this.getLengths()},getUtoTmapping:function(t,e){var i,r=this.getLengths(),n=0,o=r.length;i=e||t*r[o-1];for(var a,s=0,c=o-1;s<=c;)if(n=Math.floor(s+(c-s)/2),(a=r[n]-i)<0)s=n+1;else{if(!(a>0)){c=n;break}c=n-1}if(n=c,r[n]===i)return n/(o-1);var u=r[n];return(n+(i-u)/(r[n+1]-u))/(o-1)},getTangent:function(t){var e=t-1e-4,i=t+1e-4;e<0&&(e=0),i>1&&(i=1);var r=this.getPoint(e);return this.getPoint(i).clone().sub(r).normalize()},getTangentAt:function(t){var e=this.getUtoTmapping(t);return this.getTangent(e)},computeFrenetFrames:function(t,e){var i,r,n,o=this,a=new g,s=[],c=[],u=[],h=new g,l=new v;for(i=0;i<=t;i++)r=i/t,s[i]=o.getTangentAt(r),s[i].normalize();c[0]=new g,u[0]=new g;var p=Number.MAX_VALUE,d=Math.abs(s[0].x),f=Math.abs(s[0].y),m=Math.abs(s[0].z);for(d<=p&&(p=d,a.set(1,0,0)),f<=p&&(p=f,a.set(0,1,0)),m<=p&&a.set(0,0,1),h.crossVectors(s[0],a).normalize(),c[0].crossVectors(s[0],h),u[0].crossVectors(s[0],c[0]),i=1;i<=t;i++)c[i]=c[i-1].clone(),u[i]=u[i-1].clone(),h.crossVectors(s[i-1],s[i]),h.length()>Number.EPSILON&&(h.normalize(),n=Math.acos(xl.clamp(s[i-1].dot(s[i]),-1,1)),c[i].applyMatrix4(l.makeRotationAxis(h,n))),u[i].crossVectors(s[i],c[i]);if(!0===e)for(n=Math.acos(xl.clamp(c[0].dot(c[t]),-1,1)),n/=t,s[0].dot(h.crossVectors(c[0],c[t]))>0&&(n=-n),i=1;i<=t;i++)c[i].applyMatrix4(l.makeRotationAxis(s[i],n*i)),u[i].crossVectors(s[i],c[i]);return{tangents:s,normals:c,binormals:u}}}),_r.prototype=Object.create(xr.prototype),_r.prototype.constructor=_r,_r.prototype.isLineCurve=!0,_r.prototype.getPoint=function(t){if(1===t)return this.v2.clone();var e=this.v2.clone().sub(this.v1);return e.multiplyScalar(t).add(this.v1),e},_r.prototype.getPointAt=function(t){return this.getPoint(t)},_r.prototype.getTangent=function(t){return this.v2.clone().sub(this.v1).normalize()},wr.prototype=Object.assign(Object.create(xr.prototype),{constructor:wr,add:function(t){this.curves.push(t)},closePath:function(){var t=this.curves[0].getPoint(0),e=this.curves[this.curves.length-1].getPoint(1);t.equals(e)||this.curves.push(new _r(e,t))},getPoint:function(t){for(var e=this,i=t*this.getLength(),r=this.getCurveLengths(),n=0;n<r.length;){if(r[n]>=i){var o=r[n]-i,a=e.curves[n],s=a.getLength(),c=0===s?0:1-o/s;return a.getPointAt(c)}n++}return null},getLength:function(){var t=this.getCurveLengths();return t[t.length-1]},updateArcLengths:function(){this.needsUpdate=!0,this.cacheLengths=null,this.getCurveLengths()},getCurveLengths:function(){var t=this;if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var e=[],i=0,r=0,n=this.curves.length;r<n;r++)i+=t.curves[r].getLength(),e.push(i);return this.cacheLengths=e,e},getSpacedPoints:function(t){var e=this;void 0===t&&(t=40);for(var i=[],r=0;r<=t;r++)i.push(e.getPoint(r/t));return this.autoClose&&i.push(i[0]),i},getPoints:function(t){t=t||12;for(var e,i=[],r=0,n=this.curves;r<n.length;r++)for(var o=n[r],a=o&&o.isEllipseCurve?2*t:o&&o.isLineCurve?1:o&&o.isSplineCurve?t*o.points.length:t,s=o.getPoints(a),c=0;c<s.length;c++){var u=s[c];e&&e.equals(u)||(i.push(u),e=u)}return this.autoClose&&i.length>1&&!i[i.length-1].equals(i[0])&&i.push(i[0]),i},createPointsGeometry:function(t){var e=this.getPoints(t);return this.createGeometry(e)},createSpacedPointsGeometry:function(t){var e=this.getSpacedPoints(t);return this.createGeometry(e)},createGeometry:function(t){for(var e=new Et,i=0,r=t.length;i<r;i++){var n=t[i];e.vertices.push(new g(n.x,n.y,n.z||0))}return e}}),Sr.prototype=Object.create(xr.prototype),Sr.prototype.constructor=Sr,Sr.prototype.isEllipseCurve=!0,Sr.prototype.getPoint=function(t){for(var e=2*Math.PI,i=this.aEndAngle-this.aStartAngle,r=Math.abs(i)<Number.EPSILON;i<0;)i+=e;for(;i>e;)i-=e;i<Number.EPSILON&&(i=r?0:e),!0!==this.aClockwise||r||(i===e?i=-e:i-=e);var n=this.aStartAngle+t*i,o=this.aX+this.xRadius*Math.cos(n),a=this.aY+this.yRadius*Math.sin(n);if(0!==this.aRotation){var s=Math.cos(this.aRotation),c=Math.sin(this.aRotation),u=o-this.aX,h=a-this.aY;o=u*s-h*c+this.aX,a=u*c+h*s+this.aY}return new l(o,a)},Ar.prototype=Object.create(xr.prototype),Ar.prototype.constructor=Ar,Ar.prototype.isSplineCurve=!0,Ar.prototype.getPoint=function(t){var e=this.points,i=(e.length-1)*t,r=Math.floor(i),n=i-r,o=e[0===r?r:r-1],a=e[r],s=e[r>e.length-2?e.length-1:r+1],c=e[r>e.length-3?e.length-1:r+2];return new l(hr(n,o.x,a.x,s.x,c.x),hr(n,o.y,a.y,s.y,c.y))},Mr.prototype=Object.create(xr.prototype),Mr.prototype.constructor=Mr,Mr.prototype.getPoint=function(t){var e=this.v0,i=this.v1,r=this.v2,n=this.v3;return new l(br(t,e.x,i.x,r.x,n.x),br(t,e.y,i.y,r.y,n.y))},Pr.prototype=Object.create(xr.prototype),Pr.prototype.constructor=Pr,Pr.prototype.getPoint=function(t){var e=this.v0,i=this.v1,r=this.v2;return new l(fr(t,e.x,i.x,r.x),fr(t,e.y,i.y,r.y))};var Yl=Object.assign(Object.create(wr.prototype),{fromPoints:function(t){var e=this;this.moveTo(t[0].x,t[0].y);for(var i=1,r=t.length;i<r;i++)e.lineTo(t[i].x,t[i].y)},moveTo:function(t,e){this.currentPoint.set(t,e)},lineTo:function(t,e){var i=new _r(this.currentPoint.clone(),new l(t,e));this.curves.push(i),this.currentPoint.set(t,e)},quadraticCurveTo:function(t,e,i,r){var n=new Pr(this.currentPoint.clone(),new l(t,e),new l(i,r));this.curves.push(n),this.currentPoint.set(i,r)},bezierCurveTo:function(t,e,i,r,n,o){var a=new Mr(this.currentPoint.clone(),new l(t,e),new l(i,r),new l(n,o));this.curves.push(a),this.currentPoint.set(n,o)},splineThru:function(t){var e=new Ar([this.currentPoint.clone()].concat(t));this.curves.push(e),this.currentPoint.copy(t[t.length-1])},arc:function(t,e,i,r,n,o){var a=this.currentPoint.x,s=this.currentPoint.y;this.absarc(t+a,e+s,i,r,n,o)},absarc:function(t,e,i,r,n,o){this.absellipse(t,e,i,i,r,n,o)},ellipse:function(t,e,i,r,n,o,a,s){var c=this.currentPoint.x,u=this.currentPoint.y;this.absellipse(t+c,e+u,i,r,n,o,a,s)},absellipse:function(t,e,i,r,n,o,a,s){var c=new Sr(t,e,i,r,n,o,a,s);if(this.curves.length>0){var u=c.getPoint(0);u.equals(this.currentPoint)||this.lineTo(u.x,u.y)}this.curves.push(c);var h=c.getPoint(1);this.currentPoint.copy(h)}});Tr.prototype=Yl,Yl.constructor=Tr,Er.prototype=Object.assign(Object.create(Yl),{constructor:Er,getPointsHoles:function(t){for(var e=this,i=[],r=0,n=this.holes.length;r<n;r++)i[r]=e.holes[r].getPoints(t);return i},extractAllPoints:function(t){return{shape:this.getPoints(t),holes:this.getPointsHoles(t)}},extractPoints:function(t){return this.extractAllPoints(t)}}),Object.assign(Cr.prototype,{moveTo:function(t,e){this.currentPath=new Tr,this.subPaths.push(this.currentPath),this.currentPath.moveTo(t,e)},lineTo:function(t,e){this.currentPath.lineTo(t,e)},quadraticCurveTo:function(t,e,i,r){this.currentPath.quadraticCurveTo(t,e,i,r)},bezierCurveTo:function(t,e,i,r,n,o){this.currentPath.bezierCurveTo(t,e,i,r,n,o)},splineThru:function(t){this.currentPath.splineThru(t)},toShapes:function(t,e){function i(t){for(var e=[],i=0,r=t.length;i<r;i++){var n=t[i],o=new Er;o.curves=n.curves,e.push(o)}return e}var r=Fl.isClockWise,n=this.subPaths;if(0===n.length)return[];if(!0===e)return i(n);var o,a,s,c=[];if(1===n.length)return a=n[0],s=new Er,s.curves=a.curves,c.push(s),c;var u=!r(n[0].getPoints());u=t?!u:u;var h,l=[],p=[],d=[],f=0;p[f]=void 0,d[f]=[];for(var m=0,g=n.length;m<g;m++)o=r(h=(a=n[m]).getPoints()),(o=t?!o:o)?(!u&&p[f]&&f++,p[f]={s:new Er,p:h},p[f].s.curves=a.curves,u&&f++,d[f]=[]):d[f].push({h:a,p:h[0]});if(!p[0])return i(n);if(p.length>1){for(var v=!1,y=[],b=0,x=p.length;b<x;b++)l[b]=[];for(var b=0,x=p.length;b<x;b++)for(var _=d[b],w=0;w<_.length;w++){for(var S=_[w],A=!0,M=0;M<p.length;M++)(function(t,e){for(var i=e.length,r=!1,n=i-1,o=0;o<i;n=o++){var a=e[n],s=e[o],c=s.x-a.x,u=s.y-a.y;if(Math.abs(u)>Number.EPSILON){if(u<0&&(a=e[o],c=-c,s=e[n],u=-u),t.y<a.y||t.y>s.y)continue;if(t.y===a.y){if(t.x===a.x)return!0}else{var h=u*(t.x-a.x)-c*(t.y-a.y);if(0===h)return!0;if(h<0)continue;r=!r}}else{if(t.y!==a.y)continue;if(s.x<=t.x&&t.x<=a.x||a.x<=t.x&&t.x<=s.x)return!0}}return r})(S.p,p[M].p)&&(b!==M&&y.push({froms:b,tos:M,hole:w}),A?(A=!1,l[M].push(S)):v=!0);A&&l[b].push(S)}y.length>0&&(v||(d=l))}for(var P,m=0,T=p.length;m<T;m++){s=p[m].s,c.push(s);for(var E=0,C=(P=d[m]).length;E<C;E++)s.holes.push(P[E].h)}return c}}),Object.assign(Ir.prototype,{isFont:!0,generateShapes:function(t,e,i){function r(t,e,r,o){var a=n.glyphs[t]||n.glyphs["?"];if(a){var s,c,u,h,l,p,d,f,m,g,v,y=new Cr,b=[];if(a.o)for(var x=a._cachedOutline||(a._cachedOutline=a.o.split(" ")),_=0,w=x.length;_<w;)switch(x[_++]){case"m":s=x[_++]*e+r,c=x[_++]*e+o,y.moveTo(s,c);break;case"l":s=x[_++]*e+r,c=x[_++]*e+o,y.lineTo(s,c);break;case"q":if(u=x[_++]*e+r,h=x[_++]*e+o,d=x[_++]*e+r,f=x[_++]*e+o,y.quadraticCurveTo(d,f,u,h),v=b[b.length-1]){l=v.x,p=v.y;for(S=1;S<=i;S++)fr(A=S/i,l,d,u),fr(A,p,f,h)}break;case"b":if(u=x[_++]*e+r,h=x[_++]*e+o,d=x[_++]*e+r,f=x[_++]*e+o,m=x[_++]*e+r,g=x[_++]*e+o,y.bezierCurveTo(d,f,m,g,u,h),v=b[b.length-1]){l=v.x,p=v.y;for(var S=1;S<=i;S++){var A=S/i;br(A,l,d,m,u),br(A,p,f,g,h)}}}return{offsetX:a.ha*e,path:y}}}void 0===e&&(e=100),void 0===i&&(i=4);for(var n=this.data,o=function(t){for(var i=String(t).split(""),o=e/n.resolution,a=(n.boundingBox.yMax-n.boundingBox.yMin+n.underlineThickness)*o,s=0,c=0,u=[],h=0;h<i.length;h++){var l=i[h];if("\n"===l)s=0,c-=a;else{var p=r(l,o,s,c);s+=p.offsetX,u.push(p.path)}}return u}(t),a=[],s=0,c=o.length;s<c;s++)Array.prototype.push.apply(a,o[s].toShapes());return a}}),Object.assign(Lr.prototype,{load:function(t,e,i,r){var n=this;new Ci(this.manager).load(t,function(t){var i;try{i=JSON.parse(t)}catch(e){console.warn("THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead."),i=JSON.parse(t.substring(65,t.length-2))}var r=n.parse(i);e&&e(r)},i,r)},parse:function(t){return new Ir(t)}});var Zl,Kl={getContext:function(){return void 0===Zl&&(Zl=new(window.AudioContext||window.webkitAudioContext)),Zl},setContext:function(t){Zl=t}};Object.assign(Rr.prototype,{load:function(t,e,i,r){var n=new Ci(this.manager);n.setResponseType("arraybuffer"),n.load(t,function(t){Kl.getContext().decodeAudioData(t,function(t){e(t)})},i,r)}}),Object.assign(Or.prototype,{update:function(){var t,e,i,r,n,o,a,s,c=new v,u=new v;return function(h){if(t!==this||e!==h.focus||i!==h.fov||r!==h.aspect*this.aspect||n!==h.near||o!==h.far||a!==h.zoom||s!==this.eyeSep){t=this,e=h.focus,i=h.fov,r=h.aspect*this.aspect,n=h.near,o=h.far,a=h.zoom;var l,p,d=h.projectionMatrix.clone(),f=(s=this.eyeSep/2)*n/e,m=n*Math.tan(xl.DEG2RAD*i*.5)/a;u.elements[12]=-s,c.elements[12]=s,l=-m*r+f,p=m*r+f,d.elements[0]=2*n/(p-l),d.elements[8]=(p+l)/(p-l),this.cameraL.projectionMatrix.copy(d),l=-m*r-f,p=m*r-f,d.elements[0]=2*n/(p-l),d.elements[8]=(p+l)/(p-l),this.cameraR.projectionMatrix.copy(d)}this.cameraL.matrixWorld.copy(h.matrixWorld).multiply(u),this.cameraR.matrixWorld.copy(h.matrixWorld).multiply(c)}}()}),Dr.prototype=Object.assign(Object.create(kt.prototype),{constructor:Dr,isArrayCamera:!0}),Nr.prototype=Object.assign(Object.create(gt.prototype),{constructor:Nr,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null)},getFilter:function(){return this.filter},setFilter:function(t){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination),this.filter=t,this.gain.connect(this.filter),this.filter.connect(this.context.destination)},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(t){this.gain.gain.value=t},updateMatrixWorld:function(){var t=new g,e=new m,i=new g,r=new g;return function(n){gt.prototype.updateMatrixWorld.call(this,n);var o=this.context.listener,a=this.up;this.matrixWorld.decompose(t,e,i),r.set(0,0,-1).applyQuaternion(e),o.positionX?(o.positionX.setValueAtTime(t.x,this.context.currentTime),o.positionY.setValueAtTime(t.y,this.context.currentTime),o.positionZ.setValueAtTime(t.z,this.context.currentTime),o.forwardX.setValueAtTime(r.x,this.context.currentTime),o.forwardY.setValueAtTime(r.y,this.context.currentTime),o.forwardZ.setValueAtTime(r.z,this.context.currentTime),o.upX.setValueAtTime(a.x,this.context.currentTime),o.upY.setValueAtTime(a.y,this.context.currentTime),o.upZ.setValueAtTime(a.z,this.context.currentTime)):(o.setPosition(t.x,t.y,t.z),o.setOrientation(r.x,r.y,r.z,a.x,a.y,a.z))}}()}),kr.prototype=Object.assign(Object.create(gt.prototype),{constructor:kr,getOutput:function(){return this.gain},setNodeSource:function(t){return this.hasPlaybackControl=!1,this.sourceType="audioNode",this.source=t,this.connect(),this},setBuffer:function(t){return this.buffer=t,this.sourceType="buffer",this.autoplay&&this.play(),this},play:function(){if(!0===this.isPlaying)return void console.warn("THREE.Audio: Audio is already playing.");if(!1===this.hasPlaybackControl)return void console.warn("THREE.Audio: this Audio has no playback control.");var t=this.context.createBufferSource();return t.buffer=this.buffer,t.loop=this.loop,t.onended=this.onEnded.bind(this),t.playbackRate.setValueAtTime(this.playbackRate,this.startTime),t.start(0,this.startTime),this.isPlaying=!0,this.source=t,this.connect()},pause:function(){return!1===this.hasPlaybackControl?void console.warn("THREE.Audio: this Audio has no playback control."):(this.source.stop(),this.startTime=this.context.currentTime,this.isPlaying=!1,this)},stop:function(){return!1===this.hasPlaybackControl?void console.warn("THREE.Audio: this Audio has no playback control."):(this.source.stop(),this.startTime=0,this.isPlaying=!1,this)},connect:function(){var t=this;if(this.filters.length>0){this.source.connect(this.filters[0]);for(var e=1,i=this.filters.length;e<i;e++)t.filters[e-1].connect(t.filters[e]);this.filters[this.filters.length-1].connect(this.getOutput())}else this.source.connect(this.getOutput());return this},disconnect:function(){var t=this;if(this.filters.length>0){this.source.disconnect(this.filters[0]);for(var e=1,i=this.filters.length;e<i;e++)t.filters[e-1].disconnect(t.filters[e]);this.filters[this.filters.length-1].disconnect(this.getOutput())}else this.source.disconnect(this.getOutput());return this},getFilters:function(){return this.filters},setFilters:function(t){return t||(t=[]),!0===this.isPlaying?(this.disconnect(),this.filters=t,this.connect()):this.filters=t,this},getFilter:function(){return this.getFilters()[0]},setFilter:function(t){return this.setFilters(t?[t]:[])},setPlaybackRate:function(t){return!1===this.hasPlaybackControl?void console.warn("THREE.Audio: this Audio has no playback control."):(this.playbackRate=t,!0===this.isPlaying&&this.source.playbackRate.setValueAtTime(this.playbackRate,this.context.currentTime),this)},getPlaybackRate:function(){return this.playbackRate},onEnded:function(){this.isPlaying=!1},getLoop:function(){return!1===this.hasPlaybackControl?(console.warn("THREE.Audio: this Audio has no playback control."),!1):this.loop},setLoop:function(t){return!1===this.hasPlaybackControl?void console.warn("THREE.Audio: this Audio has no playback control."):(this.loop=t,!0===this.isPlaying&&(this.source.loop=this.loop),this)},getVolume:function(){return this.gain.gain.value},setVolume:function(t){return this.gain.gain.value=t,this}}),Br.prototype=Object.assign(Object.create(kr.prototype),{constructor:Br,getOutput:function(){return this.panner},getRefDistance:function(){return this.panner.refDistance},setRefDistance:function(t){this.panner.refDistance=t},getRolloffFactor:function(){return this.panner.rolloffFactor},setRolloffFactor:function(t){this.panner.rolloffFactor=t},getDistanceModel:function(){return this.panner.distanceModel},setDistanceModel:function(t){this.panner.distanceModel=t},getMaxDistance:function(){return this.panner.maxDistance},setMaxDistance:function(t){this.panner.maxDistance=t},updateMatrixWorld:function(){var t=new g;return function(e){gt.prototype.updateMatrixWorld.call(this,e),t.setFromMatrixPosition(this.matrixWorld),this.panner.setPosition(t.x,t.y,t.z)}}()}),Object.assign(Fr.prototype,{getFrequencyData:function(){return this.analyser.getByteFrequencyData(this.data),this.data},getAverageFrequency:function(){for(var t=0,e=this.getFrequencyData(),i=0;i<e.length;i++)t+=e[i];return t/e.length}}),Object.assign(zr.prototype,{accumulate:function(t,e){var i=this.buffer,r=this.valueSize,n=t*r+r,o=this.cumulativeWeight;if(0===o){for(var a=0;a!==r;++a)i[n+a]=i[a];o=e}else{var s=e/(o+=e);this._mixBufferRegion(i,n,0,s,r)}this.cumulativeWeight=o},apply:function(t){var e=this.valueSize,i=this.buffer,r=t*e+e,n=this.cumulativeWeight,o=this.binding;if(this.cumulativeWeight=0,n<1){var a=3*e;this._mixBufferRegion(i,r,a,1-n,e)}for(var s=e,c=e+e;s!==c;++s)if(i[s]!==i[s+e]){o.setValue(i,r);break}},saveOriginalState:function(){var t=this.binding,e=this.buffer,i=this.valueSize,r=3*i;t.getValue(e,r);for(var n=i,o=r;n!==o;++n)e[n]=e[r+n%i];this.cumulativeWeight=0},restoreOriginalState:function(){var t=3*this.valueSize;this.binding.setValue(this.buffer,t)},_select:function(t,e,i,r,n){if(r>=.5)for(var o=0;o!==n;++o)t[e+o]=t[i+o]},_slerp:function(t,e,i,r){m.slerpFlat(t,e,t,e,t,i,r)},_lerp:function(t,e,i,r,n){for(var o=1-r,a=0;a!==n;++a){var s=e+a;t[s]=t[s]*o+t[i+a]*r}}}),Object.assign(Ur.prototype,{getValue:function(t,e){this.bind();var i=this._targetGroup.nCachedObjects_,r=this._bindings[i];void 0!==r&&r.getValue(t,e)},setValue:function(t,e){for(var i=this._bindings,r=this._targetGroup.nCachedObjects_,n=i.length;r!==n;++r)i[r].setValue(t,e)},bind:function(){for(var t=this._bindings,e=this._targetGroup.nCachedObjects_,i=t.length;e!==i;++e)t[e].bind()},unbind:function(){for(var t=this._bindings,e=this._targetGroup.nCachedObjects_,i=t.length;e!==i;++e)t[e].unbind()}}),Object.assign(jr,{Composite:Ur,create:function(t,e,i){return t&&t.isAnimationObjectGroup?new jr.Composite(t,e,i):new jr(t,e,i)},parseTrackName:function(){var t=new RegExp("^"+/((?:[\w-]+[\/:])*)/.source+/([\w-\.]+)?/.source+/(?:\.([\w-]+)(?:\[(.+)\])?)?/.source+/\.([\w-]+)(?:\[(.+)\])?/.source+"$"),e=["material","materials","bones"];return function(i){var r=t.exec(i);if(!r)throw new Error("PropertyBinding: Cannot parse trackName: "+i);var n={nodeName:r[2],objectName:r[3],objectIndex:r[4],propertyName:r[5],propertyIndex:r[6]},o=n.nodeName&&n.nodeName.lastIndexOf(".");if(void 0!==o&&-1!==o){var a=n.nodeName.substring(o+1);-1!==e.indexOf(a)&&(n.nodeName=n.nodeName.substring(0,o),n.objectName=a)}if(null===n.propertyName||0===n.propertyName.length)throw new Error("PropertyBinding: can not parse propertyName from trackName: "+i);return n}}(),findNode:function(t,e){if(!e||""===e||"root"===e||"."===e||-1===e||e===t.name||e===t.uuid)return t;if(t.skeleton){var i=function(t){for(var i=0;i<t.bones.length;i++){var r=t.bones[i];if(r.name===e)return r}return null}(t.skeleton);if(i)return i}if(t.children){var r=function(t){for(var i=0;i<t.length;i++){var n=t[i];if(n.name===e||n.uuid===e)return n;var o=r(n.children);if(o)return o}return null},n=r(t.children);if(n)return n}return null}}),Object.assign(jr.prototype,{_getValue_unavailable:function(){},_setValue_unavailable:function(){},BindingType:{Direct:0,EntireArray:1,ArrayElement:2,HasFromToArray:3},Versioning:{None:0,NeedsUpdate:1,MatrixWorldNeedsUpdate:2},GetterByBindingType:[function(t,e){t[e]=this.node[this.propertyName]},function(t,e){for(var i=this.resolvedProperty,r=0,n=i.length;r!==n;++r)t[e++]=i[r]},function(t,e){t[e]=this.resolvedProperty[this.propertyIndex]},function(t,e){this.resolvedProperty.toArray(t,e)}],SetterByBindingTypeAndVersioning:[[function(t,e){this.node[this.propertyName]=t[e]},function(t,e){this.node[this.propertyName]=t[e],this.targetObject.needsUpdate=!0},function(t,e){this.node[this.propertyName]=t[e],this.targetObject.matrixWorldNeedsUpdate=!0}],[function(t,e){for(var i=this.resolvedProperty,r=0,n=i.length;r!==n;++r)i[r]=t[e++]},function(t,e){for(var i=this.resolvedProperty,r=0,n=i.length;r!==n;++r)i[r]=t[e++];this.targetObject.needsUpdate=!0},function(t,e){for(var i=this.resolvedProperty,r=0,n=i.length;r!==n;++r)i[r]=t[e++];this.targetObject.matrixWorldNeedsUpdate=!0}],[function(t,e){this.resolvedProperty[this.propertyIndex]=t[e]},function(t,e){this.resolvedProperty[this.propertyIndex]=t[e],this.targetObject.needsUpdate=!0},function(t,e){this.resolvedProperty[this.propertyIndex]=t[e],this.targetObject.matrixWorldNeedsUpdate=!0}],[function(t,e){this.resolvedProperty.fromArray(t,e)},function(t,e){this.resolvedProperty.fromArray(t,e),this.targetObject.needsUpdate=!0},function(t,e){this.resolvedProperty.fromArray(t,e),this.targetObject.matrixWorldNeedsUpdate=!0}]],getValue:function(t,e){this.bind(),this.getValue(t,e)},setValue:function(t,e){this.bind(),this.setValue(t,e)},bind:function(){var t=this.node,e=this.parsedPath,i=e.objectName,r=e.propertyName,n=e.propertyIndex;if(t||(t=jr.findNode(this.rootNode,e.nodeName)||this.rootNode,this.node=t),this.getValue=this._getValue_unavailable,this.setValue=this._setValue_unavailable,!t)return void console.error("  trying to update node for track: "+this.path+" but it wasn't found.");if(i){var o=e.objectIndex;switch(i){case"materials":if(!t.material)return void console.error("  can not bind to material as node does not have a material",this);if(!t.material.materials)return void console.error("  can not bind to material.materials as node.material does not have a materials array",this);t=t.material.materials;break;case"bones":if(!t.skeleton)return void console.error("  can not bind to bones as node does not have a skeleton",this);t=t.skeleton.bones;for(h=0;h<t.length;h++)if(t[h].name===o){o=h;break}break;default:if(void 0===t[i])return void console.error("  can not bind to objectName of node, undefined",this);t=t[i]}if(void 0!==o){if(void 0===t[o])return void console.error("  trying to bind to objectIndex of objectName, but is undefined:",this,t);t=t[o]}}var a=t[r];if(void 0===a){var s=e.nodeName;return void console.error("  trying to update property for track: "+s+"."+r+" but it wasn't found.",t)}var c=this.Versioning.None;void 0!==t.needsUpdate?(c=this.Versioning.NeedsUpdate,this.targetObject=t):void 0!==t.matrixWorldNeedsUpdate&&(c=this.Versioning.MatrixWorldNeedsUpdate,this.targetObject=t);var u=this.BindingType.Direct;if(void 0!==n){if("morphTargetInfluences"===r){if(!t.geometry)return void console.error("  can not bind to morphTargetInfluences becasuse node does not have a geometry",this);if(!t.geometry.morphTargets)return void console.error("  can not bind to morphTargetInfluences becasuse node does not have a geometry.morphTargets",this);for(var h=0;h<this.node.geometry.morphTargets.length;h++)if(t.geometry.morphTargets[h].name===n){n=h;break}}u=this.BindingType.ArrayElement,this.resolvedProperty=a,this.propertyIndex=n}else void 0!==a.fromArray&&void 0!==a.toArray?(u=this.BindingType.HasFromToArray,this.resolvedProperty=a):Array.isArray(a)?(u=this.BindingType.EntireArray,this.resolvedProperty=a):this.propertyName=r;this.getValue=this.GetterByBindingType[u],this.setValue=this.SetterByBindingTypeAndVersioning[u][c]},unbind:function(){this.node=null,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}}),Object.assign(jr.prototype,{_getValue_unbound:jr.prototype.getValue,_setValue_unbound:jr.prototype.setValue}),Object.assign(Gr.prototype,{isAnimationObjectGroup:!0,add:function(t){for(var e=arguments,i=this._objects,r=i.length,n=this.nCachedObjects_,o=this._indicesByUUID,a=this._paths,s=this._parsedPaths,c=this._bindings,u=c.length,h=0,l=arguments.length;h!==l;++h){var p=e[h],d=p.uuid,f=o[d],m=void 0;if(void 0===f){f=r++,o[d]=f,i.push(p);for(var g=0,v=u;g!==v;++g)c[g].push(new jr(p,a[g],s[g]))}else if(f<n){m=i[f];var y=--n,b=i[y];o[b.uuid]=f,i[f]=b,o[d]=y,i[y]=p;for(var g=0,v=u;g!==v;++g){var x=c[g],_=x[y],w=x[f];x[f]=_,void 0===w&&(w=new jr(p,a[g],s[g])),x[y]=w}}else i[f]!==m&&console.error("Different objects with the same UUID detected. Clean the caches or recreate your infrastructure when reloading scenes...")}this.nCachedObjects_=n},remove:function(t){for(var e=arguments,i=this._objects,r=this.nCachedObjects_,n=this._indicesByUUID,o=this._bindings,a=o.length,s=0,c=arguments.length;s!==c;++s){var u=e[s],h=u.uuid,l=n[h];if(void 0!==l&&l>=r){var p=r++,d=i[p];n[d.uuid]=l,i[l]=d,n[h]=p,i[p]=u;for(var f=0,m=a;f!==m;++f){var g=o[f],v=g[p],y=g[l];g[l]=v,g[p]=y}}}this.nCachedObjects_=r},uncache:function(t){for(var e=arguments,i=this._objects,r=i.length,n=this.nCachedObjects_,o=this._indicesByUUID,a=this._bindings,s=a.length,c=0,u=arguments.length;c!==u;++c){var h=e[c].uuid,l=o[h];if(void 0!==l)if(delete o[h],l<n){var p=--n,d=i[p],f=i[b=--r];o[d.uuid]=l,i[l]=d,o[f.uuid]=p,i[p]=f,i.pop();for(var m=0,g=s;m!==g;++m){var v=(x=a[m])[p],y=x[b];x[l]=v,x[p]=y,x.pop()}}else{var b=--r;o[(f=i[b]).uuid]=l,i[l]=f,i.pop();for(var m=0,g=s;m!==g;++m){var x=a[m];x[l]=x[b],x.pop()}}}this.nCachedObjects_=n},subscribe_:function(t,e){var i=this._bindingsIndicesByPath,r=i[t],n=this._bindings;if(void 0!==r)return n[r];var o=this._paths,a=this._parsedPaths,s=this._objects,c=s.length,u=this.nCachedObjects_,h=new Array(c);r=n.length,i[t]=r,o.push(t),a.push(e),n.push(h);for(var l=u,p=s.length;l!==p;++l){var d=s[l];h[l]=new jr(d,t,e)}return h},unsubscribe_:function(t){var e=this._bindingsIndicesByPath,i=e[t];if(void 0!==i){var r=this._paths,n=this._parsedPaths,o=this._bindings,a=o.length-1,s=o[a];e[t[a]]=i,o[i]=s,o.pop(),n[i]=n[a],n.pop(),r[i]=r[a],r.pop()}}}),Object.assign(Vr.prototype,{play:function(){return this._mixer._activateAction(this),this},stop:function(){return this._mixer._deactivateAction(this),this.reset()},reset:function(){return this.paused=!1,this.enabled=!0,this.time=0,this._loopCount=-1,this._startTime=null,this.stopFading().stopWarping()},isRunning:function(){return this.enabled&&!this.paused&&0!==this.timeScale&&null===this._startTime&&this._mixer._isActiveAction(this)},isScheduled:function(){return this._mixer._isActiveAction(this)},startAt:function(t){return this._startTime=t,this},setLoop:function(t,e){return this.loop=t,this.repetitions=e,this},setEffectiveWeight:function(t){return this.weight=t,this._effectiveWeight=this.enabled?t:0,this.stopFading()},getEffectiveWeight:function(){return this._effectiveWeight},fadeIn:function(t){return this._scheduleFading(t,0,1)},fadeOut:function(t){return this._scheduleFading(t,1,0)},crossFadeFrom:function(t,e,i){if(t.fadeOut(e),this.fadeIn(e),i){var r=this._clip.duration,n=t._clip.duration,o=n/r,a=r/n;t.warp(1,o,e),this.warp(a,1,e)}return this},crossFadeTo:function(t,e,i){return t.crossFadeFrom(this,e,i)},stopFading:function(){var t=this._weightInterpolant;return null!==t&&(this._weightInterpolant=null,this._mixer._takeBackControlInterpolant(t)),this},setEffectiveTimeScale:function(t){return this.timeScale=t,this._effectiveTimeScale=this.paused?0:t,this.stopWarping()},getEffectiveTimeScale:function(){return this._effectiveTimeScale},setDuration:function(t){return this.timeScale=this._clip.duration/t,this.stopWarping()},syncWith:function(t){return this.time=t.time,this.timeScale=t.timeScale,this.stopWarping()},halt:function(t){return this.warp(this._effectiveTimeScale,0,t)},warp:function(t,e,i){var r=this._mixer,n=r.time,o=this._timeScaleInterpolant,a=this.timeScale;null===o&&(o=r._lendControlInterpolant(),this._timeScaleInterpolant=o);var s=o.parameterPositions,c=o.sampleValues;return s[0]=n,s[1]=n+i,c[0]=t/a,c[1]=e/a,this},stopWarping:function(){var t=this._timeScaleInterpolant;return null!==t&&(this._timeScaleInterpolant=null,this._mixer._takeBackControlInterpolant(t)),this},getMixer:function(){return this._mixer},getClip:function(){return this._clip},getRoot:function(){return this._localRoot||this._mixer._root},_update:function(t,e,i,r){if(!this.enabled)return void this._updateWeight(t);var n=this._startTime;if(null!==n){var o=(t-n)*i;if(o<0||0===i)return;this._startTime=null,e=i*o}e*=this._updateTimeScale(t);var a=this._updateTime(e),s=this._updateWeight(t);if(s>0)for(var c=this._interpolants,u=this._propertyBindings,h=0,l=c.length;h!==l;++h)c[h].evaluate(a),u[h].accumulate(r,s)},_updateWeight:function(t){var e=0;if(this.enabled){e=this.weight;var i=this._weightInterpolant;if(null!==i){var r=i.evaluate(t)[0];e*=r,t>i.parameterPositions[1]&&(this.stopFading(),0===r&&(this.enabled=!1))}}return this._effectiveWeight=e,e},_updateTimeScale:function(t){var e=0;if(!this.paused){e=this.timeScale;var i=this._timeScaleInterpolant;null!==i&&(e*=i.evaluate(t)[0],t>i.parameterPositions[1]&&(this.stopWarping(),0===e?this.paused=!0:this.timeScale=e))}return this._effectiveTimeScale=e,e},_updateTime:function(t){var e=this.time+t;if(0===t)return e;var i=this._clip.duration,r=this.loop,n=this._loopCount;if(2200===r){-1===n&&(this._loopCount=0,this._setEndings(!0,!0,!1));t:{if(e>=i)e=i;else{if(!(e<0))break t;e=0}this.clampWhenFinished?this.paused=!0:this.enabled=!1,this._mixer.dispatchEvent({type:"finished",action:this,direction:t<0?-1:1})}}else{var o=2202===r;if(-1===n&&(t>=0?(n=0,this._setEndings(!0,0===this.repetitions,o)):this._setEndings(0===this.repetitions,!0,o)),e>=i||e<0){var a=Math.floor(e/i);e-=i*a,n+=Math.abs(a);var s=this.repetitions-n;if(s<0)this.clampWhenFinished?this.paused=!0:this.enabled=!1,e=t>0?i:0,this._mixer.dispatchEvent({type:"finished",action:this,direction:t>0?1:-1});else{if(0===s){var c=t<0;this._setEndings(c,!c,o)}else this._setEndings(!1,!1,o);this._loopCount=n,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:a})}}if(o&&1==(1&n))return this.time=e,i-e}return this.time=e,e},_setEndings:function(t,e,i){var r=this._interpolantSettings;i?(r.endingStart=2401,r.endingEnd=2401):(r.endingStart=t?this.zeroSlopeAtStart?2401:sl:2402,r.endingEnd=e?this.zeroSlopeAtEnd?2401:sl:2402)},_scheduleFading:function(t,e,i){var r=this._mixer,n=r.time,o=this._weightInterpolant;null===o&&(o=r._lendControlInterpolant(),this._weightInterpolant=o);var a=o.parameterPositions,s=o.sampleValues;return a[0]=n,s[0]=e,a[1]=n+t,s[1]=i,this}}),Object.assign($r.prototype,h.prototype,{_bindAction:function(t,e){var i=this,r=t._localRoot||this._root,n=t._clip.tracks,o=n.length,a=t._propertyBindings,s=t._interpolants,c=r.uuid,u=this._bindingsByRootAndName,h=u[c];void 0===h&&(h={},u[c]=h);for(var l=0;l!==o;++l){var p=n[l],d=p.name,f=h[d];if(void 0!==f)a[l]=f;else{if(void 0!==(f=a[l])){null===f._cacheIndex&&(++f.referenceCount,i._addInactiveBinding(f,c,d));continue}var m=e&&e._propertyBindings[l].binding.parsedPath;++(f=new zr(jr.create(r,d,m),p.ValueTypeName,p.getValueSize())).referenceCount,i._addInactiveBinding(f,c,d),a[l]=f}s[l].resultBuffer=f.buffer}},_activateAction:function(t){var e=this;if(!this._isActiveAction(t)){if(null===t._cacheIndex){var i=(t._localRoot||this._root).uuid,r=t._clip.uuid,n=this._actionsByClip[r];this._bindAction(t,n&&n.knownActions[0]),this._addInactiveAction(t,r,i)}for(var o=t._propertyBindings,a=0,s=o.length;a!==s;++a){var c=o[a];0==c.useCount++&&(e._lendBinding(c),c.saveOriginalState())}this._lendAction(t)}},_deactivateAction:function(t){var e=this;if(this._isActiveAction(t)){for(var i=t._propertyBindings,r=0,n=i.length;r!==n;++r){var o=i[r];0==--o.useCount&&(o.restoreOriginalState(),e._takeBackBinding(o))}this._takeBackAction(t)}},_initMemoryManager:function(){this._actions=[],this._nActiveActions=0,this._actionsByClip={},this._bindings=[],this._nActiveBindings=0,this._bindingsByRootAndName={},this._controlInterpolants=[],this._nActiveControlInterpolants=0;var t=this;this.stats={actions:{get total(){return t._actions.length},get inUse(){return t._nActiveActions}},bindings:{get total(){return t._bindings.length},get inUse(){return t._nActiveBindings}},controlInterpolants:{get total(){return t._controlInterpolants.length},get inUse(){return t._nActiveControlInterpolants}}}},_isActiveAction:function(t){var e=t._cacheIndex;return null!==e&&e<this._nActiveActions},_addInactiveAction:function(t,e,i){var r=this._actions,n=this._actionsByClip,o=n[e];if(void 0===o)o={knownActions:[t],actionByRoot:{}},t._byClipCacheIndex=0,n[e]=o;else{var a=o.knownActions;t._byClipCacheIndex=a.length,a.push(t)}t._cacheIndex=r.length,r.push(t),o.actionByRoot[i]=t},_removeInactiveAction:function(t){var e=this._actions,i=e[e.length-1],r=t._cacheIndex;i._cacheIndex=r,e[r]=i,e.pop(),t._cacheIndex=null;var n=t._clip.uuid,o=this._actionsByClip,a=o[n],s=a.knownActions,c=s[s.length-1],u=t._byClipCacheIndex;c._byClipCacheIndex=u,s[u]=c,s.pop(),t._byClipCacheIndex=null,delete a.actionByRoot[(t._localRoot||this._root).uuid],0===s.length&&delete o[n],this._removeInactiveBindingsForAction(t)},_removeInactiveBindingsForAction:function(t){for(var e=this,i=t._propertyBindings,r=0,n=i.length;r!==n;++r){var o=i[r];0==--o.referenceCount&&e._removeInactiveBinding(o)}},_lendAction:function(t){var e=this._actions,i=t._cacheIndex,r=this._nActiveActions++,n=e[r];t._cacheIndex=r,e[r]=t,n._cacheIndex=i,e[i]=n},_takeBackAction:function(t){var e=this._actions,i=t._cacheIndex,r=--this._nActiveActions,n=e[r];t._cacheIndex=r,e[r]=t,n._cacheIndex=i,e[i]=n},_addInactiveBinding:function(t,e,i){var r=this._bindingsByRootAndName,n=r[e],o=this._bindings;void 0===n&&(n={},r[e]=n),n[i]=t,t._cacheIndex=o.length,o.push(t)},_removeInactiveBinding:function(t){var e=this._bindings,i=t.binding,r=i.rootNode.uuid,n=i.path,o=this._bindingsByRootAndName,a=o[r],s=e[e.length-1],c=t._cacheIndex;s._cacheIndex=c,e[c]=s,e.pop(),delete a[n];t:{for(var u in a)break t;delete o[r]}},_lendBinding:function(t){var e=this._bindings,i=t._cacheIndex,r=this._nActiveBindings++,n=e[r];t._cacheIndex=r,e[r]=t,n._cacheIndex=i,e[i]=n},_takeBackBinding:function(t){var e=this._bindings,i=t._cacheIndex,r=--this._nActiveBindings,n=e[r];t._cacheIndex=r,e[r]=t,n._cacheIndex=i,e[i]=n},_lendControlInterpolant:function(){var t=this._controlInterpolants,e=this._nActiveControlInterpolants++,i=t[e];return void 0===i&&((i=new Xi(new Float32Array(2),new Float32Array(2),1,this._controlInterpolantsResultBuffer)).__cacheIndex=e,t[e]=i),i},_takeBackControlInterpolant:function(t){var e=this._controlInterpolants,i=t.__cacheIndex,r=--this._nActiveControlInterpolants,n=e[r];t.__cacheIndex=r,e[r]=t,n.__cacheIndex=i,e[i]=n},_controlInterpolantsResultBuffer:new Float32Array(1),clipAction:function(t,e){var i=e||this._root,r=i.uuid,n="string"==typeof t?nr.findByName(i,t):t,o=null!==n?n.uuid:t,a=this._actionsByClip[o],s=null;if(void 0!==a){var c=a.actionByRoot[r];if(void 0!==c)return c;s=a.knownActions[0],null===n&&(n=s._clip)}if(null===n)return null;var u=new Vr(this,n,e);return this._bindAction(u,s),this._addInactiveAction(u,o,r),u},existingAction:function(t,e){var i=e||this._root,r=i.uuid,n="string"==typeof t?nr.findByName(i,t):t,o=n?n.uuid:t,a=this._actionsByClip[o];return void 0!==a?a.actionByRoot[r]||null:null},stopAllAction:function(){var t=this._actions,e=this._nActiveActions,i=this._bindings,r=this._nActiveBindings;this._nActiveActions=0,this._nActiveBindings=0;for(n=0;n!==e;++n)t[n].reset();for(var n=0;n!==r;++n)i[n].useCount=0;return this},update:function(t){t*=this.timeScale;for(var e=this._actions,i=this._nActiveActions,r=this.time+=t,n=Math.sign(t),o=this._accuIndex^=1,a=0;a!==i;++a)e[a]._update(r,t,n,o);for(var s=this._bindings,c=this._nActiveBindings,a=0;a!==c;++a)s[a].apply(o);return this},getRoot:function(){return this._root},uncacheClip:function(t){var e=this,i=this._actions,r=t.uuid,n=this._actionsByClip,o=n[r];if(void 0!==o){for(var a=o.knownActions,s=0,c=a.length;s!==c;++s){var u=a[s];e._deactivateAction(u);var h=u._cacheIndex,l=i[i.length-1];u._cacheIndex=null,u._byClipCacheIndex=null,l._cacheIndex=h,i[h]=l,i.pop(),e._removeInactiveBindingsForAction(u)}delete n[r]}},uncacheRoot:function(t){var e=this,i=t.uuid,r=this._actionsByClip;for(var n in r){var o=r[n].actionByRoot[i];void 0!==o&&(e._deactivateAction(o),e._removeInactiveAction(o))}var a=this._bindingsByRootAndName[i];if(void 0!==a)for(var s in a){var c=a[s];c.restoreOriginalState(),e._removeInactiveBinding(c)}},uncacheAction:function(t,e){var i=this.existingAction(t,e);null!==i&&(this._deactivateAction(i),this._removeInactiveAction(i))}}),Hr.prototype.clone=function(){return new Hr(void 0===this.value.clone?this.value:this.value.clone())},Wr.prototype=Object.assign(Object.create(Ct.prototype),{constructor:Wr,isInstancedBufferGeometry:!0,addGroup:function(t,e,i){this.groups.push({start:t,count:e,materialIndex:i})},copy:function(t){var e=this,i=t.index;null!==i&&this.setIndex(i.clone());var r=t.attributes;for(var n in r){var o=r[n];e.addAttribute(n,o.clone())}for(var a=t.groups,s=0,c=a.length;s<c;s++){var u=a[s];e.addGroup(u.start,u.count,u.materialIndex)}return this}}),Object.defineProperties(Xr.prototype,{count:{get:function(){return this.data.count}},array:{get:function(){return this.data.array}}}),Object.assign(Xr.prototype,{isInterleavedBufferAttribute:!0,setX:function(t,e){return this.data.array[t*this.data.stride+this.offset]=e,this},setY:function(t,e){return this.data.array[t*this.data.stride+this.offset+1]=e,this},setZ:function(t,e){return this.data.array[t*this.data.stride+this.offset+2]=e,this},setW:function(t,e){return this.data.array[t*this.data.stride+this.offset+3]=e,this},getX:function(t){return this.data.array[t*this.data.stride+this.offset]},getY:function(t){return this.data.array[t*this.data.stride+this.offset+1]},getZ:function(t){return this.data.array[t*this.data.stride+this.offset+2]},getW:function(t){return this.data.array[t*this.data.stride+this.offset+3]},setXY:function(t,e,i){return t=t*this.data.stride+this.offset,this.data.array[t+0]=e,this.data.array[t+1]=i,this},setXYZ:function(t,e,i,r){return t=t*this.data.stride+this.offset,this.data.array[t+0]=e,this.data.array[t+1]=i,this.data.array[t+2]=r,this},setXYZW:function(t,e,i,r,n){return t=t*this.data.stride+this.offset,this.data.array[t+0]=e,this.data.array[t+1]=i,this.data.array[t+2]=r,this.data.array[t+3]=n,this}}),Object.defineProperty(qr.prototype,"needsUpdate",{set:function(t){!0===t&&this.version++}}),Object.assign(qr.prototype,{isInterleavedBuffer:!0,setArray:function(t){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.count=void 0!==t?t.length/this.stride:0,this.array=t},setDynamic:function(t){return this.dynamic=t,this},copy:function(t){return this.array=new t.array.constructor(t.array),this.count=t.count,this.stride=t.stride,this.dynamic=t.dynamic,this},copyAt:function(t,e,i){var r=this;t*=this.stride,i*=e.stride;for(var n=0,o=this.stride;n<o;n++)r.array[t+n]=e.array[i+n];return this},set:function(t,e){return void 0===e&&(e=0),this.array.set(t,e),this},clone:function(){return(new this.constructor).copy(this)},onUpload:function(t){return this.onUploadCallback=t,this}}),Yr.prototype=Object.assign(Object.create(qr.prototype),{constructor:Yr,isInstancedInterleavedBuffer:!0,copy:function(t){return qr.prototype.copy.call(this,t),this.meshPerAttribute=t.meshPerAttribute,this}}),Zr.prototype=Object.assign(Object.create(_t.prototype),{constructor:Zr,isInstancedBufferAttribute:!0,copy:function(t){return _t.prototype.copy.call(this,t),this.meshPerAttribute=t.meshPerAttribute,this}}),Object.assign(Kr.prototype,{linePrecision:1,set:function(t,e){this.ray.set(t,e)},setFromCamera:function(t,e){e&&e.isPerspectiveCamera?(this.ray.origin.setFromMatrixPosition(e.matrixWorld),this.ray.direction.set(t.x,t.y,.5).unproject(e).sub(this.ray.origin).normalize()):e&&e.isOrthographicCamera?(this.ray.origin.set(t.x,t.y,(e.near+e.far)/(e.near-e.far)).unproject(e),this.ray.direction.set(0,0,-1).transformDirection(e.matrixWorld)):console.error("THREE.Raycaster: Unsupported camera type.")},intersectObject:function(t,e){var i=[];return Jr(t,this,i,e),i.sort(Qr),i},intersectObjects:function(t,e){var i=this,r=[];if(!1===Array.isArray(t))return console.warn("THREE.Raycaster.intersectObjects: objects is not an Array."),r;for(var n=0,o=t.length;n<o;n++)Jr(t[n],i,r,e);return r.sort(Qr),r}}),Object.assign(tn.prototype,{start:function(){this.startTime=("undefined"==typeof performance?Date:performance).now(),this.oldTime=this.startTime,this.elapsedTime=0,this.running=!0},stop:function(){this.getElapsedTime(),this.running=!1},getElapsedTime:function(){return this.getDelta(),this.elapsedTime},getDelta:function(){var t=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var e=("undefined"==typeof performance?Date:performance).now();t=(e-this.oldTime)/1e3,this.oldTime=e,this.elapsedTime+=t}return t}}),Object.assign(en.prototype,{set:function(t,e,i){return this.radius=t,this.phi=e,this.theta=i,this},clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.radius=t.radius,this.phi=t.phi,this.theta=t.theta,this},makeSafe:function(){return this.phi=Math.max(1e-6,Math.min(Math.PI-1e-6,this.phi)),this},setFromVector3:function(t){return this.radius=t.length(),0===this.radius?(this.theta=0,this.phi=0):(this.theta=Math.atan2(t.x,t.z),this.phi=Math.acos(xl.clamp(t.y/this.radius,-1,1))),this}}),Object.assign(rn.prototype,{set:function(t,e,i){return this.radius=t,this.theta=e,this.y=i,this},clone:function(){return(new this.constructor).copy(this)},copy:function(t){return this.radius=t.radius,this.theta=t.theta,this.y=t.y,this},setFromVector3:function(t){return this.radius=Math.sqrt(t.x*t.x+t.z*t.z),this.theta=Math.atan2(t.x,t.z),this.y=t.y,this}}),nn.prototype=Object.create(Ee.prototype),nn.prototype.constructor=nn,nn.prototype.update=function(){var t=new g,e=new g,i=new ut;return function(){var r=this,n=["a","b","c"];this.object.updateMatrixWorld(!0),i.getNormalMatrix(this.object.matrixWorld);var o=this.object.matrixWorld,a=this.geometry.attributes.position,s=this.object.geometry;if(s&&s.isGeometry)for(var c=s.vertices,u=s.faces,h=0,l=0,p=u.length;l<p;l++)for(var d=u[l],f=0,m=d.vertexNormals.length;f<m;f++){var g=c[d[n[f]]],v=d.vertexNormals[f];t.copy(g).applyMatrix4(o),e.copy(v).applyMatrix3(i).normalize().multiplyScalar(r.size).add(t),a.setXYZ(h,t.x,t.y,t.z),h+=1,a.setXYZ(h,e.x,e.y,e.z),h+=1}else if(s&&s.isBufferGeometry)for(var y=s.attributes.position,b=s.attributes.normal,h=0,f=0,m=y.count;f<m;f++)t.set(y.getX(f),y.getY(f),y.getZ(f)).applyMatrix4(o),e.set(b.getX(f),b.getY(f),b.getZ(f)),e.applyMatrix3(i).normalize().multiplyScalar(r.size).add(t),a.setXYZ(h,t.x,t.y,t.z),h+=1,a.setXYZ(h,e.x,e.y,e.z),h+=1;a.needsUpdate=!0}}(),on.prototype=Object.create(Ee.prototype),on.prototype.constructor=on,on.prototype.getBoneList=function(t){var e=this,i=[];t&&t.isBone&&i.push(t);for(var r=0;r<t.children.length;r++)i.push.apply(i,e.getBoneList(t.children[r]));return i},on.prototype.update=function(){var t=new g,e=new v,i=new v;return function(){var r=this,n=this.geometry,o=n.getAttribute("position");i.getInverse(this.root.matrixWorld);for(var a=0,s=0;a<this.bones.length;a++){var c=r.bones[a];c.parent&&c.parent.isBone&&(e.multiplyMatrices(i,c.matrixWorld),t.setFromMatrixPosition(e),o.setXYZ(s,t.x,t.y,t.z),e.multiplyMatrices(i,c.parent.matrixWorld),t.setFromMatrixPosition(e),o.setXYZ(s+1,t.x,t.y,t.z),s+=2)}n.getAttribute("position").needsUpdate=!0}}(),an.prototype=Object.create(gt.prototype),an.prototype.constructor=an,an.prototype.dispose=function(){this.children[0].geometry.dispose(),this.children[0].material.dispose()},an.prototype.update=function(){var t=new g,e=new tt,i=new tt;return function(){var r=this.children[0],n=r.geometry.getAttribute("color");e.copy(this.light.color).multiplyScalar(this.light.intensity),i.copy(this.light.groundColor).multiplyScalar(this.light.intensity);for(var o=0,a=n.count;o<a;o++){var s=o<a/2?e:i;n.setXYZ(o,s.r,s.g,s.b)}r.lookAt(t.setFromMatrixPosition(this.light.matrixWorld).negate()),n.needsUpdate=!0}}(),sn.prototype=Object.create(Ee.prototype),sn.prototype.constructor=sn,sn.prototype.update=function(){var t=new g,e=new g,i=new ut;return function(){var r=this;this.object.updateMatrixWorld(!0),i.getNormalMatrix(this.object.matrixWorld);for(var n=this.object.matrixWorld,o=this.geometry.attributes.position,a=this.object.geometry,s=a.vertices,c=a.faces,u=0,h=0,l=c.length;h<l;h++){var p=c[h],d=p.normal;t.copy(s[p.a]).add(s[p.b]).add(s[p.c]).divideScalar(3).applyMatrix4(n),e.copy(d).applyMatrix3(i).normalize().multiplyScalar(r.size).add(t),o.setXYZ(u,t.x,t.y,t.z),u+=1,o.setXYZ(u,e.x,e.y,e.z),u+=1}o.needsUpdate=!0}}(),cn.prototype=Object.create(Ee.prototype),cn.prototype.constructor=cn,cn.prototype.update=function(){function t(t,o,a,s){r.set(o,a,s).unproject(n);var c=i[t];if(void 0!==c)for(var u=e.getAttribute("position"),h=0,l=c.length;h<l;h++)u.setXYZ(c[h],r.x,r.y,r.z)}var e,i,r=new g,n=new Nt;return function(){e=this.geometry,i=this.pointMap;n.projectionMatrix.copy(this.camera.projectionMatrix),t("c",0,0,-1),t("t",0,0,1),t("n1",-1,-1,-1),t("n2",1,-1,-1),t("n3",-1,1,-1),t("n4",1,1,-1),t("f1",-1,-1,1),t("f2",1,-1,1),t("f3",-1,1,1),t("f4",1,1,1),t("u1",.7,1.1,-1),t("u2",-.7,1.1,-1),t("u3",0,2,-1),t("cf1",-1,0,1),t("cf2",1,0,1),t("cf3",0,-1,1),t("cf4",0,1,1),t("cn1",-1,0,-1),t("cn2",1,0,-1),t("cn3",0,-1,-1),t("cn4",0,1,-1),e.getAttribute("position").needsUpdate=!0}}();var Ql=new g,Jl=new un,tp=new un,ep=new un;hn.prototype=Object.create(xr.prototype),hn.prototype.constructor=hn,hn.prototype.getPoint=function(t){var e=this.points,i=e.length;i<2&&console.log("duh, you need at least 2 points");var r=(i-(this.closed?0:1))*t,n=Math.floor(r),o=r-n;this.closed?n+=n>0?0:(Math.floor(Math.abs(n)/e.length)+1)*e.length:0===o&&n===i-1&&(n=i-2,o=1);var a,s,c,u;if(this.closed||n>0?a=e[(n-1)%i]:(Ql.subVectors(e[0],e[1]).add(e[0]),a=Ql),s=e[n%i],c=e[(n+1)%i],this.closed||n+2<i?u=e[(n+2)%i]:(Ql.subVectors(e[i-1],e[i-2]).add(e[i-1]),u=Ql),void 0===this.type||"centripetal"===this.type||"chordal"===this.type){var h="chordal"===this.type?.5:.25,l=Math.pow(a.distanceToSquared(s),h),p=Math.pow(s.distanceToSquared(c),h),d=Math.pow(c.distanceToSquared(u),h);p<1e-4&&(p=1),l<1e-4&&(l=p),d<1e-4&&(d=p),Jl.initNonuniformCatmullRom(a.x,s.x,c.x,u.x,l,p,d),tp.initNonuniformCatmullRom(a.y,s.y,c.y,u.y,l,p,d),ep.initNonuniformCatmullRom(a.z,s.z,c.z,u.z,l,p,d)}else if("catmullrom"===this.type){var f=void 0!==this.tension?this.tension:.5;Jl.initCatmullRom(a.x,s.x,c.x,u.x,f),tp.initCatmullRom(a.y,s.y,c.y,u.y,f),ep.initCatmullRom(a.z,s.z,c.z,u.z,f)}return new g(Jl.calc(o),tp.calc(o),ep.calc(o))},xr.create=function(t,e){return console.log("THREE.Curve.create() has been deprecated"),t.prototype=Object.create(xr.prototype),t.prototype.constructor=t,t.prototype.getPoint=e,t},ln.prototype=Object.create(hn.prototype),Object.assign(ln.prototype,{initFromArray:function(t){console.error("THREE.Spline: .initFromArray() has been removed.")},getControlPointsArray:function(t){console.error("THREE.Spline: .getControlPointsArray() has been removed.")},reparametrizeByArcLength:function(t){console.error("THREE.Spline: .reparametrizeByArcLength() has been removed.")}}),Object.assign(et.prototype,{center:function(t){return console.warn("THREE.Box2: .center() has been renamed to .getCenter()."),this.getCenter(t)},empty:function(){return console.warn("THREE.Box2: .empty() has been renamed to .isEmpty()."),this.isEmpty()},isIntersectionBox:function(t){return console.warn("THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox()."),this.intersectsBox(t)},size:function(t){return console.warn("THREE.Box2: .size() has been renamed to .getSize()."),this.getSize(t)}}),Object.assign(st.prototype,{center:function(t){return console.warn("THREE.Box3: .center() has been renamed to .getCenter()."),this.getCenter(t)},empty:function(){return console.warn("THREE.Box3: .empty() has been renamed to .isEmpty()."),this.isEmpty()},isIntersectionBox:function(t){return console.warn("THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox()."),this.intersectsBox(t)},isIntersectionSphere:function(t){return console.warn("THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere()."),this.intersectsSphere(t)},size:function(t){return console.warn("THREE.Box3: .size() has been renamed to .getSize()."),this.getSize(t)}}),vt.prototype.center=function(t){return console.warn("THREE.Line3: .center() has been renamed to .getCenter()."),this.getCenter(t)},xl.random16=function(){return console.warn("THREE.Math.random16() has been deprecated. Use Math.random() instead."),Math.random()},Object.assign(ut.prototype,{flattenToArrayOffset:function(t,e){return console.warn("THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead."),this.toArray(t,e)},multiplyVector3:function(t){return console.warn("THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead."),t.applyMatrix3(this)},multiplyVector3Array:function(t){return console.warn("THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead."),this.applyToVector3Array(t)},applyToBuffer:function(t,e,i){return console.warn("THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead."),this.applyToBufferAttribute(t)},applyToVector3Array:function(t,e,i){console.error("THREE.Matrix3: .applyToVector3Array() has been removed.")}}),Object.assign(v.prototype,{extractPosition:function(t){return console.warn("THREE.Matrix4: .extractPosition() has been renamed to .copyPosition()."),this.copyPosition(t)},flattenToArrayOffset:function(t,e){return console.warn("THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead."),this.toArray(t,e)},getPosition:function(){var t;return function(){return void 0===t&&(t=new g),console.warn("THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead."),t.setFromMatrixColumn(this,3)}}(),setRotationFromQuaternion:function(t){return console.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion()."),this.makeRotationFromQuaternion(t)},multiplyToArray:function(){console.warn("THREE.Matrix4: .multiplyToArray() has been removed.")},multiplyVector3:function(t){return console.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead."),t.applyMatrix4(this)},multiplyVector4:function(t){return console.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead."),t.applyMatrix4(this)},multiplyVector3Array:function(t){return console.warn("THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead."),this.applyToVector3Array(t)},rotateAxis:function(t){console.warn("THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead."),t.transformDirection(this)},crossVector:function(t){return console.warn("THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead."),t.applyMatrix4(this)},translate:function(){console.error("THREE.Matrix4: .translate() has been removed.")},rotateX:function(){console.error("THREE.Matrix4: .rotateX() has been removed.")},rotateY:function(){console.error("THREE.Matrix4: .rotateY() has been removed.")},rotateZ:function(){console.error("THREE.Matrix4: .rotateZ() has been removed.")},rotateByAxis:function(){console.error("THREE.Matrix4: .rotateByAxis() has been removed.")},applyToBuffer:function(t,e,i){return console.warn("THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead."),this.applyToBufferAttribute(t)},applyToVector3Array:function(t,e,i){console.error("THREE.Matrix4: .applyToVector3Array() has been removed.")},makeFrustum:function(t,e,i,r,n,o){return console.warn("THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead."),this.makePerspective(t,e,r,i,n,o)}}),ht.prototype.isIntersectionLine=function(t){return console.warn("THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine()."),this.intersectsLine(t)},m.prototype.multiplyVector3=function(t){return console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."),t.applyQuaternion(this)},Object.assign(dt.prototype,{isIntersectionBox:function(t){return console.warn("THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox()."),this.intersectsBox(t)},isIntersectionPlane:function(t){return console.warn("THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane()."),this.intersectsPlane(t)},isIntersectionSphere:function(t){return console.warn("THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere()."),this.intersectsSphere(t)}}),Object.assign(Er.prototype,{extrude:function(t){return console.warn("THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead."),new ti(this,t)},makeGeometry:function(t){return console.warn("THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead."),new hi(this,t)}}),Object.assign(l.prototype,{fromAttribute:function(t,e,i){return console.error("THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute()."),this.fromBufferAttribute(t,e,i)}}),Object.assign(g.prototype,{setEulerFromRotationMatrix:function(){console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},setEulerFromQuaternion:function(){console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")},getPositionFromMatrix:function(t){return console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition()."),this.setFromMatrixPosition(t)},getScaleFromMatrix:function(t){return console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale()."),this.setFromMatrixScale(t)},getColumnFromMatrix:function(t,e){return console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn()."),this.setFromMatrixColumn(e,t)},applyProjection:function(t){return console.warn("THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead."),this.applyMatrix4(t)},fromAttribute:function(t,e,i){return console.error("THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute()."),this.fromBufferAttribute(t,e,i)}}),Object.assign(d.prototype,{fromAttribute:function(t,e,i){return console.error("THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute()."),this.fromBufferAttribute(t,e,i)}}),Et.prototype.computeTangents=function(){console.warn("THREE.Geometry: .computeTangents() has been removed.")},Object.assign(gt.prototype,{getChildByName:function(t){return console.warn("THREE.Object3D: .getChildByName() has been renamed to .getObjectByName()."),this.getObjectByName(t)},renderDepth:function(){console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.")},translate:function(t,e){return console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead."),this.translateOnAxis(e,t)}}),Object.defineProperties(gt.prototype,{eulerOrder:{get:function(){return console.warn("THREE.Object3D: .eulerOrder is now .rotation.order."),this.rotation.order},set:function(t){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order."),this.rotation.order=t}},useQuaternion:{get:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")}}}),Object.defineProperties(we.prototype,{objects:{get:function(){return console.warn("THREE.LOD: .objects has been renamed to .levels."),this.levels}}}),Object.defineProperty(Se.prototype,"useVertexTexture",{get:function(){console.warn("THREE.Skeleton: useVertexTexture has been removed.")},set:function(){console.warn("THREE.Skeleton: useVertexTexture has been removed.")}}),Object.defineProperty(xr.prototype,"__arcLengthDivisions",{get:function(){return console.warn("THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions."),this.arcLengthDivisions},set:function(t){console.warn("THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions."),this.arcLengthDivisions=t}}),kt.prototype.setLens=function(t,e){console.warn("THREE.PerspectiveCamera.setLens is deprecated. Use .setFocalLength and .filmGauge for a photographic setup."),void 0!==e&&(this.filmGauge=e),this.setFocalLength(t)},Object.defineProperties(Ni.prototype,{onlyShadow:{set:function(){console.warn("THREE.Light: .onlyShadow has been removed.")}},shadowCameraFov:{set:function(t){console.warn("THREE.Light: .shadowCameraFov is now .shadow.camera.fov."),this.shadow.camera.fov=t}},shadowCameraLeft:{set:function(t){console.warn("THREE.Light: .shadowCameraLeft is now .shadow.camera.left."),this.shadow.camera.left=t}},shadowCameraRight:{set:function(t){console.warn("THREE.Light: .shadowCameraRight is now .shadow.camera.right."),this.shadow.camera.right=t}},shadowCameraTop:{set:function(t){console.warn("THREE.Light: .shadowCameraTop is now .shadow.camera.top."),this.shadow.camera.top=t}},shadowCameraBottom:{set:function(t){console.warn("THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom."),this.shadow.camera.bottom=t}},shadowCameraNear:{set:function(t){console.warn("THREE.Light: .shadowCameraNear is now .shadow.camera.near."),this.shadow.camera.near=t}},shadowCameraFar:{set:function(t){console.warn("THREE.Light: .shadowCameraFar is now .shadow.camera.far."),this.shadow.camera.far=t}},shadowCameraVisible:{set:function(){console.warn("THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.")}},shadowBias:{set:function(t){console.warn("THREE.Light: .shadowBias is now .shadow.bias."),this.shadow.bias=t}},shadowDarkness:{set:function(){console.warn("THREE.Light: .shadowDarkness has been removed.")}},shadowMapWidth:{set:function(t){console.warn("THREE.Light: .shadowMapWidth is now .shadow.mapSize.width."),this.shadow.mapSize.width=t}},shadowMapHeight:{set:function(t){console.warn("THREE.Light: .shadowMapHeight is now .shadow.mapSize.height."),this.shadow.mapSize.height=t}}}),Object.defineProperties(_t.prototype,{length:{get:function(){return console.warn("THREE.BufferAttribute: .length has been deprecated. Use .count instead."),this.array.length}}}),Object.assign(Ct.prototype,{addIndex:function(t){console.warn("THREE.BufferGeometry: .addIndex() has been renamed to .setIndex()."),this.setIndex(t)},addDrawCall:function(t,e,i){void 0!==i&&console.warn("THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset."),console.warn("THREE.BufferGeometry: .addDrawCall() is now .addGroup()."),this.addGroup(t,e)},clearDrawCalls:function(){console.warn("THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups()."),this.clearGroups()},computeTangents:function(){console.warn("THREE.BufferGeometry: .computeTangents() has been removed.")},computeOffsets:function(){console.warn("THREE.BufferGeometry: .computeOffsets() has been removed.")}}),Object.defineProperties(Ct.prototype,{drawcalls:{get:function(){return console.error("THREE.BufferGeometry: .drawcalls has been renamed to .groups."),this.groups}},offsets:{get:function(){return console.warn("THREE.BufferGeometry: .offsets has been renamed to .groups."),this.groups}}}),Object.defineProperties(Hr.prototype,{dynamic:{set:function(){console.warn("THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.")}},onUpdate:{value:function(){return console.warn("THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead."),this}}}),Object.defineProperties(nt.prototype,{wrapAround:{get:function(){console.warn("THREE.Material: .wrapAround has been removed.")},set:function(){console.warn("THREE.Material: .wrapAround has been removed.")}},wrapRGB:{get:function(){return console.warn("THREE.Material: .wrapRGB has been removed."),new tt}}}),Object.defineProperties(Si.prototype,{metal:{get:function(){return console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead."),!1},set:function(){console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead")}}}),Object.defineProperties(ot.prototype,{derivatives:{get:function(){return console.warn("THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives."),this.extensions.derivatives},set:function(t){console.warn("THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives."),this.extensions.derivatives=t}}}),Object.assign(me.prototype,{getCurrentRenderTarget:function(){return console.warn("THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget()."),this.getRenderTarget()},supportsFloatTextures:function(){return console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' )."),this.extensions.get("OES_texture_float")},supportsHalfFloatTextures:function(){return console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' )."),this.extensions.get("OES_texture_half_float")},supportsStandardDerivatives:function(){return console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' )."),this.extensions.get("OES_standard_derivatives")},supportsCompressedTextureS3TC:function(){return console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' )."),this.extensions.get("WEBGL_compressed_texture_s3tc")},supportsCompressedTexturePVRTC:function(){return console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' )."),this.extensions.get("WEBGL_compressed_texture_pvrtc")},supportsBlendMinMax:function(){return console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' )."),this.extensions.get("EXT_blend_minmax")},supportsVertexTextures:function(){return console.warn("THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures."),this.capabilities.vertexTextures},supportsInstancedArrays:function(){return console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' )."),this.extensions.get("ANGLE_instanced_arrays")},enableScissorTest:function(t){console.warn("THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest()."),this.setScissorTest(t)},initMaterial:function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")},addPrePlugin:function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")},addPostPlugin:function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")},updateShadowMap:function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}}),Object.defineProperties(me.prototype,{shadowMapEnabled:{get:function(){return this.shadowMap.enabled},set:function(t){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled."),this.shadowMap.enabled=t}},shadowMapType:{get:function(){return this.shadowMap.type},set:function(t){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type."),this.shadowMap.type=t}},shadowMapCullFace:{get:function(){return this.shadowMap.cullFace},set:function(t){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace."),this.shadowMap.cullFace=t}}}),Object.defineProperties(pt.prototype,{cullFace:{get:function(){return this.renderReverseSided?xu:bu},set:function(t){var e=t!==bu;console.warn("WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to "+e+"."),this.renderReverseSided=e}}}),Object.defineProperties(f.prototype,{wrapS:{get:function(){return console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS."),this.texture.wrapS},set:function(t){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS."),this.texture.wrapS=t}},wrapT:{get:function(){return console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT."),this.texture.wrapT},set:function(t){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT."),this.texture.wrapT=t}},magFilter:{get:function(){return console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter."),this.texture.magFilter},set:function(t){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter."),this.texture.magFilter=t}},minFilter:{get:function(){return console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter."),this.texture.minFilter},set:function(t){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter."),this.texture.minFilter=t}},anisotropy:{get:function(){return console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy."),this.texture.anisotropy},set:function(t){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy."),this.texture.anisotropy=t}},offset:{get:function(){return console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset."),this.texture.offset},set:function(t){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset."),this.texture.offset=t}},repeat:{get:function(){return console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat."),this.texture.repeat},set:function(t){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat."),this.texture.repeat=t}},format:{get:function(){return console.warn("THREE.WebGLRenderTarget: .format is now .texture.format."),this.texture.format},set:function(t){console.warn("THREE.WebGLRenderTarget: .format is now .texture.format."),this.texture.format=t}},type:{get:function(){return console.warn("THREE.WebGLRenderTarget: .type is now .texture.type."),this.texture.type},set:function(t){console.warn("THREE.WebGLRenderTarget: .type is now .texture.type."),this.texture.type=t}},generateMipmaps:{get:function(){return console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps."),this.texture.generateMipmaps},set:function(t){console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps."),this.texture.generateMipmaps=t}}}),kr.prototype.load=function(t){console.warn("THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.");var e=this;return(new Rr).load(t,function(t){e.setBuffer(t)}),this},Fr.prototype.getData=function(){return console.warn("THREE.AudioAnalyser: .getData() is now .getFrequencyData()."),this.getFrequencyData()};var ip=function(t){this.name=t,this._dict={}},rp={names:{}};ip.prototype.add=function(t,e){this._dict[Bn(t)]=e},ip.prototype.get=function(t){return this._dict[Bn(t)]},rp.names.get=function(){return Object.keys(this._dict)},Object.defineProperties(ip.prototype,rp);var np=function(){this.activeWorkerCount=0,this._funcDict={},this._depsDict={},this._blobDict={}};np.prototype.add=function(t,e,i){this._funcDict[t]=e,this._depsDict[t]=i},np.prototype.get=function(t){return this._blobDict[t]||(this._blobDict[t]=jn(this._funcDict[t],this._depsDict[t])),this._blobDict[t]};var op,ap,sp,cp,up,hp,lp,pp,dp,fp,mp,gp,vp,yp,bp,xp,_p,wp,Sp,Ap,Mp,Pp,Tp,Ep,Cp,Ip,Lp,Rp,Op,Dp,Np,kp,Bp,Fp,zp,Up,jp,Gp,Vp,$p,Hp,Wp,Xp,qp,Yp,Zp,Kp,Qp,Jp,td,ed,id,rd,nd,od,ad,sd,cd,ud,hd,ld,pd,dd,fd,md,gd,vd,yd,bd,xd,_d,wd,Sd,Ad,Md,Pd,Td,Ed,Cd,Id="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),Ld=new Array(36),Rd=[].slice;Md=function(){var t,e,i,r,n;for(t={},r=0,e=(n="Boolean Number String Function Array Date RegExp Undefined Null".split(" ")).length;r<e;r++)i=n[r],t["[object "+i+"]"]=i.toLowerCase();return function(e){var i;return i=Object.prototype.toString.call(e),t[i]||"object"}}(),Yp=function(t,e,i){return null==e&&(e=0),null==i&&(i=1),t<e&&(t=e),t>i&&(t=i),t},Pd=function(t){return t.length>=3?[].slice.call(t):t[0]},Ap=function(t){var e,i;for(t._clipped=!1,t._unclipped=t.slice(0),e=i=0;i<3;e=++i)e<3?((t[e]<0||t[e]>255)&&(t._clipped=!0),t[e]<0&&(t[e]=0),t[e]>255&&(t[e]=255)):3===e&&(t[e]<0&&(t[e]=0),t[e]>1&&(t[e]=1));return t._clipped||delete t._unclipped,t},cp=Math.PI,xd=Math.round,Pp=Math.cos,Lp=Math.floor,nd=Math.pow,Zp=Math.log,wd=Math.sin,Sd=Math.sqrt,vp=Math.atan2,Jp=Math.max,gp=Math.abs,lp=2*cp,up=cp/3,ap=cp/180,hp=180/cp,mp=[],(Sp=function(){return arguments[0]instanceof op?arguments[0]:function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,arguments,function(){})}).version="1.3.3",fp={},pp=[],dp=!1,op=function(){function t(){var t,e,i,r,n,o,a,s,c,u=arguments;for(o=this,e=[],s=0,r=arguments.length;s<r;s++)null!=(t=u[s])&&e.push(t);if(a=e[e.length-1],null!=fp[a])o._rgb=Ap(fp[a](Pd(e.slice(0,-1))));else{for(dp||(pp=pp.sort(function(t,e){return e.p-t.p}),dp=!0),c=0,n=pp.length;c<n&&(i=pp[c],!(a=i.test.apply(i,e)));c++);a&&(o._rgb=Ap(fp[a].apply(fp,e)))}null==o._rgb&&console.warn("unknown format: "+e),null==o._rgb&&(o._rgb=[0,0,0]),3===o._rgb.length&&o._rgb.push(1)}return t.prototype.toString=function(){return this.hex()},t}(),Sp._input=fp,Sp.brewer=_p={OrRd:["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"],PuBu:["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"],BuPu:["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"],Oranges:["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"],BuGn:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"],YlOrBr:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"],YlGn:["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"],Reds:["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"],RdPu:["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"],Greens:["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"],YlGnBu:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"],Purples:["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"],GnBu:["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],Greys:["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"],YlOrRd:["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"],PuRd:["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"],Blues:["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"],PuBuGn:["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"],Viridis:["#440154","#482777","#3f4a8a","#31678e","#26838f","#1f9d8a","#6cce5a","#b6de2b","#fee825"],Spectral:["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],RdYlGn:["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],RdBu:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],PiYG:["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],PRGn:["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],RdYlBu:["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],BrBG:["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],RdGy:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],PuOr:["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],Set2:["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"],Accent:["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"],Set1:["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"],Set3:["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"],Dark2:["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"],Paired:["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"],Pastel2:["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"],Pastel1:["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]},function(){var t,e;e=[];for(t in _p)e.push(_p[t.toLowerCase()]=_p[t])}(),Td={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflower:"#6495ed",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",laserlemon:"#ffff54",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrod:"#fafad2",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",maroon2:"#7f0000",maroon3:"#b03060",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",purple2:"#7f007f",purple3:"#a020f0",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},Sp.colors=Td,$p=function(){var t,e,i,r,n,o,a,s,c;return e=Pd(arguments),n=e[0],t=e[1],i=e[2],s=(n+16)/116,a=isNaN(t)?s:s+t/500,c=isNaN(i)?s:s-i/200,s=sp.Yn*Hp(s),a=sp.Xn*Hp(a),c=sp.Zn*Hp(c),o=Cd(3.2404542*a-1.5371385*s-.4985314*c),r=Cd(-.969266*a+1.8760108*s+.041556*c),i=Cd(.0556434*a-.2040259*s+1.0572252*c),[o,r,i,e.length>3?e[3]:1]},Cd=function(t){return 255*(t<=.00304?12.92*t:1.055*nd(t,1/2.4)-.055)},Hp=function(t){return t>sp.t1?t*t*t:sp.t2*(t-sp.t0)},sp={Kn:18,Xn:.95047,Yn:1,Zn:1.08883,t0:.137931034,t1:.206896552,t2:.12841855,t3:.008856452},pd=function(){var t,e,i,r,n,o,a,s;return r=Pd(arguments),i=r[0],e=r[1],t=r[2],n=vd(i,e,t),o=n[0],a=n[1],s=n[2],[116*a-16,500*(o-a),200*(a-s)]},yd=function(t){return(t/=255)<=.04045?t/12.92:nd((t+.055)/1.055,2.4)},Ed=function(t){return t>sp.t3?nd(t,1/3):t/sp.t2+sp.t0},vd=function(){var t,e,i,r,n,o,a;return r=Pd(arguments),i=r[0],e=r[1],t=r[2],i=yd(i),e=yd(e),t=yd(t),n=Ed((.4124564*i+.3575761*e+.1804375*t)/sp.Xn),o=Ed((.2126729*i+.7151522*e+.072175*t)/sp.Yn),a=Ed((.0193339*i+.119192*e+.9503041*t)/sp.Zn),[n,o,a]},Sp.lab=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["lab"]),function(){})},fp.lab=$p,op.prototype.lab=function(){return pd(this._rgb)},yp=function(t){var e,i,r,n,o,a,s,c,u,h,l;return t=function(){var e,i,r;for(r=[],i=0,e=t.length;i<e;i++)n=t[i],r.push(Sp(n));return r}(),2===t.length?(u=function(){var e,i,r;for(r=[],i=0,e=t.length;i<e;i++)n=t[i],r.push(n.lab());return r}(),o=u[0],a=u[1],e=function(t){var e,i;return i=function(){var i,r;for(r=[],e=i=0;i<=2;e=++i)r.push(o[e]+t*(a[e]-o[e]));return r}(),Sp.lab.apply(Sp,i)}):3===t.length?(h=function(){var e,i,r;for(r=[],i=0,e=t.length;i<e;i++)n=t[i],r.push(n.lab());return r}(),o=h[0],a=h[1],s=h[2],e=function(t){var e,i;return i=function(){var i,r;for(r=[],e=i=0;i<=2;e=++i)r.push((1-t)*(1-t)*o[e]+2*(1-t)*t*a[e]+t*t*s[e]);return r}(),Sp.lab.apply(Sp,i)}):4===t.length?(l=function(){var e,i,r;for(r=[],i=0,e=t.length;i<e;i++)n=t[i],r.push(n.lab());return r}(),o=l[0],a=l[1],s=l[2],c=l[3],e=function(t){var e,i;return i=function(){var i,r;for(r=[],e=i=0;i<=2;e=++i)r.push((1-t)*(1-t)*(1-t)*o[e]+3*(1-t)*(1-t)*t*a[e]+3*(1-t)*t*t*s[e]+t*t*t*c[e]);return r}(),Sp.lab.apply(Sp,i)}):5===t.length&&(i=yp(t.slice(0,3)),r=yp(t.slice(2,5)),e=function(t){return t<.5?i(2*t):r(2*(t-.5))}),e},Sp.bezier=function(t){var e;return e=yp(t),e.scale=function(){return Sp.scale(e)},e},Sp.cubehelix=function(t,e,i,r,n){var o,a,s;return null==t&&(t=300),null==e&&(e=-1.5),null==i&&(i=1),null==r&&(r=1),null==n&&(n=[0,1]),o=0,"array"===Md(n)?a=n[1]-n[0]:(a=0,n=[n,n]),s=function(s){var c,u,h,l,p,d,f,m,g;return c=lp*((t+120)/360+e*s),f=nd(n[0]+a*s,r),d=0!==o?i[0]+s*o:i,u=d*f*(1-f)/2,l=Pp(c),g=wd(c),m=f+u*(-.14861*l+1.78277*g),p=f+u*(-.29227*l-.90649*g),h=f+u*(1.97294*l),Sp(Ap([255*m,255*p,255*h]))},s.start=function(e){return null==e?t:(t=e,s)},s.rotations=function(t){return null==t?e:(e=t,s)},s.gamma=function(t){return null==t?r:(r=t,s)},s.hue=function(t){return null==t?i:(i=t,"array"===Md(i)?0===(o=i[1]-i[0])&&(i=i[1]):o=0,s)},s.lightness=function(t){return null==t?n:("array"===Md(t)?(n=t,a=t[1]-t[0]):(n=[t,t],a=0),s)},s.scale=function(){return Sp.scale(s)},s.hue(i),s},Sp.random=function(){var t,e;for("0123456789abcdef",t="#",e=0;e<6;++e)t+="0123456789abcdef".charAt(Lp(16*Math.random()));return new op(t)},Sp.average=function(t,e){var i,r,n,o,a,s,c,u,h,l,p,d,f;null==e&&(e="rgb"),h=t.length,d=(c=(t=t.map(function(t){return Sp(t)})).splice(0,1)[0]).get(e),o=[],a=0,s=0;for(u in d)d[u]=d[u]||0,o.push(isNaN(d[u])?0:1),"h"!==e.charAt(u)||isNaN(d[u])||(i=d[u]/180*cp,a+=Pp(i),s+=wd(i));for(r=c.alpha(),p=0,l=t.length;p<l;p++){f=(n=t[p]).get(e),r+=n.alpha();for(u in d)isNaN(f[u])||(d[u]+=f[u],o[u]+=1,"h"===e.charAt(u)&&(i=d[u]/180*cp,a+=Pp(i),s+=wd(i)))}for(u in d)if(d[u]=d[u]/o[u],"h"===e.charAt(u)){for(i=vp(s/o[u],a/o[u])/cp*180;i<0;)i+=360;for(;i>=360;)i-=360;d[u]=i}return Sp(d,e).alpha(r/h)},fp.rgb=function(){var t,e,i,r;e=Pd(arguments),i=[];for(t in e)r=e[t],i.push(r);return i},Sp.rgb=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["rgb"]),function(){})},op.prototype.rgb=function(t){return null==t&&(t=!0),t?this._rgb.map(Math.round).slice(0,3):this._rgb.slice(0,3)},op.prototype.rgba=function(t){return null==t&&(t=!0),t?[Math.round(this._rgb[0]),Math.round(this._rgb[1]),Math.round(this._rgb[2]),this._rgb[3]]:this._rgb.slice(0)},pp.push({p:3,test:function(t){var e;return e=Pd(arguments),"array"===Md(e)&&3===e.length?"rgb":4===e.length&&"number"===Md(e[3])&&e[3]>=0&&e[3]<=1?"rgb":void 0}}),Op=function(t){var e,i,r,n,o,a;if(t.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/))return 4!==t.length&&7!==t.length||(t=t.substr(1)),3===t.length&&(t=(t=t.split(""))[0]+t[0]+t[1]+t[1]+t[2]+t[2]),a=parseInt(t,16),n=a>>16,r=a>>8&255,i=255&a,[n,r,i,1];if(t.match(/^#?([A-Fa-f0-9]{8})$/))return 9===t.length&&(t=t.substr(1)),a=parseInt(t,16),n=a>>24&255,r=a>>16&255,i=a>>8&255,e=xd((255&a)/255*100)/100,[n,r,i,e];if(null!=fp.css&&(o=fp.css(t)))return o;throw"unknown color: "+t},cd=function(t,e){var i,r,n,o,a,s,c;return null==e&&(e="rgb"),a=t[0],n=t[1],r=t[2],i=t[3],a=Math.round(a),n=Math.round(n),r=Math.round(r),c=a<<16|n<<8|r,s="000000"+c.toString(16),s=s.substr(s.length-6),o="0"+xd(255*i).toString(16),o=o.substr(o.length-2),"#"+function(){switch(e.toLowerCase()){case"rgba":return s+o;case"argb":return o+s;default:return s}}()},fp.hex=function(t){return Op(t)},Sp.hex=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["hex"]),function(){})},op.prototype.hex=function(t){return null==t&&(t="rgb"),cd(this._rgb,t)},pp.push({p:4,test:function(t){if(1===arguments.length&&"string"===Md(t))return"hex"}}),kp=function(){var t,e,i,r,n,o,a,s,c,u,h,l,p,d;if(t=Pd(arguments),n=t[0],h=t[1],a=t[2],0===h)c=r=e=255*a;else{for(d=[0,0,0],i=[0,0,0],l=2*a-(p=a<.5?a*(1+h):a+h-a*h),n/=360,d[0]=n+1/3,d[1]=n,d[2]=n-1/3,o=s=0;s<=2;o=++s)d[o]<0&&(d[o]+=1),d[o]>1&&(d[o]-=1),6*d[o]<1?i[o]=l+6*(p-l)*d[o]:2*d[o]<1?i[o]=p:3*d[o]<2?i[o]=l+(p-l)*(2/3-d[o])*6:i[o]=l;c=(u=[xd(255*i[0]),xd(255*i[1]),xd(255*i[2])])[0],r=u[1],e=u[2]}return t.length>3?[c,r,e,t[3]]:[c,r,e]},hd=function(t,e,i){var r,n,o,a,s;return void 0!==t&&t.length>=3&&(t=(a=t)[0],e=a[1],i=a[2]),t/=255,e/=255,i/=255,o=Math.min(t,e,i),Jp=Math.max(t,e,i),n=(Jp+o)/2,Jp===o?(s=0,r=Number.NaN):s=n<.5?(Jp-o)/(Jp+o):(Jp-o)/(2-Jp-o),t===Jp?r=(e-i)/(Jp-o):e===Jp?r=2+(i-t)/(Jp-o):i===Jp&&(r=4+(t-e)/(Jp-o)),(r*=60)<0&&(r+=360),[r,s,n]},Sp.hsl=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["hsl"]),function(){})},fp.hsl=kp,op.prototype.hsl=function(){return hd(this._rgb)},Bp=function(){var t,e,i,r,n,o,a,s,c,u,h,l,p,d,f,m,g,v;if(t=Pd(arguments),n=t[0],m=t[1],v=t[2],v*=255,0===m)c=r=e=v;else switch(360===n&&(n=0),n>360&&(n-=360),n<0&&(n+=360),n/=60,o=Lp(n),i=n-o,a=v*(1-m),s=v*(1-m*i),g=v*(1-m*(1-i)),o){case 0:c=(u=[v,g,a])[0],r=u[1],e=u[2];break;case 1:c=(h=[s,v,a])[0],r=h[1],e=h[2];break;case 2:c=(l=[a,v,g])[0],r=l[1],e=l[2];break;case 3:c=(p=[a,s,v])[0],r=p[1],e=p[2];break;case 4:c=(d=[g,a,v])[0],r=d[1],e=d[2];break;case 5:c=(f=[v,a,s])[0],r=f[1],e=f[2]}return[c,r,e,t.length>3?t[3]:1]},ld=function(){var t,e,i,r,n,o,a,s,c;return a=Pd(arguments),o=a[0],i=a[1],t=a[2],n=Math.min(o,i,t),Jp=Math.max(o,i,t),e=Jp-n,c=Jp/255,0===Jp?(r=Number.NaN,s=0):(s=e/Jp,o===Jp&&(r=(i-t)/e),i===Jp&&(r=2+(t-o)/e),t===Jp&&(r=4+(o-i)/e),(r*=60)<0&&(r+=360)),[r,s,c]},Sp.hsv=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["hsv"]),function(){})},fp.hsv=Bp,op.prototype.hsv=function(){return ld(this._rgb)},id=function(t){var e,i,r;return"number"===Md(t)&&t>=0&&t<=16777215?(r=t>>16,i=t>>8&255,e=255&t,[r,i,e,1]):(console.warn("unknown num color: "+t),[0,0,0,1])},md=function(){var t,e,i,r;return r=Pd(arguments),i=r[0],e=r[1],t=r[2],(i<<16)+(e<<8)+t},Sp.num=function(t){return new op(t,"num")},op.prototype.num=function(t){return null==t&&(t="rgb"),md(this._rgb,t)},fp.num=id,pp.push({p:1,test:function(t){if(1===arguments.length&&"number"===Md(t)&&t>=0&&t<=16777215)return"num"}}),Rp=function(){var t,e,i,r,n,o,a,s,c,u,h,l,p,d,f,m,g,v,y,b;if(i=Pd(arguments),s=i[0],n=i[1],e=i[2],n/=100,a=a/100*255,t=255*n,0===n)l=a=r=e;else switch(360===s&&(s=0),s>360&&(s-=360),s<0&&(s+=360),s/=60,c=Lp(s),o=s-c,u=e*(1-n),h=u+t*(1-o),y=u+t*o,b=u+t,c){case 0:l=(p=[b,y,u])[0],a=p[1],r=p[2];break;case 1:l=(d=[h,b,u])[0],a=d[1],r=d[2];break;case 2:l=(f=[u,b,y])[0],a=f[1],r=f[2];break;case 3:l=(m=[u,h,b])[0],a=m[1],r=m[2];break;case 4:l=(g=[y,u,b])[0],a=g[1],r=g[2];break;case 5:l=(v=[b,u,h])[0],a=v[1],r=v[2]}return[l,a,r,i.length>3?i[3]:1]},sd=function(){var t,e,i,r,n,o,a,s,c;return c=Pd(arguments),s=c[0],n=c[1],e=c[2],a=Math.min(s,n,e),Jp=Math.max(s,n,e),r=Jp-a,i=100*r/255,t=a/(255-r)*100,0===r?o=Number.NaN:(s===Jp&&(o=(n-e)/r),n===Jp&&(o=2+(e-s)/r),e===Jp&&(o=4+(s-n)/r),(o*=60)<0&&(o+=360)),[o,i,t]},Sp.hcg=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["hcg"]),function(){})},fp.hcg=Rp,op.prototype.hcg=function(){return sd(this._rgb)},Tp=function(t){var e,i,r,n,o,a,s,c;if(t=t.toLowerCase(),null!=Sp.colors&&Sp.colors[t])return Op(Sp.colors[t]);if(o=t.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)){for(s=o.slice(1,4),n=a=0;a<=2;n=++a)s[n]=+s[n];s[3]=1}else if(o=t.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/))for(s=o.slice(1,5),n=c=0;c<=3;n=++c)s[n]=+s[n];else if(o=t.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)){for(s=o.slice(1,4),n=e=0;e<=2;n=++e)s[n]=xd(2.55*s[n]);s[3]=1}else if(o=t.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)){for(s=o.slice(1,5),n=i=0;i<=2;n=++i)s[n]=xd(2.55*s[n]);s[3]=+s[3]}else(o=t.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/))?((r=o.slice(1,4))[1]*=.01,r[2]*=.01,(s=kp(r))[3]=1):(o=t.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/))&&((r=o.slice(1,4))[1]*=.01,r[2]*=.01,(s=kp(r))[3]=+o[4]);return s},ad=function(t){var e;return e=t[3]<1?"rgba":"rgb","rgb"===e?e+"("+t.slice(0,3).map(xd).join(",")+")":"rgba"===e?e+"("+t.slice(0,3).map(xd).join(",")+","+t[3]+")":void 0},bd=function(t){return xd(100*t)/100},Np=function(t,e){var i;return i=e<1?"hsla":"hsl",t[0]=bd(t[0]||0),t[1]=bd(100*t[1])+"%",t[2]=bd(100*t[2])+"%","hsla"===i&&(t[3]=e),i+"("+t.join(",")+")"},fp.css=function(t){return Tp(t)},Sp.css=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["css"]),function(){})},op.prototype.css=function(t){return null==t&&(t="rgb"),"rgb"===t.slice(0,3)?ad(this._rgb):"hsl"===t.slice(0,3)?Np(this.hsl(),this.alpha()):void 0},fp.named=function(t){return Op(Td[t])},pp.push({p:5,test:function(t){if(1===arguments.length&&null!=Td[t])return"named"}}),op.prototype.name=function(t){var e,i;arguments.length&&(Td[t]&&(this._rgb=Op(Td[t])),this._rgb[3]=1),e=this.hex();for(i in Td)if(e===Td[i])return i;return e},Wp=function(){var t,e,i,r;return r=Pd(arguments),i=r[0],t=r[1],e=r[2],e*=ap,[i,Pp(e)*t,wd(e)*t]},Xp=function(){var t,e,i,r,n,o,a,s,c,u,h;return i=Pd(arguments),s=i[0],n=i[1],a=i[2],u=Wp(s,n,a),t=u[0],e=u[1],r=u[2],h=$p(t,e,r),c=h[0],o=h[1],r=h[2],[c,o,r,i.length>3?i[3]:1]},Vp=function(){var t,e,i,r,n,o;return o=Pd(arguments),n=o[0],t=o[1],e=o[2],i=Sd(t*t+e*e),r=(vp(e,t)*hp+360)%360,0===xd(1e4*i)&&(r=Number.NaN),[n,i,r]},dd=function(){var t,e,i,r,n,o,a;return o=Pd(arguments),n=o[0],i=o[1],e=o[2],a=pd(n,i,e),r=a[0],t=a[1],e=a[2],Vp(r,t,e)},Sp.lch=function(){var t;return t=Pd(arguments),new op(t,"lch")},Sp.hcl=function(){var t;return t=Pd(arguments),new op(t,"hcl")},fp.lch=Xp,fp.hcl=function(){var t,e,i,r;return r=Pd(arguments),e=r[0],t=r[1],i=r[2],Xp([i,t,e])},op.prototype.lch=function(){return dd(this._rgb)},op.prototype.hcl=function(){return dd(this._rgb).reverse()},od=function(t){var e,i,r,n,o,a,s,c,u;return null==t&&(t="rgb"),c=Pd(arguments),s=c[0],n=c[1],e=c[2],s/=255,n/=255,e/=255,o=1-Math.max(s,Math.max(n,e)),r=o<1?1/(1-o):0,i=(1-s-o)*r,a=(1-n-o)*r,u=(1-e-o)*r,[i,a,u,o]},Mp=function(){var t,e,i,r,n,o,a,s,c;return e=Pd(arguments),r=e[0],a=e[1],c=e[2],o=e[3],t=e.length>4?e[4]:1,1===o?[0,0,0,t]:(s=r>=1?0:255*(1-r)*(1-o),n=a>=1?0:255*(1-a)*(1-o),i=c>=1?0:255*(1-c)*(1-o),[s,n,i,t])},fp.cmyk=function(){return Mp(Pd(arguments))},Sp.cmyk=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["cmyk"]),function(){})},op.prototype.cmyk=function(){return od(this._rgb)},fp.gl=function(){var t,e,i,r,n;for(r=function(){var t,i;t=Pd(arguments),i=[];for(e in t)n=t[e],i.push(n);return i}.apply(this,arguments),t=i=0;i<=2;t=++i)r[t]*=255;return r},Sp.gl=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["gl"]),function(){})},op.prototype.gl=function(){var t;return t=this._rgb,[t[0]/255,t[1]/255,t[2]/255,t[3]]},fd=function(t,e,i){var r;return r=Pd(arguments),t=r[0],e=r[1],i=r[2],t=Kp(t),e=Kp(e),i=Kp(i),.2126*t+.7152*e+.0722*i},Kp=function(t){return t/=255,t<=.03928?t/12.92:nd((t+.055)/1.055,2.4)},mp=[],Fp=function(t,e,i,r){var n,o,a,s;for(null==i&&(i=.5),null==r&&(r="rgb"),"object"!==Md(t)&&(t=Sp(t)),"object"!==Md(e)&&(e=Sp(e)),a=0,o=mp.length;a<o;a++)if(n=mp[a],r===n[0]){s=n[1](t,e,i,r);break}if(null==s)throw"color mode "+r+" is not supported";return s.alpha(t.alpha()+i*(e.alpha()-t.alpha()))},Sp.interpolate=Fp,op.prototype.interpolate=function(t,e,i){return Fp(this,t,e,i)},Sp.mix=Fp,op.prototype.mix=op.prototype.interpolate,Gp=function(t,e,i,r){var n,o;return n=t._rgb,o=e._rgb,new op(n[0]+i*(o[0]-n[0]),n[1]+i*(o[1]-n[1]),n[2]+i*(o[2]-n[2]),r)},mp.push(["rgb",Gp]),op.prototype.luminance=function(t,e){var i,r,n,o;return null==e&&(e="rgb"),arguments.length?(0===t?this._rgb=[0,0,0,this._rgb[3]]:1===t?this._rgb=[255,255,255,this._rgb[3]]:(r=1e-7,n=20,o=function(i,a){var s,c;return c=i.interpolate(a,.5,e),s=c.luminance(),Math.abs(t-s)<r||!n--?c:s>t?o(i,c):o(c,a)},i=fd(this._rgb),this._rgb=(i>t?o(Sp("black"),this):o(this,Sp("white"))).rgba()),this):fd(this._rgb)},Ad=function(t){var e,i,r,n;return n=t/100,n<66?(r=255,i=-155.25485562709179-.44596950469579133*(i=n-2)+104.49216199393888*Zp(i),e=n<20?0:.8274096064007395*(e=n-10)-254.76935184120902+115.67994401066147*Zp(e)):(r=351.97690566805693+.114206453784165*(r=n-55)-40.25366309332127*Zp(r),i=325.4494125711974+.07943456536662342*(i=n-50)-28.0852963507957*Zp(i),e=255),[r,i,e]},gd=function(){var t,e,i,r,n,o,a;for(r=(n=Pd(arguments))[0],n[1],t=n[2],i=1e3,e=4e4,.4;e-i>.4;)(o=Ad(a=.5*(e+i)))[2]/o[0]>=t/r?e=a:i=a;return xd(a)},Sp.temperature=Sp.kelvin=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["temperature"]),function(){})},fp.temperature=fp.kelvin=fp.K=Ad,op.prototype.temperature=function(){return gd(this._rgb)},op.prototype.kelvin=op.prototype.temperature,Sp.contrast=function(t,e){var i,r,n,o;return"string"!==(n=Md(t))&&"number"!==n||(t=new op(t)),"string"!==(o=Md(e))&&"number"!==o||(e=new op(e)),i=t.luminance(),r=e.luminance(),i>r?(i+.05)/(r+.05):(r+.05)/(i+.05)},Sp.distance=function(t,e,i){var r,n,o,a,s,c,u;null==i&&(i="lab"),"string"!==(s=Md(t))&&"number"!==s||(t=new op(t)),"string"!==(c=Md(e))&&"number"!==c||(e=new op(e)),o=t.get(i),a=e.get(i),u=0;for(n in o)u+=(r=(o[n]||0)-(a[n]||0))*r;return Math.sqrt(u)},Sp.deltaE=function(t,e,i,r){var n,o,a,s,c,u,h,l,p,d,f,m,g,v,y,b,x,_,w,S,A,M,P,T,E,C,I;for(null==i&&(i=1),null==r&&(r=1),"string"!==(x=Md(t))&&"number"!==x||(t=new op(t)),"string"!==(_=Md(e))&&"number"!==_||(e=new op(e)),n=(w=t.lab())[0],a=w[1],c=w[2],o=(S=e.lab())[0],s=S[1],u=S[2],h=Sd(a*a+c*c),l=Sd(s*s+u*u),P=n<16?.511:.040975*n/(1+.01765*n),A=.0638*h/(1+.0131*h)+.638,b=h<1e-6?0:180*vp(c,a)/cp;b<0;)b+=360;for(;b>=360;)b-=360;return T=b>=164&&b<=345?.56+gp(.2*Pp(cp*(b+168)/180)):.36+gp(.4*Pp(cp*(b+35)/180)),p=h*h*h*h,y=Sd(p/(p+1900)),M=A*(y*T+1-y),v=n-o,g=h-l,f=a-s,m=c-u,d=f*f+m*m-g*g,E=v/(i*P),C=g/(r*A),I=M,Sd(E*E+C*C+d/(I*I))},op.prototype.get=function(t){var e,i,r,n,o,a;return r=this,o=t.split("."),n=o[0],e=o[1],a=r[n](),e?(i=n.indexOf(e),i>-1?a[i]:console.warn("unknown channel "+e+" in mode "+n)):a},op.prototype.set=function(t,e){var i,r,n,o,a,s;if(n=this,a=t.split("."),o=a[0],i=a[1])if(s=n[o](),(r=o.indexOf(i))>-1)if("string"===Md(e))switch(e.charAt(0)){case"+":case"-":s[r]+=+e;break;case"*":s[r]*=+e.substr(1);break;case"/":s[r]/=+e.substr(1);break;default:s[r]=+e}else s[r]=e;else console.warn("unknown channel "+i+" in mode "+o);else s=e;return Sp(s,o).alpha(n.alpha())},op.prototype.clipped=function(){return this._rgb._clipped||!1},op.prototype.alpha=function(t){return arguments.length?Sp.rgb([this._rgb[0],this._rgb[1],this._rgb[2],t]):this._rgb[3]},op.prototype.darken=function(t){var e,i;return null==t&&(t=1),i=this,e=i.lab(),e[0]-=sp.Kn*t,Sp.lab(e).alpha(i.alpha())},op.prototype.brighten=function(t){return null==t&&(t=1),this.darken(-t)},op.prototype.darker=op.prototype.darken,op.prototype.brighter=op.prototype.brighten,op.prototype.saturate=function(t){var e,i;return null==t&&(t=1),i=this,e=i.lch(),e[1]+=t*sp.Kn,e[1]<0&&(e[1]=0),Sp.lch(e).alpha(i.alpha())},op.prototype.desaturate=function(t){return null==t&&(t=1),this.saturate(-t)},op.prototype.premultiply=function(){var t,e;return e=this.rgb(),t=this.alpha(),Sp(e[0]*t,e[1]*t,e[2]*t,t)},xp=function(t){return function(e,i){var r,n;return r=Sp(i).rgb(),n=Sp(e).rgb(),Sp(t(r,n),"rgb")}},Ip=function(t){return function(e,i){var r,n,o;for(o=[],r=n=0;n<=3;r=++n)o[r]=t(e[r],i[r]);return o}},ed=function(t,e){return t},td=function(t,e){return t*e/255},Ep=function(t,e){return t>e?e:t},qp=function(t,e){return t>e?t:e},_d=function(t,e){return 255*(1-(1-t/255)*(1-e/255))},rd=function(t,e){return e<128?2*t*e/255:255*(1-2*(1-t/255)*(1-e/255))},wp=function(t,e){return 255*(1-(1-e/255)/(t/255))},Cp=function(t,e){return 255===t?255:(t=e/255*255/(1-t/255),t>255?255:t)},(bp=function(t,e,i){if(!bp[i])throw"unknown blend mode "+i;return bp[i](t,e)}).normal=xp(Ip(ed)),bp.multiply=xp(Ip(td)),bp.screen=xp(Ip(_d)),bp.overlay=xp(Ip(rd)),bp.darken=xp(Ip(Ep)),bp.lighten=xp(Ip(qp)),bp.dodge=xp(Ip(Cp)),bp.burn=xp(Ip(wp)),Sp.blend=bp,Sp.analyze=function(t){var e,i,r,n;for(r={min:Number.MAX_VALUE,max:-1*Number.MAX_VALUE,sum:0,values:[],count:0},i=0,e=t.length;i<e;i++)null==(n=t[i])||isNaN(n)||(r.values.push(n),r.sum+=n,n<r.min&&(r.min=n),n>r.max&&(r.max=n),r.count+=1);return r.domain=[r.min,r.max],r.limits=function(t,e){return Sp.limits(r,t,e)},r},Sp.scale=function(t,e){var i,r,n,o,a,s,c,u,h,l,p,d,f,m,g,v,y,b,x,_;return u="rgb",h=Sp("#ccc"),f=0,!1,a=[0,1],d=[],p=[0,0],i=!1,n=[],l=!1,c=0,s=1,o=!1,r={},m=!0,x=function(t){var e,i,r,o,a,s;if(null==t&&(t=["#fff","#000"]),null!=t&&"string"===Md(t)&&null!=Sp.brewer&&(t=Sp.brewer[t]||Sp.brewer[t.toLowerCase()]||t),"array"===Md(t)){for(e=r=0,o=(t=t.slice(0)).length-1;0<=o?r<=o:r>=o;e=0<=o?++r:--r)i=t[e],"string"===Md(i)&&(t[e]=Sp(i));for(d.length=0,e=s=0,a=t.length-1;0<=a?s<=a:s>=a;e=0<=a?++s:--s)d.push(e/(t.length-1))}return b(),n=t},v=function(t){var e,r;if(null!=i){for(r=i.length-1,e=0;e<r&&t>=i[e];)e++;return e-1}return 0},_=function(t){return t},function(t){var e,r,n,o,a;return a=t,i.length>2&&(o=i.length-1,e=v(t),n=i[0]+(i[1]-i[0])*(0+.5*f),r=i[o-1]+(i[o]-i[o-1])*(1-.5*f),a=c+(i[e]+.5*(i[e+1]-i[e])-n)/(r-n)*(s-c)),a},y=function(t,e){var o,a,l,f,g,y,b;if(null==e&&(e=!1),isNaN(t))return h;if(e?b=t:i&&i.length>2?(b=v(t)/(i.length-2),b=p[0]+b*(1-p[0]-p[1])):s!==c?(b=(t-c)/(s-c),b=p[0]+b*(1-p[0]-p[1]),b=Math.min(1,Math.max(0,b))):b=1,e||(b=_(b)),l=Math.floor(1e4*b),m&&r[l])o=r[l];else{if("array"===Md(n))for(a=f=0,y=d.length-1;0<=y?f<=y:f>=y;a=0<=y?++f:--f){if(g=d[a],b<=g){o=n[a];break}if(b>=g&&a===d.length-1){o=n[a];break}if(b>g&&b<d[a+1]){b=(b-g)/(d[a+1]-g),o=Sp.interpolate(n[a],n[a+1],b,u);break}}else"function"===Md(n)&&(o=n(b));m&&(r[l]=o)}return o},b=function(){return r={}},x(t),g=function(t){var e;return e=Sp(y(t)),l&&e[l]?e[l]():e},g.classes=function(t){var e;return null!=t?("array"===Md(t)?(i=t,a=[t[0],t[t.length-1]]):(e=Sp.analyze(a),i=0===t?[e.min,e.max]:Sp.limits(e,"e",t)),g):i},g.domain=function(t){var e,i,r,o,u,h,l;if(!arguments.length)return a;if(c=t[0],s=t[t.length-1],d=[],r=n.length,t.length===r&&c!==s)for(u=0,o=t.length;u<o;u++)i=t[u],d.push((i-c)/(s-c));else for(e=l=0,h=r-1;0<=h?l<=h:l>=h;e=0<=h?++l:--l)d.push(e/(r-1));return a=[c,s],g},g.mode=function(t){return arguments.length?(u=t,b(),g):u},g.range=function(t,e){return x(t),g},g.out=function(t){return l=t,g},g.spread=function(t){return arguments.length?(f=t,g):f},g.correctLightness=function(t){return null==t&&(t=!0),o=t,b(),_=o?function(t){var e,i,r,n,o,a,s,c,u;for(e=y(0,!0).lab()[0],i=y(1,!0).lab()[0],s=e>i,r=y(t,!0).lab()[0],n=r-(o=e+(i-e)*t),c=0,u=1,a=20;Math.abs(n)>.01&&a-- >0;)!function(){s&&(n*=-1),n<0?(c=t,t+=.5*(u-t)):(u=t,t+=.5*(c-t)),r=y(t,!0).lab()[0],n=r-o}();return t}:function(t){return t},g},g.padding=function(t){return null!=t?("number"===Md(t)&&(t=[t,t]),p=t,g):p},g.colors=function(e,r){var o,s,c,u,h,l,p;if(null==r&&(r="hex"),0===arguments.length)return n.map(function(t){return t[r]()});if(e)return 1===e?g(.5)[r]():(s=a[0],o=a[1]-s,function(){h=[];for(var t=0;0<=e?t<e:t>e;0<=e?t++:t--)h.push(t);return h}.apply(this).map(function(t){return g(s+t/(e-1)*o)[r]()}));if(t=[],l=[],i&&i.length>2)for(c=p=1,u=i.length;1<=u?p<u:p>u;c=1<=u?++p:--p)l.push(.5*(i[c-1]+i[c]));else l=a;return l.map(function(t){return g(t)[r]()})},g.cache=function(t){return null!=t?m=t:m},g},null==Sp.scales&&(Sp.scales={}),Sp.scales.cool=function(){return Sp.scale([Sp.hsl(180,1,.9),Sp.hsl(250,.7,.4)])},Sp.scales.hot=function(){return Sp.scale(["#000","#f00","#ff0","#fff"],[0,.25,.75,1]).mode("rgb")},Sp.analyze=function(t,e,i){var r,n,o,a,s,c;if(s={min:Number.MAX_VALUE,max:-1*Number.MAX_VALUE,sum:0,values:[],count:0},null==i&&(i=function(){return!0}),r=function(t){null==t||isNaN(t)||(s.values.push(t),s.sum+=t,t<s.min&&(s.min=t),t>s.max&&(s.max=t),s.count+=1)},c=function(t,n){if(i(t,n))return r(null!=e&&"function"===Md(e)?e(t):null!=e&&"string"===Md(e)||"number"===Md(e)?t[e]:t)},"array"===Md(t))for(a=0,o=t.length;a<o;a++)c(t[a]);else for(n in t)c(t[n],n);return s.domain=[s.min,s.max],s.limits=function(t,e){return Sp.limits(s,t,e)},s},Sp.limits=function(t,e,i){var r,n,o,a,s,c,u,h,l,p,d,f,m,g,v,y,b,x,_,w,S,A,M,P,T,E,C,I,L,R,O,D,N,k,B,F,z,U,j,G,V,$,H,W,X,q,Y,Z,K,Q,J,tt,et,it,rt;if(null==e&&(e="equal"),null==i&&(i=7),"array"===Md(t)&&(t=Sp.analyze(t)),T=t.min,Jp=t.max,t.sum,it=t.values.sort(function(t,e){return t-e}),1===i)return[T,Jp];if(M=[],"c"===e.substr(0,1)&&(M.push(T),M.push(Jp)),"e"===e.substr(0,1)){for(M.push(T),w=O=1,B=i-1;1<=B?O<=B:O>=B;w=1<=B?++O:--O)M.push(T+w/i*(Jp-T));M.push(Jp)}else if("l"===e.substr(0,1)){if(T<=0)throw"Logarithmic scales are only possible for values > 0";for(E=Math.LOG10E*Zp(T),P=Math.LOG10E*Zp(Jp),M.push(T),w=rt=1,F=i-1;1<=F?rt<=F:rt>=F;w=1<=F?++rt:--rt)M.push(nd(10,E+w/i*(P-E)));M.push(Jp)}else if("q"===e.substr(0,1)){for(M.push(T),w=r=1,$=i-1;1<=$?r<=$:r>=$;w=1<=$?++r:--r)D=(it.length-1)*w/i,(N=Lp(D))===D?M.push(it[N]):(k=D-N,M.push(it[N]*(1-k)+it[N+1]*k));M.push(Jp)}else if("k"===e.substr(0,1)){for(I=it.length,g=new Array(I),x=new Array(i),Q=!0,L=0,y=null,(y=[]).push(T),w=n=1,H=i-1;1<=H?n<=H:n>=H;w=1<=H?++n:--n)y.push(T+w/i*(Jp-T));for(y.push(Jp);Q;){for(S=o=0,W=i-1;0<=W?o<=W:o>=W;S=0<=W?++o:--o)x[S]=0;for(w=a=0,X=I-1;0<=X?a<=X:a>=X;w=0<=X?++a:--a){for(et=it[w],C=Number.MAX_VALUE,S=s=0,q=i-1;0<=q?s<=q:s>=q;S=0<=q?++s:--s)(_=gp(y[S]-et))<C&&(C=_,v=S);x[v]++,g[w]=v}for(R=new Array(i),S=c=0,Y=i-1;0<=Y?c<=Y:c>=Y;S=0<=Y?++c:--c)R[S]=null;for(w=u=0,Z=I-1;0<=Z?u<=Z:u>=Z;w=0<=Z?++u:--u)null===R[b=g[w]]?R[b]=it[w]:R[b]+=it[w];for(S=h=0,K=i-1;0<=K?h<=K:h>=K;S=0<=K?++h:--h)R[S]*=1/x[S];for(Q=!1,S=l=0,z=i-1;0<=z?l<=z:l>=z;S=0<=z?++l:--l)if(R[S]!==y[w]){Q=!0;break}y=R,++L>200&&(Q=!1)}for(A={},S=p=0,U=i-1;0<=U?p<=U:p>=U;S=0<=U?++p:--p)A[S]=[];for(w=d=0,j=I-1;0<=j?d<=j:d>=j;w=0<=j?++d:--d)A[b=g[w]].push(it[w]);for(J=[],S=f=0,G=i-1;0<=G?f<=G:f>=G;S=0<=G?++f:--f)J.push(A[S][0]),J.push(A[S][A[S].length-1]);for(J=J.sort(function(t,e){return t-e}),M.push(J[0]),w=m=1,V=J.length-1;m<=V;w=m+=2)tt=J[w],isNaN(tt)||-1!==M.indexOf(tt)||M.push(tt)}return M},Dp=function(t,e,i){var r,n,o,a;return r=Pd(arguments),t=r[0],e=r[1],i=r[2],isNaN(t)&&(t=0),t/=360,t<1/3?o=1-((n=(1-e)/3)+(a=(1+e*Pp(lp*t)/Pp(up-lp*t))/3)):t<2/3?n=1-((a=(1-e)/3)+(o=(1+e*Pp(lp*(t-=1/3))/Pp(up-lp*t))/3)):a=1-((o=(1-e)/3)+(n=(1+e*Pp(lp*(t-=2/3))/Pp(up-lp*t))/3)),a=Yp(i*a*3),o=Yp(i*o*3),n=Yp(i*n*3),[255*a,255*o,255*n,r.length>3?r[3]:1]},ud=function(){var t,e,i,r,n,o,a,s;return a=Pd(arguments),o=a[0],e=a[1],t=a[2],lp=2*Math.PI,o/=255,e/=255,t/=255,n=Math.min(o,e,t),r=(o+e+t)/3,s=1-n/r,0===s?i=0:(i=(o-e+(o-t))/2,i/=Math.sqrt((o-e)*(o-e)+(o-t)*(e-t)),i=Math.acos(i),t>e&&(i=lp-i),i/=lp),[360*i,s,r]},Sp.hsi=function(){return function(t,e,i){i.prototype=t.prototype;var r=new i,n=t.apply(r,e);return Object(n)===n?n:r}(op,Rd.call(arguments).concat(["hsi"]),function(){})},fp.hsi=Dp,op.prototype.hsi=function(){return ud(this._rgb)},zp=function(t,e,i,r){var n,o,a,s,c,u,h,l,p,d,f;return"hsl"===r?(d=t.hsl(),f=e.hsl()):"hsv"===r?(d=t.hsv(),f=e.hsv()):"hcg"===r?(d=t.hcg(),f=e.hcg()):"hsi"===r?(d=t.hsi(),f=e.hsi()):"lch"!==r&&"hcl"!==r||(r="hcl",d=t.hcl(),f=e.hcl()),"h"===r.substr(0,1)&&(o=d[0],l=d[1],c=d[2],a=f[0],p=f[1],u=f[2]),isNaN(o)||isNaN(a)?isNaN(o)?isNaN(a)?n=Number.NaN:(n=a,1!==c&&0!==c||"hsv"===r||(h=p)):(n=o,1!==u&&0!==u||"hsv"===r||(h=l)):n=o+i*(a>o&&a-o>180?a-(o+360):a<o&&o-a>180?a+360-o:a-o),null==h&&(h=l+i*(p-l)),s=c+i*(u-c),Sp[r](n,h,s)},jp=function(t,e,i,r){var n,o;return n=t.num(),o=e.num(),Sp.num(n+(o-n)*i,"num")},(mp=mp.concat(function(){var t,e,i,r;for(r=[],e=0,t=(i=["hsv","hsl","hsi","hcl","lch","hcg"]).length;e<t;e++)Qp=i[e],r.push([Qp,zp]);return r}())).push(["num",jp]),Up=function(t,e,i,r){var n,o;return n=t.lab(),o=e.lab(),new op(n[0]+i*(o[0]-n[0]),n[1]+i*(o[1]-n[1]),n[2]+i*(o[2]-n[2]),r)},mp.push(["lab",Up]);var Od=Sp,Dd=function(t){var e=t||{};this.scale=dn(e.scale,"uniform"),this.mode=dn(e.mode,"hcl"),this.domain=dn(e.domain,[0,1]),this.value=new tt(dn(e.value,16777215)).getHex(),this.reverse=dn(e.reverse,!1),this.structure=e.structure,this.volume=e.volume,this.surface=e.surface,this.structure&&(this.atomProxy=this.structure.getAtomProxy())};Dd.prototype.getScale=function(t){var e=t||{},i=dn(e.scale,this.scale);"rainbow"===i?i=["red","orange","yellow","green","blue"]:"rwb"===i&&(i=["red","white","blue"]);var r=dn(e.domain,this.domain);return this.reverse&&r.reverse(),Od.scale(i).mode(dn(e.mode,this.mode)).domain(r).out("num")},Dd.prototype.colorToArray=function(t,e,i){return void 0===e&&(e=[]),void 0===i&&(i=0),e[i+0]=(t>>16&255)/255,e[i+1]=(t>>8&255)/255,e[i+2]=(255&t)/255,e},Dd.prototype.atomColorToArray=function(t,e,i){return this.colorToArray(this.atomColor(t),e,i)},Dd.prototype.bondColor=function(t,e){return this.atomProxy.index=e?t.atomIndex1:t.atomIndex2,this.atomColor(this.atomProxy)},Dd.prototype.bondColorToArray=function(t,e,i,r){return this.colorToArray(this.bondColor(t,e),i,r)},Dd.prototype.volumeColorToArray=function(t,e,i){return this.colorToArray(this.volumeColor(t),e,i)},Dd.prototype.positionColorToArray=function(t,e,i){return this.colorToArray(this.positionColor(t),e,i)},to.prototype={active:!0,params:null,execute:function(t){var e,i;return this.active&&this._listener&&(i=this.params?this.params.concat(t):t,e=this._listener.apply(this.context,i),this._isOnce&&this.detach()),e},detach:function(){return this.isBound()?this._signal.remove(this._listener,this.context):null},isBound:function(){return!!this._signal&&!!this._listener},isOnce:function(){return this._isOnce},getListener:function(){return this._listener},getSignal:function(){return this._signal},_destroy:function(){delete this._signal,delete this._listener,delete this.context},toString:function(){return"[SignalBinding isOnce:"+this._isOnce+", isBound:"+this.isBound()+", active:"+this.active+"]"}},io.prototype={VERSION:"1.0.0",memorize:!1,_shouldPropagate:!0,active:!0,_registerListener:function(t,e,i,r){var n,o=this._indexOfListener(t,i);if(-1!==o){if((n=this._bindings[o]).isOnce()!==e)throw new Error("You cannot add"+(e?"":"Once")+"() then add"+(e?"Once":"")+"() the same listener without removing the relationship first.")}else n=new to(this,t,e,i,r),this._addBinding(n);return this.memorize&&this._prevParams&&n.execute(this._prevParams),n},_addBinding:function(t){var e=this._bindings.length;do{--e}while(this._bindings[e]&&t._priority<=this._bindings[e]._priority);this._bindings.splice(e+1,0,t)},_indexOfListener:function(t,e){for(var i,r=this,n=this._bindings.length;n--;)if((i=r._bindings[n])._listener===t&&i.context===e)return n;return-1},has:function(t,e){return-1!==this._indexOfListener(t,e)},add:function(t,e,i){return eo(t,"add"),this._registerListener(t,!1,e,i)},addOnce:function(t,e,i){return eo(t,"addOnce"),this._registerListener(t,!0,e,i)},remove:function(t,e){eo(t,"remove");var i=this._indexOfListener(t,e);return-1!==i&&(this._bindings[i]._destroy(),this._bindings.splice(i,1)),t},removeAll:function(){for(var t=this,e=this._bindings.length;e--;)t._bindings[e]._destroy();this._bindings.length=0},getNumListeners:function(){return this._bindings.length},halt:function(){this._shouldPropagate=!1},dispatch:function(t){if(this.active){var e,i=Array.prototype.slice.call(arguments),r=this._bindings.length;if(this.memorize&&(this._prevParams=i),r){e=this._bindings.slice(),this._shouldPropagate=!0;do{r--}while(e[r]&&this._shouldPropagate&&!1!==e[r].execute(i))}}},forget:function(){this._prevParams=null},dispose:function(){this.removeAll(),delete this._bindings,delete this._prevParams},toString:function(){return"[Signal active:"+this.active+" numListeners:"+this.getNumListeners()+"]"}};var Nd={PROTEIN:1,NUCLEIC:2,RNA:3,DNA:4,POLYMER:5,WATER:6,HELIX:7,SHEET:8,TURN:9,BACKBONE:10,SIDECHAIN:11,ALL:12,HETERO:13,ION:14,SACCHARIDE:15,SUGAR:15,BONDED:16,RING:17},kd=["*","","ALL"],Bd=[Nd.BACKBONE,Nd.SIDECHAIN,Nd.BONDED,Nd.RING],Fd=[Nd.POLYMER,Nd.WATER],zd=["ALA","GLY","SER"],Ud=["CYS","SER","THR"],jd=["ALA","ILE","LEU","MET","PHE","PRO","TRP","VAL"],Gd=["PHE","TRP","TYR","HIS"],Vd=["ASN","GLN"],$d=["ASP","GLU"],Hd=["ARG","HIS","LYS"],Wd=["ARG","ASP","GLU","HIS","LYS"],Xd=["ASN","ARG","ASP","CYS","GLY","GLN","GLU","HIS","LYS","SER","THR","TYR"],qd=["ALA","ILE","LEU","MET","PHE","PRO","TRP","VAL"],Yd=["HIS","PHE","PRO","TRP","TYR"],Zd=["ALA","GLY","ILE","LEU","VAL"],Kd=function(t){this.signals={stringChanged:new io},this.setString(t)},Qd={type:{}};Qd.type.get=function(){return"selection"},Kd.prototype.setString=function(t,e){if(void 0===t&&(t=this.string||""),t!==this.string){try{this.parse(t)}catch(t){this.selection={error:t.message}}this.string=t,this.test=this.makeAtomTest(),this.residueTest=this.makeResidueTest(),this.chainTest=this.makeChainTest(),this.modelTest=this.makeModelTest(),this.atomOnlyTest=this.makeAtomTest(!0),this.residueOnlyTest=this.makeResidueTest(!0),this.chainOnlyTest=this.makeChainTest(!0),this.modelOnlyTest=this.makeModelTest(!0),e||this.signals.stringChanged.dispatch(this.string)}},Kd.prototype.parse=function(t){var e=this;if(this.selection={operator:void 0,rules:[]},t){var i,r,n=this.selection,o=[];"("===(t=t.replace(/\(/g," ( ").replace(/\)/g," ) ").trim()).charAt(0)&&")"===t.substr(-1)&&(t=t.slice(1,-1).trim());for(var a,s=t.split(/\s+/),c=function(t){i={operator:t,rules:[]},void 0===n?(n=i,e.selection=i):(n.rules.push(i),o.push(n),n=i)},u=function(t){r=n,void 0===(n=o.pop())&&(c(t),h(r))},h=function(t){n.rules.push(t)},l=0;l<s.length;++l){var p=s[l],d=p.toUpperCase();if("("!==p)if(")"!==p){if(a>0)if("NOT"===d)a=1;else if(1===a)a=2;else{if(2!==a)throw new Error("something went wrong with 'not'");a=!1,u()}if("AND"!==d)if("OR"!==d)if("NOT"!==p.toUpperCase()){var f=Nd[d];if(void 0===f)if("HYDROGEN"!==d)if("SMALL"!==d)if("NUCLEOPHILIC"!==d)if("HYDROPHOBIC"!==d)if("AROMATIC"!==d)if("AMIDE"!==d)if("ACIDIC"!==d)if("BASIC"!==d)if("CHARGED"!==d)if("POLAR"!==d)if("NONPOLAR"!==d)if("CYCLIC"!==d)if("ALIPHATIC"!==d)if("SIDECHAINATTACHED"!==d)if("LIGAND"!==d)if(-1===kd.indexOf(d))if("@"!==p.charAt(0))if("#"!==p.charAt(0))if("_"!==p.charAt(0))if("["!==p[0]||"]"!==p[p.length-1])if(p.length>=1&&p.length<=4&&"^"!==p[0]&&":"!==p[0]&&"."!==p[0]&&"%"!==p[0]&&"/"!==p[0]&&isNaN(parseInt(p)))h({resname:d});else{var m={operator:"AND",rules:[]},g=p.split("/");if(g.length>1&&g[1]){if(isNaN(parseInt(g[1])))throw new Error("model must be an integer");m.rules.push({model:parseInt(g[1])})}var v=g[0].split("%");v.length>1&&m.rules.push({altloc:v[1]});var y=v[0].split(".");if(y.length>1&&y[1]){if(y[1].length>4)throw new Error("atomname must be one to four characters");m.rules.push({atomname:y[1].substring(0,4).toUpperCase()})}var b=y[0].split(":");b.length>1&&b[1]&&m.rules.push({chainname:b[1]});var x=b[0].split("^");if(x.length>1&&m.rules.push({inscode:x[1]}),x[0]){var _=void 0,w=void 0;"-"===x[0][0]&&(x[0]=x[0].substr(1),_=!0),x[0].includes("--")&&(x[0]=x[0].replace("--","-"),w=!0);var S=x[0].split("-");if(1===S.length){if(S=parseInt(S[0]),isNaN(S))throw new Error("resi must be an integer");_&&(S*=-1),m.rules.push({resno:S})}else{if(2!==S.length)throw new Error("resi range must contain one '-'");_&&(S[0]*=-1),w&&(S[1]*=-1),m.rules.push({resno:[parseInt(S[0]),parseInt(S[1])]})}}if(1===m.rules.length)h(m.rules[0]);else{if(!(m.rules.length>1))throw new Error("empty selection chunk");h(m)}}else{var A=d.substr(1,p.length-2).split(","),M=A.length>1?A:A[0];h({resname:M})}else h({element:d.substr(1)});else console.error("# for element selection deprecated, use _"),h({element:d.substr(1)});else{for(var P=p.substr(1).split(","),T=0,E=P.length;T<E;++T)P[T]=parseInt(P[T]);P.sort(function(t,e){return t-e}),h({atomindex:P})}else h({keyword:Nd.ALL});else h({operator:"AND",rules:[{operator:"OR",rules:[{keyword:Nd.HETERO},{negate:!0,operator:void 0,rules:[{keyword:Nd.POLYMER}]}]},{negate:!0,operator:void 0,rules:[{operator:"OR",rules:[{keyword:Nd.WATER},{keyword:Nd.ION}]}]}]});else h({operator:"OR",rules:[{keyword:Nd.SIDECHAIN},{operator:"AND",negate:!1,rules:[{keyword:Nd.PROTEIN},{operator:"OR",negate:!1,rules:[{atomname:"CA"},{atomname:"BB"}]}]},{operator:"AND",negate:!1,rules:[{resname:"PRO"},{atomname:"N"}]},{operator:"AND",negate:!1,rules:[{keyword:Nd.NUCLEIC},{operator:"OR",negate:!0,rules:[{atomname:"P"},{atomname:"OP1"},{atomname:"OP2"},{atomname:"O3'"},{atomname:"O3*"},{atomname:"O5'"},{atomname:"O5*"},{atomname:"C5'"},{atomname:"C5*"}]}]}]});else h({resname:Zd});else h({resname:Yd});else h({resname:qd});else h({resname:Xd});else h({resname:Wd});else h({resname:Hd});else h({resname:$d});else h({resname:Vd});else h({resname:Gd});else h({resname:jd});else h({resname:Ud});else h({resname:zd});else h({element:"H"});else h({keyword:f})}else a=1,c(),n.negate=!0;else"AND"===n.operator?u("OR"):n.operator="OR";else if("OR"===n.operator){var C=n.rules.pop();c("AND"),h(C)}else n.operator="AND"}else u(),n.negate&&u();else a=!1,c()}void 0===this.selection.operator&&1===this.selection.rules.length&&this.selection.rules[0].hasOwnProperty("operator")&&(this.selection=this.selection.rules[0])}},Kd.prototype._makeTest=function(t,e){var i=this;if(void 0===e&&(e=this.selection),null===e)return!1;if(e.error)return!1;var r=e.rules.length;if(0===r)return!1;for(var n=!e.negate,o=!!e.negate,a=[],s=0;s<r;++s){var c=e.rules[s];c.hasOwnProperty("operator")&&(a[s]=i._makeTest(t,c))}return function(i){for(var s="AND"===e.operator,c=!1,u=0;u<r;++u){var h=e.rules[u],l=void 0;if(h.hasOwnProperty("operator")){if(-1===(l=a[u]?a[u](i):-1)){c=!0;continue}if(!0===l){if(s)continue;return n}if(s)return o}else{if(h.keyword===Nd.ALL){if(s)continue;return n}if(-1!==(l=t(i,h))){if(!0===l){if(s)continue;return n}if(s)return o}else c=!0}}return c?-1:s?n:o}},Kd.prototype._filter=function(t,e){var i=this;if(void 0===e&&(e=this.selection),e.error)return e;var r=e.rules.length;if(0===r)return e;var n={operator:e.operator,rules:[]};e.hasOwnProperty("negate")&&(n.negate=e.negate);for(var o=0;o<r;++o){var a=e.rules[o];if(a.hasOwnProperty("operator")){var s=i._filter(t,a);null!==s&&n.rules.push(s)}else t(a)||n.rules.push(a)}return n.rules.length>0?e:null},Kd.prototype.makeAtomTest=function(t){var e;return e=t?this._filter(function(t){return void 0!==t.keyword&&!Bd.includes(t.keyword)||(void 0!==t.model||(void 0!==t.chainname||(void 0!==t.resname||(void 0!==t.resno||void 0!==t.sstruc))))}):this.selection,this._makeTest(ro,e)},Kd.prototype.makeResidueTest=function(t){var e;return e=t?this._filter(function(t){return!(void 0===t.keyword||!Bd.includes(t.keyword))||(void 0!==t.model||(void 0!==t.chainname||(void 0!==t.atomname||(void 0!==t.element||void 0!==t.altloc))))}):this.selection,this._makeTest(no,e)},Kd.prototype.makeChainTest=function(t){var e;return e=t?this._filter(function(t){return void 0!==t.keyword&&!Fd.includes(t.keyword)||(void 0!==t.resname||(void 0!==t.resno||(void 0!==t.atomname||(void 0!==t.element||(void 0!==t.altloc||(void 0!==t.sstruc||void 0!==t.inscode))))))}):this.selection,this._makeTest(oo,e)},Kd.prototype.makeModelTest=function(t){var e;return e=t?this._filter(function(t){return void 0!==t.keyword||(void 0!==t.chainname||(void 0!==t.resname||(void 0!==t.resno||(void 0!==t.atomname||(void 0!==t.element||(void 0!==t.altloc||(void 0!==t.sstruc||void 0!==t.inscode)))))))}):this.selection,this._makeTest(ao,e)},Object.defineProperties(Kd.prototype,Qd);var Jd=function(t){function e(e){var i=this;t.call(this,e);var r=e.dataList||[];this.colormakerList=[],this.selectionList=[],r.forEach(function(t){var e=t[0],r=t[1],n=t[2];void 0===n&&(n={}),lf.hasScheme(e)?Object.assign(n,{scheme:e,structure:i.structure}):Object.assign(n,{scheme:"uniform",value:new tt(e).getHex()}),i.colormakerList.push(lf.getScheme(n)),i.selectionList.push(new Kd(r))})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){for(var e=this,i=0,r=this.selectionList.length;i<r;++i)if(e.selectionList[i].test(t))return e.colormakerList[i].atomColor(t);return 16777215},e}(Dd),tf={"":"",OrRd:"[S] Orange-Red",PuBu:"[S] Purple-Blue",BuPu:"[S] Blue-Purple",Oranges:"[S] Oranges",BuGn:"[S] Blue-Green",YlOrBr:"[S] Yellow-Orange-Brown",YlGn:"[S] Yellow-Green",Reds:"[S] Reds",RdPu:"[S] Red-Purple",Greens:"[S] Greens",YlGnBu:"[S] Yellow-Green-Blue",Purples:"[S] Purples",GnBu:"[S] Green-Blue",Greys:"[S] Greys",YlOrRd:"[S] Yellow-Orange-Red",PuRd:"[S] Purple-Red",Blues:"[S] Blues",PuBuGn:"[S] Purple-Blue-Green",Viridis:"[D] Viridis",Spectral:"[D] Spectral",RdYlGn:"[D] Red-Yellow-Green",RdBu:"[D] Red-Blue",PiYG:"[D] Pink-Yellowgreen",PRGn:"[D] Purplered-Green",RdYlBu:"[D] Red-Yellow-Blue",BrBG:"[D] Brown-Bluegreen",RdGy:"[D] Red-Grey",PuOr:"[D] Purple-Orange",Set1:"[Q] Set1",Set2:"[Q] Set2",Set3:"[Q] Set3",Dark2:"[Q] Dark2",Paired:"[Q] Paired",Pastel1:"[Q] Pastel1",Pastel2:"[Q] Pastel2",Accent:"[Q] Accent",rainbow:"[?] Rainbow",rwb:"[?] Red-White-Blue"},ef={"":"",rgb:"Red Green Blue",hsv:"Hue Saturation Value",hsl:"Hue Saturation Lightness",hsi:"Hue Saturation Intensity",lab:"CIE L*a*b*",hcl:"Hue Chroma Lightness"},rf=function(){this.schemes={},this.userSchemes={}};rf.prototype.getScheme=function(t){var e=(t||{}).scheme||"";return new(e in this.schemes?this.schemes[e]:e in this.userSchemes?this.userSchemes[e]:Dd)(t)},rf.prototype.getSchemes=function(){var t={};return Object.keys(this.schemes).forEach(function(e){t[e]=e}),Object.keys(this.userSchemes).forEach(function(e){t[e]=e.split("|")[1]}),t},rf.prototype.getScales=function(){return tf},rf.prototype.getModes=function(){return ef},rf.prototype.add=function(t,e){this.schemes[t]=e},rf.prototype.addScheme=function(t,e){return t instanceof Dd||(t=this._createScheme(t,e)),this._addUserScheme(t,e)},rf.prototype._addUserScheme=function(t,e){e=e||"";var i=$n()+"|"+e;return this.userSchemes[i]=t,i},rf.prototype.removeScheme=function(t){delete this.userSchemes[t]},rf.prototype._createScheme=function(t,e){var i=function(i){Dd.call(this,i),this.label=e||"",t.call(this,i)};return i.prototype=Dd.prototype,i.prototype.constructor=Dd,i},rf.prototype.addSelectionScheme=function(t,e){var i=function(e){function i(i){e.call(this,Object.assign({dataList:t},i))}return e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i,i}(Jd);return this._addUserScheme(i,e)},rf.prototype.hasScheme=function(t){return t in this.schemes||t in this.userSchemes};var nf=mn(),of="undefined"!=typeof window&&void 0!==window.orientation,af=!1,sf=!1,cf={log:Function.prototype.bind.call(console.log,console),info:Function.prototype.bind.call(console.info,console),warn:Function.prototype.bind.call(console.warn,console),error:Function.prototype.bind.call(console.error,console),time:Function.prototype.bind.call(console.time,console),timeEnd:Function.prototype.bind.call(console.timeEnd,console)};t.Debug=function(t){return!!t&&("string"!=typeof t||/^1|true|t|yes|y$/i.test(t))}(pn("debug"));var uf='<div style="display:flex;align-items:center;justify-content:center;height:100%;"><p style="padding:15px;text-align:center;">Your browser/graphics card does not seem to support <a target="_blank" href="https://en.wikipedia.org/wiki/WebGL">WebGL</a>.<br/><br/>Find out how to get it <a target="_blank" href="http://get.webgl.org/">here</a>.</p></div>',hf=new np,lf=new rf,pf=new ip("datasource"),df=new ip("representatation"),ff=new ip("parser"),mf=new ip("shader"),gf=new ip("decompressor"),vf=new ip("component");ho.prototype={constructor:ho,type:"",__srcName:void 0,isBinary:function(){return this.binary||this.compressed},onload:function(){},onprogress:function(){},onerror:function(){},read:function(){var t=this;return new Promise(function(e,i){try{t._read(function(i){var r=gf.get(t.compressed);t.compressed&&r?t.data=r(i):((t.binary||t.compressed)&&i instanceof ArrayBuffer&&(i=new Uint8Array(i)),t.data=i),e(t.data)})}catch(t){i(t)}})},_read:function(t){t(this.src)},_chunk:function(t,e){return e=Math.min(this.data.length,e),0===t&&this.data.length===e?this.data:this.isBinary()?this.data.subarray(t,e):this.data.substring(t,e)},chunk:function(t){var e=t+this.chunkSize;return this._chunk(t,e)},peekLines:function(t){var e,i=this.data,r=i.length,n=this.isBinary()?this.newline.charCodeAt(0):this.newline,o=0;for(e=0;e<r&&(i[e]===n&&++o,o!==t);++e);var a=this._chunk(0,e+1);return this.chunkToLines(a,"",e>r).lines},lineCount:function(){console.warn("lineCount - deprecated");for(var t=this.data,e=t.length,i=this.isBinary()?this.newline.charCodeAt(0):this.newline,r=0,n=0;n<e;++n)t[n]===i&&++r;return t[e-1]!==i&&++r,r},chunkCount:function(){return Math.floor(this.data.length/this.chunkSize)+1},asText:function(){return this.isBinary()?Pn(this.data):this.data},chunkToLines:function(t,e,i){var r=this.newline;if(!this.isBinary()&&t.length===this.data.length)return{lines:t.split(r),partialLine:""};var n=this.isBinary()?Pn(t):t,o=[],a=n.lastIndexOf(r);if(-1===a)e+=n;else{var s=e+n.substr(0,a);o=o.concat(s.split(r)),e=a===n.length-r.length?"":n.substr(a+r.length)}return i&&""!==e&&o.push(e),{lines:o,partialLine:e}},nextChunk:function(){var t=this.__pointer;if(!(t>this.data.length))return this.__pointer+=this.chunkSize,this.chunk(t)},nextChunkOfLines:function(){var t=this.nextChunk();if(void 0!==t){var e=this.__pointer>this.data.length,i=this.chunkToLines(t,this.__partialLine,e);return this.__partialLine=i.partialLine,i.lines}},eachChunk:function(t){for(var e=this,i=this.chunkSize,r=this.data.length,n=this.chunkCount(),o=0;o<r;o+=i)t(e.chunk(o),Math.round(o/i),n)},eachChunkOfLines:function(t){this.eachChunk(function(e,i,r){var n=i===r+1,o=this.chunkToLines(e,this.__partialLine,n);this.__partialLine=o.partialLine,t(o.lines,i,r)}.bind(this))},dispose:function(){delete this.src,this.__srcName&&delete this[this.__srcName]}},lo.prototype=Object.assign(Object.create(ho.prototype),{constructor:lo,type:"file",__srcName:"file",_read:function(t){var e;if("function"==typeof importScripts){e=new FileReaderSync;var i;i=this.binary||this.compressed?e.readAsArrayBuffer(this.file):e.readAsText(this.file),t(i)}else(e=new FileReader).onload=function(e){t(e.target.result)}.bind(this),"function"==typeof this.onprogress&&(e.onprogress=function(t){this.onprogress(t)}.bind(this)),"function"==typeof this.onerror&&(e.onerror=function(t){this.onerror(t)}.bind(this)),this.binary||this.compressed?e.readAsArrayBuffer(this.file):e.readAsText(this.file)}}),po.prototype=Object.assign(Object.create(ho.prototype),{constructor:po,type:"network",__srcName:"url",_read:function(t){var e=this.src;"function"==typeof importScripts&&"../"===e.substr(0,3)&&(e="../"+e);var i=new XMLHttpRequest;i.open("GET",e,!0),i.addEventListener("load",function(){if(200!==i.status&&304!==i.status&&0!==i.status)throw"function"==typeof this.onerror&&this.onerror(i.status),"NetworkStreamer._read: status code "+i.status;try{t(i.response)}catch(t){this.onerror(t)}}.bind(this),!1),"function"==typeof this.onerror&&i.addEventListener("error",function(t){this.onerror(t)}.bind(this),!1),this.isBinary()?i.responseType="arraybuffer":this.json?i.responseType="json":this.xml?i.responseType="document":i.responseType="text",i.send(null)}});var yf=["mmtf","dcd","mrc","ccp4","map","dsn6","brix","dxbin"],bf=["json"],xf=["xml","validation"],_f=function(t,e){var i=Object.assign({},e),r=yf.includes(i.ext);this.compressed=dn(i.compressed,!1),this.binary=dn(i.binary,r),this.name=dn(i.name,""),this.ext=dn(i.ext,""),this.dir=dn(i.dir,""),this.path=dn(i.path,""),this.protocol=dn(i.protocol,""),this.params=e;var n={compressed:this.compressed,binary:this.binary,json:bf.includes(this.ext),xml:xf.includes(this.ext)};"undefined"!=typeof File&&t instanceof File||"undefined"!=typeof Blob&&t instanceof Blob?this.streamer=new lo(t,n):this.streamer=new po(t,n),"function"==typeof i.onProgress&&(this.streamer.onprogress=i.onprogress)};_f.prototype.load=function(){return new Promise.reject("not implemented")};var wf=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.load=function(){return new(ff.get(this.ext))(this.streamer,this.params).parse()},e}(_f),Sf=function(t,e,i){this.signals={elementAdded:new io,elementRemoved:new io,nameChanged:new io},this.name=e,this.path=i,this.dir=i.substring(0,i.lastIndexOf("/")+1);try{this.fn=new Function("stage","panel","__name__","__path__","__dir__",t)}catch(t){cf.error("Script compilation failed",t),this.fn=function(){}}},Af={type:{}};Af.type.get=function(){return"Script"},Sf.prototype.call=function(t){var e=this,i={add:function(){this.signals.elementAdded.dispatch(arguments)}.bind(this),remove:function(){this.signals.elementRemoved.dispatch(arguments)}.bind(this),setName:function(t){this.signals.nameChanged.dispatch(t)}.bind(this)};return new Promise(function(r,n){var o=[t,i,e.name,e.path,e.dir];try{e.fn.apply(null,o),r()}catch(t){cf.error("Script.fn",t),n(t)}})},Object.defineProperties(Sf.prototype,Af);var Mf=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.load=function(){var t=this;return this.streamer.read().then(function(){return new Sf(t.streamer.asText(),t.name,t.path)})},e}(_f),Pf=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.load=function(){var t,e=this;return t=this.protocol?this.protocol+"://"+this.dir:this.dir,this.streamer.read().then(function(){var i=JSON.parse(e.streamer.asText()),r=[];return i.files.map(function(e){r.push(mo(t+e,{ext:"text",useWorker:!1}))}),Promise.all(r).then(function(t){var r=t.reduce(function(t,e){return t+"\n\n"+e.data},"");return r+=i.source||"",new Sf(r,e.name,e.path)})})},e}(_f),Tf={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/bcdiefguxX/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[\+\-]/};go.format=function(t,e){var i,r,n,o,a,s,c,u=1,h=t.length,l="",p=[],d=!0,f="";for(r=0;r<h;r++)if("string"===(l=vo(t[r])))p[p.length]=t[r];else if("array"===l){if((o=t[r])[2])for(i=e[u],n=0;n<o[2].length;n++){if(!i.hasOwnProperty(o[2][n]))throw new Error(go('[sprintf] property "%s" does not exist',o[2][n]));i=i[o[2][n]]}else i=o[1]?e[o[1]]:e[u++];if(Tf.not_type.test(o[8])&&Tf.not_primitive.test(o[8])&&"function"==vo(i)&&(i=i()),Tf.numeric_arg.test(o[8])&&"number"!=vo(i)&&isNaN(i))throw new TypeError(go("[sprintf] expecting number but found %s",vo(i)));switch(Tf.number.test(o[8])&&(d=i>=0),o[8]){case"b":i=parseInt(i,10).toString(2);break;case"c":i=String.fromCharCode(parseInt(i,10));break;case"d":case"i":i=parseInt(i,10);break;case"j":i=JSON.stringify(i,null,o[6]?parseInt(o[6]):0);break;case"e":i=o[7]?parseFloat(i).toExponential(o[7]):parseFloat(i).toExponential();break;case"f":i=o[7]?parseFloat(i).toFixed(o[7]):parseFloat(i);break;case"g":i=o[7]?parseFloat(i).toPrecision(o[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=String(i),i=o[7]?i.substring(0,o[7]):i;break;case"t":i=String(!!i),i=o[7]?i.substring(0,o[7]):i;break;case"T":i=vo(i),i=o[7]?i.substring(0,o[7]):i;break;case"u":i=parseInt(i,10)>>>0;break;case"v":i=i.valueOf(),i=o[7]?i.substring(0,o[7]):i;break;case"x":i=parseInt(i,10).toString(16);break;case"X":i=parseInt(i,10).toString(16).toUpperCase()}Tf.json.test(o[8])?p[p.length]=i:(!Tf.number.test(o[8])||d&&!o[3]?f="":(f=d?"+":"-",i=i.toString().replace(Tf.sign,"")),s=o[4]?"0"===o[4]?"0":o[4].charAt(1):" ",c=o[6]-(f+i).length,a=o[6]&&c>0?yo(s,c):"",p[p.length]=o[5]?f+i+a:"0"===s?f+a+i:a+f+i)}return p.join("")},go.cache={},go.parse=function(t){for(var e=t,i=[],r=[],n=0;e;){if(null!==(i=Tf.text.exec(e)))r[r.length]=i[0];else if(null!==(i=Tf.modulo.exec(e)))r[r.length]="%";else{if(null===(i=Tf.placeholder.exec(e)))throw new SyntaxError("[sprintf] unexpected placeholder");if(i[2]){n|=1;var o=[],a=i[2],s=[];if(null===(s=Tf.key.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(o[o.length]=s[1];""!==(a=a.substring(s[0].length));)if(null!==(s=Tf.key_access.exec(a)))o[o.length]=s[1];else{if(null===(s=Tf.index_access.exec(a)))throw new SyntaxError("[sprintf] failed to parse named argument key");o[o.length]=s[1]}i[2]=o}else n|=2;if(3===n)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");r[r.length]=i}e=e.substring(i[0].length)}return r};var Ef={0:["","0","00","000","0000","00000","000000","0000000"]," ":[""," ","  ","   ","    ","     ","      ","       "],_:["","_","__","___","____","_____","______","_______"]},Cf=function(){this.count=0,this.signals={countChanged:new io}};Cf.prototype.clear=function(){this.change(-this.count)},Cf.prototype.change=function(t){this.count+=t,this.signals.countChanged.dispatch(t,this.count),this.count<0&&cf.warn("Counter.count below zero",this.count)},Cf.prototype.increment=function(){this.change(1)},Cf.prototype.decrement=function(){this.change(-1)},Cf.prototype.listen=function(t){this.change(t.count),t.signals.countChanged.add(this.change,this)},Cf.prototype.unlisten=function(t){var e=t.signals.countChanged;e.has(this.change,this)&&e.remove(this.change,this)},Cf.prototype.onZeroOnce=function(t,e){if(0===this.count)t.call(e,0,0);else{var i=function(){0===this.count&&(this.signals.countChanged.remove(i,this),t.apply(e,arguments))};this.signals.countChanged.add(i,this)}},Cf.prototype.dispose=function(){this.clear(),this.signals.countChanged.dispose()},mf.add("shader/BasicLine.vert","void main(){\n#include begin_vertex\n#include project_vertex\n}"),mf.add("shader/BasicLine.frag","uniform vec3 uColor;\n#include common\n#include fog_pars_fragment\nvoid main(){\ngl_FragColor = vec4( uColor, 1.0 );\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n}"),mf.add("shader/Quad.vert","varying vec2 vUv;\nvoid main() {\nvUv = uv;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"),mf.add("shader/Quad.frag","varying vec2 vUv;\nuniform sampler2D tForeground;\nuniform float scale;\nvoid main() {\nvec4 foreground = texture2D( tForeground, vUv );\ngl_FragColor = foreground * scale;\n}"),xo.prototype={update:function(){this.startTime=this.end(),this.currentTime=this.startTime,this.signals.updated.dispatch()},begin:function(){this.startTime=performance.now(),this.lastFrames=this.frames},end:function(){var t=performance.now();return this.count+=1,this.frames+=1,this.lastDuration=t-this.startTime,this.minDuration=Math.min(this.minDuration,this.lastDuration),this.maxDuration=Math.max(this.maxDuration,this.lastDuration),this.avgDuration-=this.avgDuration/30,this.avgDuration+=this.lastDuration/30,t>this.prevFpsTime+1e3&&(this.lastFps=this.frames,this.prevFpsTime=t,this.frames=0),t}},mf.add("shader/chunk/dull_interior_fragment.glsl","#ifdef DULL_INTERIOR\nif( gl_FrontFacing == false ){\nnormal = vec3( 0.0, 0.0, 0.4 );\n}\n#endif"),mf.add("shader/chunk/fog_fragment.glsl","#ifdef USE_FOG\nfloat depth = length( vViewPosition );\n#ifdef FOG_EXP2\nfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\n#else\nfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n#endif\ngl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"),mf.add("shader/chunk/matrix_scale.glsl","float matrixScale( in mat4 m ){\nvec4 r = m[ 0 ];\nreturn sqrt( r[ 0 ] * r[ 0 ] + r[ 1 ] * r[ 1 ] + r[ 2 ] * r[ 2 ] );\n}"),mf.add("shader/chunk/nearclip_vertex.glsl","#ifdef NEAR_CLIP\nif( vViewPosition.z < nearClip - 5.0 )\ngl_Position.z = 2.0 * gl_Position.w;\n#endif"),mf.add("shader/chunk/nearclip_fragment.glsl","#ifdef NEAR_CLIP\nif( vViewPosition.z < nearClip )\ndiscard;\n#endif"),mf.add("shader/chunk/opaque_back_fragment.glsl","#ifdef OPAQUE_BACK\n#ifdef FLIP_SIDED\nif( gl_FrontFacing == true ){\ngl_FragColor.a = 1.0;\n}\n#else\nif( gl_FrontFacing == false ){\ngl_FragColor.a = 1.0;\n}\n#endif\n#endif"),mf.add("shader/chunk/radiusclip_vertex.glsl","#ifdef RADIUS_CLIP\nif( distance( vViewPosition, vClipCenter ) > clipRadius + 5.0 )\ngl_Position.z = 2.0 * gl_Position.w;\n#endif"),mf.add("shader/chunk/radiusclip_fragment.glsl","#ifdef RADIUS_CLIP\nif( distance( vViewPosition, vClipCenter ) > clipRadius )\ndiscard;\n#endif"),mf.add("shader/chunk/unpack_color.glsl","vec3 unpackColor(float f) {\nvec3 color;\ncolor.r = floor(f / 256.0 / 256.0);\ncolor.g = floor((f - color.r * 256.0 * 256.0) / 256.0);\ncolor.b = floor(f - color.r * 256.0 * 256.0 - color.g * 256.0);\nreturn color / 255.0;\n}");var If=/^(?!\/\/)\s*#include\s+(\S+)/gim,Lf={};if("undefined"!=typeof WebGLRenderingContext&&WebGLRenderingContext){var Rf=WebGLRenderingContext.prototype,Of=Rf.getShaderParameter;Rf.getShaderParameter=function(){return!t.Debug||Of.apply(this,arguments)};var Df=Rf.getShaderInfoLog;Rf.getShaderInfoLog=function(){return t.Debug?Df.apply(this,arguments):""};var Nf=Rf.getProgramParameter;Rf.getProgramParameter=function(e,i){return!t.Debug&&i===Rf.LINK_STATUS||Nf.apply(this,arguments)};var kf=Rf.getProgramInfoLog;Rf.getProgramInfoLog=function(){return t.Debug?kf.apply(this,arguments):""}}var Bf=[[[0,0]],[[4,4],[-4,-4]],[[-2,-6],[6,-2],[-6,2],[2,6]],[[1,-3],[-1,3],[5,1],[-3,-5],[-5,5],[-7,-1],[3,7],[7,-7]],[[1,1],[-1,-3],[-3,2],[4,-1],[-5,-2],[2,5],[5,3],[3,-5],[-2,6],[0,-7],[-4,-6],[-6,4],[-8,0],[7,-4],[6,7],[-7,-8]],[[-4,-7],[-7,-5],[-3,-5],[-5,-4],[-1,-4],[-2,-2],[-6,-1],[-4,0],[-7,1],[-1,2],[-6,3],[-3,3],[-7,6],[-3,6],[-5,7],[-1,7],[5,-7],[1,-6],[6,-5],[4,-4],[2,-3],[7,-2],[1,-1],[4,-1],[2,1],[6,2],[0,4],[4,4],[2,5],[7,5],[5,6],[3,7]]];Bf.forEach(function(t){t.forEach(function(t){t[0]*=.0625,t[1]*=.0625})}),So.prototype.constructor=So;var Ff=2*Math.PI,zf=(new Float32Array(4),new Float32Array(4),new g),Uf=new v,jf=new v,Gf=new v,Vf=new v,$f=new Float32Array(4),Hf=new Uint8Array(4),Wf=new v;Ho.prototype.constructor=Ho;var Xf=function(t,e){this.signals={moved:new io,scrolled:new io,dragged:new io,dropped:new io,clicked:new io,hovered:new io};var i=Object.assign({},e);this.hoverTimeout=dn(i.hoverTimeout,50),this.handleScroll=dn(i.handleScroll,!0),this.domElement=t,this.position=new l,this.prevPosition=new l,this.down=new l,this.canvasPosition=new l,this.moving=!1,this.hovering=!0,this.scrolled=!1,this.lastMoved=1/0,this.which=void 0,this.buttons=void 0,this.pressed=void 0,this.altKey=void 0,this.ctrlKey=void 0,this.metaKey=void 0,this.shiftKey=void 0,this._listen=this._listen.bind(this),this._onMousewheel=this._onMousewheel.bind(this),this._onMousemove=this._onMousemove.bind(this),this._onMousedown=this._onMousedown.bind(this),this._onMouseup=this._onMouseup.bind(this),this._onContextmenu=this._onContextmenu.bind(this),this._onTouchstart=this._onTouchstart.bind(this),this._onTouchend=this._onTouchend.bind(this),this._onTouchmove=this._onTouchmove.bind(this),this._listen(),document.addEventListener("mousewheel",this._onMousewheel),document.addEventListener("wheel",this._onMousewheel),document.addEventListener("MozMousePixelScroll",this._onMousewheel),document.addEventListener("mousemove",this._onMousemove),document.addEventListener("mousedown",this._onMousedown),document.addEventListener("mouseup",this._onMouseup),document.addEventListener("contextmenu",this._onContextmenu),document.addEventListener("touchstart",this._onTouchstart),document.addEventListener("touchend",this._onTouchend),document.addEventListener("touchmove",this._onTouchmove)},qf={key:{}};qf.key.get=function(){var t=0;return this.altKey&&(t+=1),this.ctrlKey&&(t+=2),this.metaKey&&(t+=4),this.shiftKey&&(t+=8),t},Xf.prototype.setParameters=function(t){var e=Object.assign({},t);this.hoverTimeout=dn(e.hoverTimeout,this.hoverTimeout)},Xf.prototype._listen=function(){if(performance.now()-this.lastMoved>this.hoverTimeout&&(this.moving=!1),(this.scrolled||!this.moving&&!this.hovering)&&(this.scrolled=!1,-1!==this.hoverTimeout&&this.overElement)){this.hovering=!0;var t=this.canvasPosition;this.signals.hovered.dispatch(t.x,t.y)}requestAnimationFrame(this._listen)},Xf.prototype._onMousewheel=function(t){var e=this;if(t.target===this.domElement&&this.handleScroll){t.preventDefault(),this._setKeys(t);var i=0;i=t.wheelDelta?t.wheelDelta/40:t.detail?-t.detail/3:-t.deltaY/(t.deltaMode?.33:30),this.signals.scrolled.dispatch(i),setTimeout(function(){e.scrolled=!0},this.hoverTimeout)}},Xf.prototype._onMousemove=function(t){t.target===this.domElement?(t.preventDefault(),this.overElement=!0):this.overElement=!1,this._setKeys(t),this.moving=!0,this.hovering=!1,this.lastMoved=performance.now(),this.prevPosition.copy(this.position),this.position.set(t.clientX,t.clientY),this._setCanvasPosition(t);var e=this.prevPosition.x-this.position.x,i=this.prevPosition.y-this.position.y;this.signals.moved.dispatch(e,i),this.pressed&&this.signals.dragged.dispatch(e,i)},Xf.prototype._onMousedown=function(t){t.target===this.domElement&&(t.preventDefault(),this._setKeys(t),this.moving=!1,this.hovering=!1,this.down.set(t.clientX,t.clientY),this.position.set(t.clientX,t.clientY),this.which=t.which,this.buttons=Xo(t),this.pressed=!0,this._setCanvasPosition(t))},Xf.prototype._onMouseup=function(t){t.target===this.domElement&&t.preventDefault(),this._setKeys(t);var e=this.canvasPosition;this.signals.clicked.dispatch(e.x,e.y),this.which=void 0,this.buttons=void 0,this.pressed=void 0},Xf.prototype._onContextmenu=function(t){t.target===this.domElement&&t.preventDefault()},Xf.prototype._onTouchstart=function(t){if(t.target===this.domElement)switch(t.preventDefault(),this.pressed=!0,t.touches.length){case 1:this.moving=!1,this.hovering=!1,this.down.set(t.touches[0].pageX,t.touches[0].pageY),this.position.set(t.touches[0].pageX,t.touches[0].pageY),this._setCanvasPosition(t.touches[0]);break;case 2:this.down.set((t.touches[0].pageX+t.touches[1].pageX)/2,(t.touches[0].pageY+t.touches[1].pageY)/2),this.position.set((t.touches[0].pageX+t.touches[1].pageX)/2,(t.touches[0].pageY+t.touches[1].pageY)/2),this.lastTouchDistance=Wo(t)}},Xf.prototype._onTouchend=function(t){t.target===this.domElement&&t.preventDefault(),this.pressed=!1},Xf.prototype._onTouchmove=function(t){switch(t.target===this.domElement?(t.preventDefault(),this.overElement=!0):this.overElement=!1,t.touches.length){case 1:this._setKeys(t),this.which=void 0,this.buttons=void 0,this.moving=!0,this.hovering=!1,this.lastMoved=performance.now(),this.prevPosition.copy(this.position),this.position.set(t.touches[0].pageX,t.touches[0].pageY),this._setCanvasPosition(t.touches[0]);var e=this.prevPosition.x-this.position.x,i=this.prevPosition.y-this.position.y;this.signals.moved.dispatch(e,i),this.pressed&&this.signals.dragged.dispatch(e,i);break;case 2:this.which=3,this.buttons=2;var r=Wo(t),n=r-this.lastTouchDistance;if(this.lastTouchDistance=r,Math.abs(n)>1)this.signals.scrolled.dispatch(n/2);else{this.prevPosition.copy(this.position),this.position.set((t.touches[0].pageX+t.touches[1].pageX)/2,(t.touches[0].pageY+t.touches[1].pageY)/2);var o=this.prevPosition.x-this.position.x,a=this.prevPosition.y-this.position.y;this.signals.moved.dispatch(o,a),this.pressed&&this.signals.dragged.dispatch(o,a)}}},Xf.prototype._distance=function(){return this.position.distanceTo(this.down)},Xf.prototype._setCanvasPosition=function(t){var e,i,r=this.domElement.getBoundingClientRect();"offsetX"in t&&"offsetY"in t?(e=t.offsetX,i=t.offsetY):(e=t.clientX-r.left,i=t.clientY-r.top),this.canvasPosition.set(e,r.height-i)},Xf.prototype._setKeys=function(t){this.altKey=t.altKey,this.ctrlKey=t.ctrlKey,this.metaKey=t.metaKey,this.shiftKey=t.shiftKey},Xf.prototype.dispose=function(){document.removeEventListener("mousewheel",this._onMousewheel),document.removeEventListener("wheel",this._onMousewheel),document.removeEventListener("MozMousePixelScroll",this._onMousewheel),document.removeEventListener("mousemove",this._onMousemove),document.removeEventListener("mousedown",this._onMousedown),document.removeEventListener("mouseup",this._onMouseup),document.removeEventListener("contextmenu",this._onContextmenu),document.removeEventListener("touchstart",this._onTouchstart),document.removeEventListener("touchend",this._onTouchend),document.removeEventListener("touchmove",this._onTouchmove)},Object.defineProperties(Xf.prototype,qf);var Yf=new v,Zf=new v,Kf=new v,Qf=new g,Jf=new m,tm=new v,em=new g,im=function(t,e){var i=e||{};this.rotateSpeed=dn(i.rotateSpeed,2),this.zoomSpeed=dn(i.zoomSpeed,1.2),this.panSpeed=dn(i.panSpeed,1),this.stage=t,this.viewer=t.viewer,this.mouse=t.mouseObserver,this.controls=t.viewerControls},rm={component:{}};rm.component.get=function(){return this.stage.transformComponent},im.prototype._setPanVector=function(t,e){var i,r=this.viewer.camera;if("OrthographicCamera"===r.type)i=1/r.zoom;else{var n=Gn(r.fov);i=-2*r.position.z*Math.tan(n/2)/this.viewer.height}em.set(t,e,0),em.multiplyScalar(this.panSpeed*i)},im.prototype._getRotateXY=function(t,e){return[this.rotateSpeed*-t*.01,this.rotateSpeed*e*.01]},im.prototype.zoom=function(t){this.controls.zoom(this.zoomSpeed*t*.02)},im.prototype.pan=function(t,e){this._setPanVector(t,e),tm.getInverse(this.viewer.rotationGroup.matrix),em.applyMatrix4(tm),this.controls.translate(em)},im.prototype.panComponent=function(t,e){this.component&&(this._setPanVector(t,e),tm.extractRotation(this.component.transform),tm.premultiply(this.viewer.rotationGroup.matrix),tm.getInverse(tm),em.applyMatrix4(tm),this.component.position.add(em),this.component.updateMatrix())},im.prototype.rotate=function(t,e){var i=this._getRotateXY(t,e),r=i[0],n=i[1];Yf.makeRotationX(n),Zf.makeRotationY(r),Yf.multiply(Zf),this.controls.applyMatrix(Yf)},im.prototype.rotateComponent=function(t,e){if(this.component){var i=this._getRotateXY(t,e),r=i[0],n=i[1];Kf.extractRotation(this.component.transform),Kf.premultiply(this.viewer.rotationGroup.matrix),Kf.getInverse(Kf),Qf.set(1,0,0),Qf.applyMatrix4(Kf),Yf.makeRotationAxis(Qf,n),Qf.set(0,1,0),Qf.applyMatrix4(Kf),Zf.makeRotationAxis(Qf,r),Yf.multiply(Zf),Jf.setFromRotationMatrix(Yf),this.component.quaternion.premultiply(Jf),this.component.updateMatrix()}},Object.defineProperties(im.prototype,rm);var nm=function(t,e){this.pid=t.pid,this.picker=t.picker,this.instance=t.instance,this.stage=e,this.controls=e.viewerControls,this.mouse=e.mouseObserver},om={type:{},altKey:{},ctrlKey:{},metaKey:{},shiftKey:{},canvasPosition:{},component:{},object:{},position:{},closestBondAtom:{},arrow:{},atom:{},axes:{},bond:{},cone:{},clash:{},contact:{},cylinder:{},distance:{},ellipsoid:{},mesh:{},slice:{},sphere:{},surface:{},unitcell:{},unknown:{},volume:{}};om.type.get=function(){return this.picker.type},om.altKey.get=function(){return this.mouse.altKey},om.ctrlKey.get=function(){return this.mouse.ctrlKey},om.metaKey.get=function(){return this.mouse.metaKey},om.shiftKey.get=function(){return this.mouse.shiftKey},om.canvasPosition.get=function(){return this.mouse.canvasPosition},om.component.get=function(){return this.stage.getComponentsByObject(this.picker.data).list[0]},om.object.get=function(){return this.picker.getObject(this.pid)},om.position.get=function(){return this.picker.getPosition(this.pid,this.instance,this.component)},om.closestBondAtom.get=function(){if("bond"===this.type){var t=this.bond,e=this.controls;return qo(this.canvasPosition,e.getPositionOnCanvas(t.atom1),e.getPositionOnCanvas(t.atom2))?t.atom1:t.atom2}},om.arrow.get=function(){return this._objectIfType("arrow")},om.atom.get=function(){return this._objectIfType("atom")},om.axes.get=function(){return this._objectIfType("axes")},om.bond.get=function(){return this._objectIfType("bond")},om.cone.get=function(){return this._objectIfType("cone")},om.clash.get=function(){return this._objectIfType("clash")},om.contact.get=function(){return this._objectIfType("contact")},om.cylinder.get=function(){return this._objectIfType("cylinder")},om.distance.get=function(){return this._objectIfType("distance")},om.ellipsoid.get=function(){return this._objectIfType("ellipsoid")},om.mesh.get=function(){return this._objectIfType("mesh")},om.slice.get=function(){return this._objectIfType("slice")},om.sphere.get=function(){return this._objectIfType("sphere")},om.surface.get=function(){return this._objectIfType("surface")},om.unitcell.get=function(){return this._objectIfType("unitcell")},om.unknown.get=function(){return this._objectIfType("unknown")},om.volume.get=function(){return this._objectIfType("volume")},nm.prototype._objectIfType=function(t){return this.type===t?this.object:void 0},nm.prototype.getLabel=function(){var t="nothing";return this.arrow?t="arrow: "+(this.arrow.name||this.pid)+" ("+this.arrow.shape.name+")":this.atom?t="atom: "+this.atom.qualifiedName()+" ("+this.atom.structure.name+")":this.axes?t="axes":this.bond?t="bond: "+this.bond.atom1.qualifiedName()+" - "+this.bond.atom2.qualifiedName()+" ("+this.bond.structure.name+")":this.cone?t="cone: "+(this.cone.name||this.pid)+" ("+this.cone.shape.name+")":this.clash?t="clash: "+this.clash.clash.sele1+" - "+this.clash.clash.sele2:this.contact?t="contact: "+this.contact.atom1.qualifiedName()+" - "+this.contact.atom2.qualifiedName()+" ("+this.contact.structure.name+")":this.cylinder?t="cylinder: "+(this.cylinder.name||this.pid)+" ("+this.cylinder.shape.name+")":this.distance?t="distance: "+this.distance.atom1.qualifiedName()+" - "+this.distance.atom2.qualifiedName()+" ("+this.distance.structure.name+")":this.ellipsoid?t="ellipsoid: "+(this.ellipsoid.name||this.pid)+" ("+this.ellipsoid.shape.name+")":this.mesh?t="mesh: "+(this.mesh.name||this.mesh.serial)+" ("+this.mesh.shape.name+")":this.slice?t="slice: "+this.slice.value.toPrecision(3)+" ("+this.slice.volume.name+")":this.sphere?t="sphere: "+(this.sphere.name||this.pid)+" ("+this.sphere.shape.name+")":this.surface?t="surface: "+this.surface.surface.name:this.unitcell?t="unitcell: "+this.unitcell.unitcell.spacegroup+" ("+this.unitcell.structure.name+")":this.unknown?t="unknown":this.volume&&(t="volume: "+this.volume.value.toPrecision(3)+" ("+this.volume.volume.name+")"),t},Object.defineProperties(nm.prototype,om);var am=function(t){this.stage=t,this.viewer=t.viewer};am.prototype.pick=function(t,e){var i=this.viewer.pick(t,e);if(i.picker&&"ignore"!==i.picker.type&&void 0!==i.pid){var r=i.picker.array;if(!(r&&i.pid>=r.length))return new nm(i,this.stage);console.error("pid >= picker.array.length")}};var sm=new m,cm=new g,um=new g,hm=new g,lm=new g,pm=new v,dm=new g,fm=new v,mm=function(t){this.stage=t,this.viewer=t.viewer,this.signals={changed:new io}},gm={position:{},rotation:{}};gm.position.get=function(){return this.viewer.translationGroup.position},gm.rotation.get=function(){return this.viewer.rotationGroup.quaternion},mm.prototype.changed=function(){this.viewer.requestRender(),this.signals.changed.dispatch()},mm.prototype.getPositionOnCanvas=function(t,e){var i=Rn(e),r=this.viewer;return hm.copy(t).add(r.translationGroup.position).applyMatrix4(r.rotationGroup.matrix).project(r.camera),i.set((hm.x+1)*r.width/2,(hm.y+1)*r.height/2)},mm.prototype.getOrientation=function(t){var e=Dn(t);e.copy(this.viewer.rotationGroup.matrix);var i=-this.viewer.camera.position.z;return e.scale(lm.set(i,i,i)),e.setPosition(this.viewer.translationGroup.position),e},mm.prototype.orient=function(t){Dn(t).decompose(cm,sm,um);var e=this.viewer;e.rotationGroup.setRotationFromQuaternion(sm),e.translationGroup.position.copy(cm),e.camera.position.z=-um.z,e.updateZoom(),this.changed()},mm.prototype.translate=function(t){this.viewer.translationGroup.position.add(On(t)),this.changed()},mm.prototype.center=function(t){this.viewer.translationGroup.position.copy(On(t)).negate(),this.changed()},mm.prototype.zoom=function(t){this.distance(this.viewer.camera.position.z*(1-t))},mm.prototype.distance=function(t){this.viewer.camera.position.z=t,this.viewer.updateZoom(),this.changed()},mm.prototype.spin=function(t,e){pm.getInverse(this.viewer.rotationGroup.matrix),dm.copy(On(t)).applyMatrix4(pm),this.viewer.rotationGroup.rotateOnAxis(dm,e),this.changed()},mm.prototype.rotate=function(t){this.viewer.rotationGroup.setRotationFromQuaternion(Nn(t)),this.changed()},mm.prototype.align=function(t){fm.getInverse(Dn(t)),this.viewer.rotationGroup.setRotationFromMatrix(fm),this.changed()},mm.prototype.applyMatrix=function(t){this.viewer.rotationGroup.applyMatrix(Dn(t)),this.changed()},Object.defineProperties(mm.prototype,gm);var vm=function(t,e){for(var i=[],r=arguments.length-2;r-- >0;)i[r]=arguments[r+2];this.duration=dn(t,1e3),this.controls=e,this.startTime=performance.now(),this.elapsedTime=0,this._resolveList=[],(n=this)._init.apply(n,i);var n},ym={done:{}};ym.done.get=function(){return 1===this.alpha},vm.prototype._init=function(){},vm.prototype._tick=function(){},vm.prototype.tick=function(t){return this.elapsedTime=t.currentTime-this.startTime,0===this.duration?this.alpha=1:this.alpha=Qn(0,1,this.elapsedTime/this.duration),this._tick(t),this.done&&this._resolveList.forEach(function(t){t()}),this.done},vm.prototype.then=function(t){var e=this;return(this.done?Promise.resolve():new Promise(function(t){e._resolveList.push(t)})).then(t)},Object.defineProperties(vm.prototype,ym);var bm=function(t){function e(e){for(var i=[],r=arguments.length-1;r-- >0;)i[r]=arguments[r+1];t.apply(this,[dn(e,1/0)].concat(i))}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._init=function(t,e){Array.isArray(t)?this.axis=(new g).fromArray(t):this.axis=dn(t,new g(0,1,0)),this.angle=dn(e,.01)},e.prototype._tick=function(t){this.axis&&this.angle&&this.controls.spin(this.axis,this.angle*t.lastDuration/16)},e}(vm),xm=function(t){function e(e){for(var i=[],r=arguments.length-1;r-- >0;)i[r]=arguments[r+1];t.apply(this,[dn(e,1/0)].concat(i))}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._init=function(t,e,i){Array.isArray(t)?this.axis=(new g).fromArray(t):this.axis=dn(t,new g(0,1,0)),this.angleStep=dn(e,.01),this.angleEnd=dn(i,.2),this.angleSum=0,this.direction=1},e.prototype._tick=function(t){if(this.axis&&this.angleStep&&this.angleEnd){var e=Qn(0,1,Math.abs(this.angleSum)/this.angleEnd),i=this.angleStep*this.direction*(1.1-e);this.controls.spin(this.axis,i*t.lastDuration/16),this.angleSum+=this.angleStep,this.angleSum>=this.angleEnd&&(this.direction*=-1,this.angleSum=-this.angleEnd)}},e}(vm),_m=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._init=function(t,e){this.moveFrom=On(dn(t,new g)),this.moveTo=On(dn(e,new g))},e.prototype._tick=function(){this.controls.position.lerpVectors(this.moveFrom,this.moveTo,this.alpha).negate(),this.controls.changed()},e}(vm),wm=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._init=function(t,e){this.zoomFrom=t,this.zoomTo=e},e.prototype._tick=function(){this.controls.distance(Zn(this.zoomFrom,this.zoomTo,this.alpha))},e}(vm),Sm=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._init=function(t,e){this.rotateFrom=Nn(t),this.rotateTo=Nn(e),this._currentRotation=new m},e.prototype._tick=function(){this._currentRotation.copy(this.rotateFrom).slerp(this.rotateTo,this.alpha),this.controls.rotate(this._currentRotation)},e}(vm),Am=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype._init=function(t,e,i){this.valueFrom=t,this.valueTo=e,this.callback=i},e.prototype._tick=function(){this.callback(Zn(this.valueFrom,this.valueTo,this.alpha))},e}(vm),Mm=function(t){this._list=t||[],this._resolveList=[]},Pm={done:{}};Pm.done.get=function(){return this._list.every(function(t){return t.done})},Mm.prototype.then=function(t){var e=this;return(this.done?Promise.resolve():new Promise(function(t){e._resolveList.push(t),e._list.forEach(function(t){t.then(function(){e._resolveList.forEach(function(t){t()}),e._resolveList.length=0})})})).then(t)},Object.defineProperties(Mm.prototype,Pm);var Tm=function(t){this.stage=t,this.viewer=t.viewer,this.controls=t.viewerControls,this.animationList=[],this.finishedList=[]};Tm.prototype.add=function(t){return 0===t.duration?t.tick(this.viewer.stats):this.animationList.push(t),t},Tm.prototype.remove=function(t){var e=this.animationList,i=e.indexOf(t);i>-1&&e.splice(i,1)},Tm.prototype.run=function(t){for(var e=this,i=this.finishedList,r=this.animationList,n=r.length,o=0;o<n;++o){var a=r[o];a.tick(t)&&i.push(a)}var s=i.length;if(s){for(var c=0;c<s;++c)e.remove(i[c]);i.length=0}},Tm.prototype.spin=function(t,e,i){return this.add(new bm(i,this.controls,t,e))},Tm.prototype.rock=function(t,e,i,r){return this.add(new xm(r,this.controls,t,e,i))},Tm.prototype.rotate=function(t,e){var i=this.viewer.rotationGroup.quaternion.clone();return this.add(new Sm(e,this.controls,i,t))},Tm.prototype.move=function(t,e){var i=this.controls.position.clone().negate();return this.add(new _m(e,this.controls,i,t))},Tm.prototype.zoom=function(t,e){var i=this.viewer.camera.position.z;return this.add(new wm(e,this.controls,i,t))},Tm.prototype.zoomMove=function(t,e,i){return new Mm([this.move(t,i),this.zoom(e,i)])},Tm.prototype.orient=function(t,e){var i=new g,r=new m,n=new g;return Dn(t).decompose(i,r,n),new Mm([this.move(i.negate(),e),this.rotate(r,e),this.zoom(-n.x,e)])},Tm.prototype.value=function(t,e,i,r){return this.add(new Am(r,this.controls,t,e,i))},Tm.prototype.spinComponent=function(t,e,i,r){return this.add(new bm(r,t.controls,e,i))},Tm.prototype.rockComponent=function(t,e,i,r,n){return this.add(new xm(n,t.controls,e,i,r))},Tm.prototype.moveComponent=function(t,e,i){var r=t.controls.position.clone().negate();return this.add(new _m(i,t.controls,r,e))},Tm.prototype.clear=function(){this.animationList.length=0},Tm.prototype.dispose=function(){this.clear()};var Em=function(){};Em.zoomScroll=function(t,e){t.trackballControls.zoom(e)},Em.clipNearScroll=function(t,e){var i=t.getParameters();t.setParameters({clipNear:i.clipNear+e/10})},Em.focusScroll=function(t,e){var i=2*t.getParameters().clipNear,r=Math.sign(e)*Jn((100-i)/10,5,.2);t.setFocus(i+r)},Em.isolevelScroll=function(t,e){var i=Math.sign(e)/5;t.eachRepresentation(function(t){if("surface"===t.repr.type){var e=t.getParameters().isolevel;t.setParameters({isolevel:e+i})}},"volume")},Em.panDrag=function(t,e,i){t.trackballControls.pan(e,i)},Em.rotateDrag=function(t,e,i){t.trackballControls.rotate(e,i)},Em.zoomDrag=function(t,e,i){t.trackballControls.zoom((e+i)/-2)},Em.zoomFocusDrag=function(t,e,i){t.trackballControls.zoom((e+i)/-2);var r=t.viewer.camera.position.z;t.setFocus(100-Math.abs(r/8))},Em.panComponentDrag=function(t,e,i){t.trackballControls.panComponent(e,i)},Em.rotateComponentDrag=function(t,e,i){t.trackballControls.rotateComponent(e,i)},Em.movePick=function(t,e){e&&t.animationControls.move(e.position.clone())},Em.tooltipPick=function(t,e){var i=t.tooltip;if(t.getParameters().tooltip&&e){var r=e.mouse.position;i.innerText=e.getLabel(),i.style.bottom=window.innerHeight-r.y+3+"px",i.style.left=r.x+3+"px",i.style.display="block"}else i.style.display="none"};var Cm={default:[["scroll",Em.zoomScroll],["scroll-ctrl",Em.clipNearScroll],["scroll-shift",Em.focusScroll],["scroll-alt",Em.isolevelScroll],["drag-right",Em.panDrag],["drag-left",Em.rotateDrag],["drag-middle",Em.zoomDrag],["drag-left+right",Em.zoomDrag],["drag-ctrl-right",Em.panComponentDrag],["drag-ctrl-left",Em.rotateComponentDrag],["clickPick-middle",Em.movePick],["hoverPick",Em.tooltipPick]],pymol:[["drag-left",Em.rotateDrag],["drag-middle",Em.panDrag],["drag-right",Em.zoomDrag],["drag-shift-right",Em.focusScroll],["clickPick-ctrl+shift-middle",Em.movePick],["hoverPick",Em.tooltipPick]],coot:[["scroll",Em.isolevelScroll],["drag-left",Em.rotateDrag],["drag-middle",Em.panDrag],["drag-ctrl-left",Em.panDrag],["drag-right",Em.zoomFocusDrag],["drag-ctrl-right",Em.focusScroll],["clickPick-middle",Em.movePick],["hoverPick",Em.tooltipPick]]},Im=function(t,e){var i=e||{};this.stage=t,this.mouse=t.mouseObserver,this.actionList=[],this.preset(i.preset||"default")};Im.prototype.run=function(t){for(var e=this,i=[],r=arguments.length-1;r-- >0;)i[r]=arguments[r+1];var n=this.mouse.key||0,o=this.mouse.buttons||0;this.actionList.forEach(function(r){r.type===t&&r.key===n&&r.button===o&&r.callback.apply(r,[e.stage].concat(i))})},Im.prototype.add=function(t,e){var i=Yo(t),r=i[0],n=i[1],o=i[2];this.actionList.push({type:r,key:n,button:o,callback:e})},Im.prototype.remove=function(t,e){var i=t.includes("*"),r=Yo(t),n=r[0],o=r[1],a=r[2],s=this.actionList.filter(function(t){return!((t.type===n||i&&""===n)&&(t.key===o||i&&0===o)&&(t.button===a||i&&0===a)&&(t.callback===e||void 0===e))});this.actionList=s},Im.prototype.preset=function(t){var e=this;this.clear(),(Cm[t]||[]).forEach(function(t){(i=e).add.apply(i,t);var i})},Im.prototype.clear=function(){this.actionList.length=0};var Lm=function(t){this.stage=t,this.mouse=t.mouseObserver,this.controls=t.mouseControls,this.mouse.signals.clicked.add(this._onClick,this),this.mouse.signals.hovered.add(this._onHover,this)};Lm.prototype._onClick=function(t,e){var i=this.stage.pickingControls.pick(t,e);this.stage.signals.clicked.dispatch(i),this.controls.run("clickPick",i)},Lm.prototype._onHover=function(t,e){var i=this.stage.pickingControls.pick(t,e);i&&this.mouse.down.equals(this.mouse.position)&&(this.stage.transformComponent=i.component),this.stage.signals.hovered.dispatch(i),this.controls.run("hoverPick",i)},Lm.prototype.dispose=function(){this.mouse.signals.clicked.remove(this._onClick,this),this.mouse.signals.hovered.remove(this._onHover,this)};var Rm=function(t){this.stage=t,this.mouse=t.mouseObserver,this.controls=t.mouseControls,this.mouse.signals.moved.add(this._onMove,this),this.mouse.signals.scrolled.add(this._onScroll,this),this.mouse.signals.dragged.add(this._onDrag,this),this.mouse.signals.clicked.add(this._onClick,this),this.mouse.signals.hovered.add(this._onHover,this)};Rm.prototype._onMove=function(){this.stage.tooltip.style.display="none"},Rm.prototype._onScroll=function(t){this.controls.run("scroll",t)},Rm.prototype._onDrag=function(t,e){this.controls.run("drag",t,e)},Rm.prototype._onClick=function(t,e){this.controls.run("click",t,e)},Rm.prototype._onHover=function(t,e){this.controls.run("hover",t,e)},Rm.prototype.dispose=function(){this.mouse.signals.moved.remove(this._onMove,this),this.mouse.signals.scrolled.remove(this._onScroll,this),this.mouse.signals.dragged.remove(this._onDrag,this),this.mouse.signals.clicked.remove(this._onClick,this),this.mouse.signals.hovered.remove(this._onHover,this)};var Om=function(t){this.viewer=t.viewer,this.animationControls=t.animationControls,this.viewer.signals.ticked.add(this._onTick,this)};Om.prototype._onTick=function(t){this.animationControls.run(t)},Om.prototype.dispose=function(){this.viewer.signals.ticked.remove(this._onTick,this)};var Dm=function(t,e,i,r){var n=r||{};this.offsetX=dn(n.offsetX,0),this.offsetY=dn(n.offsetY,0),this.visible=dn(n.visible,!0),this.component=t,this.stage=t.stage,this.viewer=this.stage.viewer,this.position=e,this._viewerPosition=new g,this._updateViewerPosition(),this._canvasPosition=new g,this._cameraPosition=new g,this.element=document.createElement("div"),Object.assign(this.element.style,{display:"block",position:"fixed",zIndex:1+(parseInt(this.viewer.container.style.zIndex)||0),pointerEvents:"none",backgroundColor:"rgba( 0, 0, 0, 0.6 )",color:"lightgrey",padding:"8px",fontFamily:"sans-serif",left:"-10000px"}),this.viewer.container.appendChild(this.element),this.setContent(i),this.updateVisibility(),this.viewer.signals.ticked.add(this._update,this),this.component.signals.matrixChanged.add(this._updateViewerPosition,this)};Dm.prototype.setContent=function(t){var e=this.element.style.display;"none"===e&&(this.element.style.left="-10000px",this.element.style.display="block"),t instanceof Element?(this.element.innerHTML="",this.element.appendChild(t)):this.element.innerHTML=t,this._clientRect=this.element.getBoundingClientRect(),"none"===e&&(this.element.style.display=e)},Dm.prototype.setVisibility=function(t){this.visible=t,this.updateVisibility()},Dm.prototype.getVisibility=function(){return this.visible&&this.component.visible},Dm.prototype.updateVisibility=function(){this.element.style.display=this.getVisibility()?"block":"none"},Dm.prototype._updateViewerPosition=function(){this._viewerPosition.copy(this.position).applyMatrix4(this.component.matrix)},Dm.prototype._update=function(){if(this.getVisibility()){var t=this.element.style,e=this._canvasPosition,i=this._viewerPosition,r=this._clientRect;if(this._cameraPosition.copy(i).add(this.viewer.translationGroup.position).applyMatrix4(this.viewer.rotationGroup.matrix).sub(this.viewer.camera.position),this._cameraPosition.z<0)return void(t.display="none");t.display="block",t.opacity=1-Qn(this.viewer.scene.fog.near,this.viewer.scene.fog.far,this._cameraPosition.length()),this.stage.viewerControls.getPositionOnCanvas(i,e),t.bottom=this.offsetX+e.y+r.height/2+"px",t.left=this.offsetY+e.x-r.width/2+"px"}},Dm.prototype.dispose=function(){this.viewer.container.removeChild(this.element),this.viewer.signals.ticked.remove(this._update,this),this.component.signals.matrixChanged.remove(this._updateViewerPosition,this)};var Nm=new v,km=new g,Bm=new m,Fm=function(t){this.component=t,this.stage=t.stage,this.viewer=t.stage.viewer,this.signals={changed:new io}},zm={position:{},rotation:{}};zm.position.get=function(){return this.component.position},zm.rotation.get=function(){return this.component.quaternion},Fm.prototype.changed=function(){this.component.updateMatrix(),this.viewer.requestRender(),this.signals.changed.dispatch()},Fm.prototype.spin=function(t,e){Nm.getInverse(this.viewer.rotationGroup.matrix),km.copy(On(t)).applyMatrix4(Nm),Nm.extractRotation(this.component.transform),Nm.premultiply(this.viewer.rotationGroup.matrix),Nm.getInverse(Nm),km.copy(On(t)),km.applyMatrix4(Nm),Nm.makeRotationAxis(km,e),Bm.setFromRotationMatrix(Nm),this.component.quaternion.premultiply(Bm),this.changed()},Object.defineProperties(Fm.prototype,zm),sa.__deps=[ca],ua.__deps=[ca,aa];var Um=function(t){this.array=t};Um.prototype.getIndex=function(t){return this.array?this.array[t]:t},Um.prototype.getObject=function(){return{}},Um.prototype._applyTransformations=function(t,e,i){return e&&t.applyMatrix4(e.matrix),i&&t.applyMatrix4(i.matrix),t},Um.prototype._getPosition=function(){return new g},Um.prototype.getPosition=function(t,e,i){return this._applyTransformations(this._getPosition(t),e,i)};var jm=function(t){function e(e){t.call(this),this.shape=e}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={data:{}};return i.data.get=function(){return this.shape},Object.defineProperties(e.prototype,i),e}(Um),Gm=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"cylinder"},e.prototype.getObject=function(t){var e=this.shape;return{shape:e,color:(new tt).fromArray(e.cylinderColor,3*t),radius:e.cylinderRadius[t],position1:(new g).fromArray(e.cylinderPosition1,3*t),position2:(new g).fromArray(e.cylinderPosition2,3*t),name:e.cylinderName[t]}},e.prototype._getPosition=function(t){var e=this.shape,i=(new g).fromArray(e.cylinderPosition1,3*t),r=(new g).fromArray(e.cylinderPosition2,3*t);return i.add(r).multiplyScalar(.5)},Object.defineProperties(e.prototype,i),e}(jm),Vm=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"arrow"},e.prototype.getObject=function(t){var e=this.shape;return{shape:e,position:this._getPosition(t),position1:(new g).fromArray(e.arrowPosition1,3*t),position2:(new g).fromArray(e.arrowPosition2,3*t),color:(new tt).fromArray(e.arrowColor,3*t),radius:e.arrowRadius[t],name:e.arrowName[t]}},e.prototype._getPosition=function(t){var e=this.shape,i=(new g).fromArray(e.arrowPosition1,3*t),r=(new g).fromArray(e.arrowPosition2,3*t);return i.add(r).multiplyScalar(.5)},Object.defineProperties(e.prototype,i),e}(jm),$m=function(t){function e(e,i){t.call(this,e),this.structure=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},data:{}};return i.type.get=function(){return"atom"},i.data.get=function(){return this.structure},e.prototype.getObject=function(t){return this.structure.getAtomProxy(this.getIndex(t))},e.prototype._getPosition=function(t){return(new g).copy(this.getObject(t))},Object.defineProperties(e.prototype,i),e}(Um),Hm=function(t){function e(e){t.call(this),this.axes=e}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},data:{}};return i.type.get=function(){return"axes"},i.data.get=function(){return this.axes},e.prototype.getObject=function(){return{axes:this.axes}},e.prototype._getPosition=function(){return this.axes.center.clone()},Object.defineProperties(e.prototype,i),e}(Um),Wm=function(t){function e(e,i,r){t.call(this,e),this.structure=i,this.bondStore=r||i.bondStore}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},data:{}};return i.type.get=function(){return"bond"},i.data.get=function(){return this.structure},e.prototype.getObject=function(t){var e=this.structure.getBondProxy(this.getIndex(t));return e.bondStore=this.bondStore,e},e.prototype._getPosition=function(t){var e=this.getObject(t);return(new g).copy(e.atom1).add(e.atom2).multiplyScalar(.5)},Object.defineProperties(e.prototype,i),e}(Um),Xm=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"contact"},Object.defineProperties(e.prototype,i),e}(Wm),qm=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"cone"},e.prototype.getObject=function(t){var e=this.shape;return{shape:e,position:this._getPosition(t),position1:(new g).fromArray(e.conePosition1,3*t),position2:(new g).fromArray(e.conePosition2,3*t),color:(new tt).fromArray(e.coneColor,3*t),radius:e.coneRadius[t],name:e.coneName[t]}},e.prototype._getPosition=function(t){var e=this.shape,i=(new g).fromArray(e.conePosition1,3*t),r=(new g).fromArray(e.conePosition2,3*t);return i.add(r).multiplyScalar(.5)},Object.defineProperties(e.prototype,i),e}(jm),Ym=function(t){function e(e,i,r){t.call(this,e),this.validation=i,this.structure=r}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},data:{}};return i.type.get=function(){return"clash"},i.data.get=function(){return this.validation},e.prototype.getObject=function(t){var e=this.validation,i=this.getIndex(t);return{validation:e,index:i,clash:e.clashArray[i]}},e.prototype._getAtomProxyFromSele=function(t){var e=new Kd(t),i=this.structure.getAtomIndices(e)[0];return this.structure.getAtomProxy(i)},e.prototype._getPosition=function(t){var e=this.getObject(t).clash,i=this._getAtomProxyFromSele(e.sele1),r=this._getAtomProxyFromSele(e.sele2);return(new g).copy(i).add(r).multiplyScalar(.5)},Object.defineProperties(e.prototype,i),e}(Um),Zm=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"distance"},Object.defineProperties(e.prototype,i),e}(Wm),Km=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"ellipsoid"},e.prototype.getObject=function(t){var e=this.shape;return{shape:e,position:this._getPosition(t),color:(new tt).fromArray(e.ellipsoidColor,3*t),radius:e.ellipsoidRadius[t],majorAxis:(new g).fromArray(e.ellipsoidMajorAxis,3*t),minorAxis:(new g).fromArray(e.ellipsoidMinorAxis,3*t),name:e.ellipsoidName[t]}},e.prototype._getPosition=function(t){return(new g).fromArray(this.shape.ellipsoidPosition,3*t)},Object.defineProperties(e.prototype,i),e}(jm),Qm=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"ignore"},Object.defineProperties(e.prototype,i),e}(Um),Jm=function(t){function e(e,i){t.call(this,e),this.mesh=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"mesh"},e.prototype.getObject=function(){var t=this.mesh;return{shape:this.shape,name:t.name,serial:t.serial}},e.prototype._getPosition=function(){return this.__position||(this.__position=Zo(this.mesh.position)),this.__position},Object.defineProperties(e.prototype,i),e}(jm),tg=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"sphere"},e.prototype.getObject=function(t){var e=this.shape;return{shape:e,position:this._getPosition(t),color:(new tt).fromArray(e.sphereColor,3*t),radius:e.sphereRadius[t],name:e.sphereName[t]}},e.prototype._getPosition=function(t){return(new g).fromArray(this.shape.spherePosition,3*t)},Object.defineProperties(e.prototype,i),e}(jm),eg=function(t){function e(e,i){t.call(this,e),this.surface=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},data:{}};return i.type.get=function(){return"surface"},i.data.get=function(){return this.surface},e.prototype.getObject=function(t){return{surface:this.surface,index:this.getIndex(t)}},e.prototype._getPosition=function(){return this.surface.center.clone()},Object.defineProperties(e.prototype,i),e}(Um),ig=function(t){function e(e,i){t.call(this),this.unitcell=e,this.structure=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},data:{}};return i.type.get=function(){return"unitcell"},i.data.get=function(){return this.unitcell},e.prototype.getObject=function(){return{unitcell:this.unitcell,structure:this.structure}},e.prototype._getPosition=function(){return this.unitcell.getCenter(this.structure)},Object.defineProperties(e.prototype,i),e}(Um),rg=(function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};i.type.get=function(){return"unknown"},Object.defineProperties(e.prototype,i)}(Um),function(t){function e(e,i){t.call(this,e),this.volume=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},data:{}};return i.type.get=function(){return"volume"},i.data.get=function(){return this.volume},e.prototype.getObject=function(t){var e=this.volume,i=this.getIndex(t);return{volume:e,index:i,value:e.data[i]}},e.prototype._getPosition=function(t){var e=this.volume.position,i=this.getIndex(t);return new g(e[3*i],e[3*i+1],e[3*i+2])},Object.defineProperties(e.prototype,i),e}(Um)),ng=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"slice"},Object.defineProperties(e.prototype,i),e}(rg),og=function(t,e){this.length=t,this._words=new Uint32Array(t+32>>>5),!0===e&&this.setAll()};og.prototype.get=function(t){return 0!=(this._words[t>>>5]&1<<t)},og.prototype.set=function(t){this._words[t>>>5]|=1<<t},og.prototype.clear=function(t){this._words[t>>>5]&=~(1<<t)},og.prototype.flip=function(t){this._words[t>>>5]^=1<<t},og.prototype._assignRange=function(t,e,i){for(var r=this._words,n=!0===i?4294967295:0,o=t>>>5,a=e>>>5,s=o;s<a;++s)r[s]=n;var c=o<<5,u=a<<5;if(!0===i)if(e-t<32)for(var h=t,l=e+1;h<l;++h)r[h>>>5]|=1<<h;else{for(var p=t,d=c;p<d;++p)r[p>>>5]|=1<<p;for(var f=u,m=e+1;f<m;++f)r[f>>>5]|=1<<f}else if(e-t<32)for(var g=t,v=e+1;g<v;++g)r[g>>>5]&=~(1<<g);else{for(var y=t,b=c;y<b;++y)r[y>>>5]&=~(1<<y);for(var x=u,_=e+1;x<_;++x)r[x>>>5]&=~(1<<x)}return this},og.prototype.setRange=function(t,e){return this._assignRange(t,e,!0)},og.prototype.clearRange=function(t,e){return this._assignRange(t,e,!1)},og.prototype.setBits=function(){for(var t=arguments,e=this._words,i=arguments.length,r=0;r<i;++r){var n=t[r];e[n>>>5]|=1<<n}return this},og.prototype.clearBits=function(){for(var t=arguments,e=this._words,i=arguments.length,r=0;r<i;++r){var n=t[r];e[n>>>5]&=~(1<<n)}return this},og.prototype.setAll=function(){return this._assignRange(0,this.length-1,!0)},og.prototype.clearAll=function(){return this._assignRange(0,this.length-1,!1)},og.prototype.flipAll=function(){for(var t=this._words.length,e=this._words,i=32-this.length%32,r=0;r<t-1;++r)e[r]=~e[r];return e[t-1]=~(e[t-1]<<i)>>>i,this},og.prototype._isRangeValue=function(t,e,i){for(var r=this._words,n=!0===i?4294967295:0,o=t>>>5,a=e>>>5,s=o;s<a;++s)if(r[s]!==n)return!1;if(e-t<32){for(var c=t,u=e+1;c<u;++c)if(!!(r[c>>>5]&1<<c)!==i)return!1}else{for(var h=a<<5,l=t,p=o<<5<<5;l<p;++l)if(!!(r[l>>>5]&1<<l)!==i)return!1;for(var d=h,f=e+1;d<f;++d)if(!!(r[d>>>5]&1<<d)!==i)return!1}return!0},og.prototype.isRangeSet=function(t,e){return this._isRangeValue(t,e,!0)},og.prototype.isRangeClear=function(t,e){return this._isRangeValue(t,e,!1)},og.prototype.isAllSet=function(){return this._isRangeValue(0,this.length-1,!0)},og.prototype.isAllClear=function(){return this._isRangeValue(0,this.length-1,!1)},og.prototype.isSet=function(){for(var t=arguments,e=this._words,i=arguments.length,r=0;r<i;++r){var n=t[r];if(0==(e[n>>>5]&1<<n))return!1}return!0},og.prototype.isClear=function(){for(var t=arguments,e=this._words,i=arguments.length,r=0;r<i;++r){var n=t[r];if(0!=(e[n>>>5]&1<<n))return!1}return!0},og.prototype.isEqualTo=function(t){for(var e=this._words,i=t._words,r=Math.min(e.length,i.length),n=0;n<r;++n)if(e[n]!==i[n])return!1;return!0},og.prototype.getSize=function(){for(var t=this._words.length,e=this._words,i=0,r=0;r<t;++r)i+=ma(e[r]);return i},og.prototype.difference=function(t){for(var e=this._words,i=t._words,r=Math.min(e.length,i.length),n=0;n<r;++n)e[n]=e[n]&~i[n];for(var o=e.length;o<r;++o)e[o]=0;return this},og.prototype.union=function(t){for(var e=this._words,i=t._words,r=Math.min(e.length,i.length),n=0;n<r;++n)e[n]|=i[n];for(var o=e.length;o<r;++o)e[o]=0;return this},og.prototype.intersection=function(t){for(var e=this._words,i=t._words,r=Math.min(e.length,i.length),n=0;n<r;++n)e[n]&=i[n];for(var o=e.length;o<r;++o)e[o]=0;return this},og.prototype.intersects=function(t){for(var e=this._words,i=t._words,r=Math.min(e.length,i.length),n=0;n<r;++n)if(0!=(e[n]&i[n]))return!0;return!1},og.prototype.getIntersectionSize=function(t){for(var e=this._words,i=t._words,r=Math.min(e.length,i.length),n=0,o=0;o<r;++o)n+=ma(e[o]&i[o]);return n},og.prototype.makeIntersection=function(t){var e=this._words,i=t._words,r=Math.min(e.length,i.length),n=new Uint32Array(r),o=Object.create(og.prototype);o._words=n,o.length=Math.min(this.length,t.length);for(var a=0;a<r;++a)n[a]=e[a]&i[a];return o},og.prototype.forEach=function(t){for(var e=this._words.length,i=this._words,r=0,n=0;n<e;++n)for(var o=i[n];0!==o;){var a=o&-o;t((n<<5)+ma(a-1),r),o^=a,++r}},og.prototype.toArray=function(){for(var t=this._words,e=new Array(this.getSize()),i=this._words.length,r=0,n=0;n<i;++n)for(var o=t[n];0!==o;){var a=o&-o;e[r++]=(n<<5)+ma(a-1),o^=a}return e},og.prototype.toString=function(){return"{"+this.toArray().join(",")+"}"},og.prototype.toSeleString=function(){var t=this.toArray().join(",");return t?"@"+t:"NONE"},og.prototype.clone=function(){var t=Object.create(og.prototype);return t.length=this.length,t._words=new Uint32Array(this._words),t};var ag=0,sg=1,cg=2,ug=3,hg=4,lg=0,pg=["D-BETA-PEPTIDE, C-GAMMA LINKING","D-GAMMA-PEPTIDE, C-DELTA LINKING","D-PEPTIDE COOH CARBOXY TERMINUS","D-PEPTIDE NH3 AMINO TERMINUS","D-PEPTIDE LINKING","L-BETA-PEPTIDE, C-GAMMA LINKING","L-GAMMA-PEPTIDE, C-DELTA LINKING","L-PEPTIDE COOH CARBOXY TERMINUS","L-PEPTIDE NH3 AMINO TERMINUS","L-PEPTIDE LINKING","PEPTIDE LINKING","PEPTIDE-LIKE"],dg=["RNA OH 3 PRIME TERMINUS","RNA OH 5 PRIME TERMINUS","RNA LINKING"],fg=["DNA OH 3 PRIME TERMINUS","DNA OH 5 PRIME TERMINUS","DNA LINKING","L-DNA LINKING","L-RNA LINKING"],mg=["D-SACCHARIDE","D-SACCHARIDE 1,4 AND 1,4 LINKING","D-SACCHARIDE 1,4 AND 1,6 LINKING","L-SACCHARIDE","L-SACCHARIDE 1,4 AND 1,4 LINKING","L-SACCHARIDE 1,4 AND 1,6 LINKING","SACCHARIDE"],gg=["OTHER"],vg=["NON-POLYMER"].concat(gg,mg),yg=["h","g","i"],bg=["e","b"],xg=["s","t","l",""],_g={H:1.1,HE:1.4,LI:1.81,BE:1.53,B:1.92,C:1.7,N:1.55,O:1.52,F:1.47,NE:1.54,NA:2.27,MG:1.73,AL:1.84,SI:2.1,P:1.8,S:1.8,CL:1.75,AR:1.88,K:2.75,CA:2.31,SC:2.3,TI:2.15,V:2.05,CR:2.05,MN:2.05,FE:2.05,CO:2,NI:2,CU:2,ZN:2.1,GA:1.87,GE:2.11,AS:1.85,SE:1.9,BR:1.83,KR:2.02,RB:3.03,SR:2.49,Y:2.4,ZR:2.3,NB:2.15,MO:2.1,TC:2.05,RU:2.05,RH:2,PD:2.05,AG:2.1,CD:2.2,IN:2.2,SN:1.93,SB:2.17,TE:2.06,I:1.98,XE:2.16,CS:3.43,BA:2.68,LA:2.5,CE:2.48,PR:2.47,ND:2.45,PM:2.43,SM:2.42,EU:2.4,GD:2.38,TB:2.37,DY:2.35,HO:2.33,ER:2.32,TM:2.3,YB:2.28,LU:2.27,HF:2.25,TA:2.2,W:2.1,RE:2.05,OS:2,IR:2,PT:2.05,AU:2.1,HG:2.05,TL:1.96,PB:2.02,BI:2.07,PO:1.97,AT:2.02,RN:2.2,FR:3.48,RA:2.83,AC:2,TH:2.4,PA:2,U:2.3,NP:2,PU:2,AM:2,CM:2,BK:2,CF:2,ES:2,FM:2,MD:2,NO:2,LR:2,RF:2,DB:2,SG:2,BH:2,HS:2,MT:2,DS:2,RG:2,CN:2,UUT:2,FL:2,UUP:2,LV:2,UUH:2},wg={H:.31,HE:.28,LI:1.28,BE:.96,B:.84,C:.76,N:.71,O:.66,F:.57,NE:.58,NA:1.66,MG:1.41,AL:1.21,SI:1.11,P:1.07,S:1.05,CL:1.02,AR:1.06,K:2.03,CA:1.76,SC:1.7,TI:1.6,V:1.53,CR:1.39,MN:1.39,FE:1.32,CO:1.26,NI:1.24,CU:1.32,ZN:1.22,GA:1.22,GE:1.2,AS:1.19,SE:1.2,BR:1.2,KR:1.16,RB:2.2,SR:1.95,Y:1.9,ZR:1.75,NB:1.64,MO:1.54,TC:1.47,RU:1.46,RH:1.42,PD:1.39,AG:1.45,CD:1.44,IN:1.42,SN:1.39,SB:1.39,TE:1.38,I:1.39,XE:1.4,CS:2.44,BA:2.15,LA:2.07,CE:2.04,PR:2.03,ND:2.01,PM:1.99,SM:1.98,EU:1.98,GD:1.96,TB:1.94,DY:1.92,HO:1.92,ER:1.89,TM:1.9,YB:1.87,LU:1.87,HF:1.75,TA:1.7,W:1.62,RE:1.51,OS:1.44,IR:1.41,PT:1.36,AU:1.36,HG:1.32,TL:1.45,PB:1.46,BI:1.48,PO:1.4,AT:1.5,RN:1.5,FR:2.6,RA:2.21,AC:2.15,TH:2.06,PA:2,U:1.96,NP:1.9,PU:1.87,AM:1.8,CM:1.69,BK:1.6,CF:1.6,ES:1.6,FM:1.6,MD:1.6,NO:1.6,LR:1.6,RF:1.6,DB:1.6,SG:1.6,BH:1.6,HS:1.6,MT:1.6,DS:1.6,RG:1.6,CN:1.6,UUT:1.6,FL:1.6,UUP:1.6,LV:1.6,UUH:1.6},Sg={ALA:[.17,.5,.33],ARG:[.81,1.81,1],ASN:[.42,.85,.43],ASP:[1.23,3.64,2.41],ASH:[-.07,.43,.5],CYS:[-.24,-.02,.22],GLN:[.58,.77,.19],GLU:[2.02,3.63,1.61],GLH:[-.01,.11,.12],GLY:[.01,1.15,1.14],HIS:[.17,.11,-.06],ILE:[-.31,-1.12,-.81],LEU:[-.56,-1.25,-.69],LYS:[.99,2.8,1.81],MET:[-.23,-.67,-.44],PHE:[-1.13,-1.71,-.58],PRO:[.45,.14,-.31],SER:[.13,.46,.33],THR:[.14,.25,.11],TRP:[-1.85,-2.09,-.24],TYR:[-.94,-.71,.23],VAL:[.07,-.46,-.53]},Ag=[0,0,0],Mg={HIS:"H",ARG:"R",LYS:"K",ILE:"I",PHE:"F",LEU:"L",TRP:"W",ALA:"A",MET:"M",PRO:"P",CYS:"C",ASN:"N",VAL:"V",GLY:"G",SER:"S",GLN:"Q",TYR:"Y",ASP:"D",GLU:"E",THR:"T",ASH:"D",GLH:"E",UNK:""},Pg=Object.keys(Mg),Tg=["A","C","T","G","U"],Eg=["DA","DC","DT","DG","DU","TCY","MCY","5CM"],Cg=["A","G","DA","DG"],Ig=["SOL","WAT","HOH","H2O","W","DOD","D3O","TIP3","TIP4"],Lg=["118","119","1AL","1CU","2FK","2HP","2OF","3CO","3MT","3NI","3OF","3P8","4MO","4PU","543","6MO","ACT","AG","AL","ALF","AM","ATH","AU","AU3","AUC","AZI","BA","BCT","BEF","BF4","BO4","BR","BS3","BSY","CA","CAC","CD","CD1","CD3","CD5","CE","CHT","CL","CO","CO3","CO5","CON","CR","CS","CSB","CU","CU1","CU3","CUA","CUZ","CYN","DME","DMI","DSC","DTI","DY","E4N","EDR","EMC","ER3","EU","EU3","F","FE","FE2","FPO","GA","GD3","GEP","HAI","HG","HGC","IN","IOD","IR","IR3","IRI","IUM","K","KO4","LA","LCO","LCP","LI","LU","MAC","MG","MH2","MH3","MLI","MLT","MMC","MN","MN3","MN5","MN6","MO1","MO2","MO3","MO4","MO5","MO6","MOO","MOS","MOW","MW1","MW2","MW3","NA","NA2","NA5","NA6","NAO","NAW","NCO","NET","NH4","NI","NI1","NI2","NI3","NO2","NO3","NRU","O4M","OAA","OC1","OC2","OC3","OC4","OC5","OC6","OC7","OC8","OCL","OCM","OCN","OCO","OF1","OF2","OF3","OH","OS","OS4","OXL","PB","PBM","PD","PDV","PER","PI","PO3","PO4","PR","PT","PT4","PTN","RB","RH3","RHD","RU","SB","SCN","SE4","SEK","SM","SMO","SO3","SO4","SR","T1A","TB","TBA","TCN","TEA","TH","THE","TL","TMA","TRA","UNX","V","VN3","VO4","W","WO5","Y1","YB","YB2","YH","YT3","ZCM","ZN","ZN2","ZN3","ZNO","ZO3","OHX"],Rg=["045","0AT","0BD","0MK","0NZ","0TS","0V4","0XY","0YT","10M","147","149","14T","15L","16G","18T","18Y","1AR","1BW","1GL","1GN","1JB","1LL","1NA","1S3","26M","26Q","26R","26V","26W","26Y","27C","289","291","293","2DG","2F8","2FG","2FL","2FP","2GL","2M4","2M5","32O","34V","3CM","3DO","3DY","3FM","3LR","3MF","3MG","3SA","3ZW","46D","46M","46Z","48Z","4CQ","4GC","4NN","50A","5DI","5GF","5MM","5RP","5SA","5SP","64K","6PG","6SA","7JZ","7SA","A1Q","A2G","AAB","AAL","AAO","ABC","ABD","ABE","ABF","ABL","ACG","ACI","ACR","ACX","ADA","ADG","ADR","AF1","AFD","AFL","AFO","AFP","AFR","AGC","AGH","AGL","AHR","AIG","ALL","ALX","AMU","AOG","AOS","ARA","ARB","ARE","ARI","ASG","ASO","AXP","AXR","B0D","B16","B2G","B4G","B6D","B8D","B9D","BBK","BCD","BDG","BDP","BDR","BEM","BFP","BGC","BGL","BGP","BGS","BHG","BMA","BMX","BNG","BNX","BOG","BRI","BXF","BXP","BXX","BXY","C3X","C4X","C5X","CAP","CBI","CBK","CBS","CDR","CEG","CGF","CHO","CR1","CR6","CRA","CT3","CTO","CTR","CTT","D6G","DAF","DAG","DDA","DDB","DDL","DEL","DFR","DFX","DG0","DGC","DGD","DGM","DGS","DIG","DLF","DLG","DMU","DNO","DOM","DP5","DQQ","DQR","DR2","DR3","DR4","DRI","DSR","DT6","DVC","E4P","E5G","EAG","EBG","EBQ","EGA","EJT","EPG","ERE","ERI","F1P","F1X","F6P","FBP","FCA","FCB","FCT","FDP","FDQ","FFC","FIX","FMO","FRU","FSI","FU4","FUB","FUC","FUD","FUL","FXP","G16","G1P","G2F","G3I","G4D","G4S","G6D","G6P","G6S","GAC","GAD","GAL","GC1","GC4","GCD","GCN","GCO","GCS","GCT","GCU","GCV","GCW","GCX","GE1","GFG","GFP","GIV","GL0","GL2","GL5","GL6","GL7","GL9","GLA","GLB","GLC","GLD","GLF","GLG","GLO","GLP","GLS","GLT","GLW","GMH","GN1","GNX","GP1","GP4","GPH","GPM","GQ1","GQ2","GQ4","GS1","GS4","GSA","GSD","GTE","GTH","GTK","GTR","GTZ","GU0","GU1","GU2","GU3","GU4","GU5","GU6","GU8","GU9","GUF","GUP","GUZ","GYP","GYV","H2P","HDL","HMS","HS2","HSD","HSG","HSH","HSJ","HSQ","HSR","HSU","HSX","HSY","HSZ","IAB","IDG","IDR","IDS","IDT","IDU","IDX","IDY","IMK","IN1","IPT","ISL","KBG","KD2","KDA","KDM","KDO","KFN","KO1","KO2","KTU","L6S","LAG","LAI","LAK","LAO","LAT","LB2","LBT","LCN","LDY","LGC","LGU","LM2","LMT","LMU","LOG","LOX","LPK","LSM","LTM","LVZ","LXB","LXZ","M1F","M3M","M6P","M8C","MA1","MA2","MA3","MAB","MAG","MAL","MAN","MAT","MAV","MAW","MBG","MCU","MDA","MDM","MDP","MFA","MFB","MFU","MG5","MGA","MGL","MLB","MMA","MMN","MN0","MRP","MTT","MUG","MVP","MXY","N1L","N9S","NAA","NAG","NBG","NDG","NED","NG1","NG6","NGA","NGB","NGC","NGE","NGF","NGL","NGS","NGY","NHF","NM6","NM9","NTF","NTO","NTP","NXD","NYT","OPG","OPM","ORP","OX2","P3M","P53","P6P","PA5","PNA","PNG","PNW","PRP","PSJ","PSV","PTQ","QDK","QPS","QV4","R1P","R1X","R2B","R5P","RAA","RAE","RAF","RAM","RAO","RAT","RB5","RBL","RCD","RDP","REL","RER","RF5","RG1","RGG","RHA","RIB","RIP","RNS","RNT","ROB","ROR","RPA","RST","RUB","RUU","RZM","S6P","S7P","SA0","SCR","SDD","SF6","SF9","SG4","SG5","SG6","SG7","SGA","SGC","SGD","SGN","SGS","SHB","SHG","SI3","SIO","SOE","SOL","SSG","SUC","SUP","SUS","T6P","T6T","TAG","TCB","TDG","TGK","TGY","TH1","TIA","TM5","TM6","TM9","TMR","TMX","TOA","TOC","TRE","TYV","UCD","UDC","VG1","X0X","X1X","X2F","X4S","X5S","X6X","XBP","XDN","XDP","XIF","XIM","XLF","XLS","XMM","XUL","XXR","XYP","XYS","YO5","Z3Q","Z6J","Z9M","ZDC","ZDM"],Og=["CA","C","N","O","O1","O2","OC1","OC2","OX1","OXT","H","H1","H2","H3","HA","BB"],Dg=["P","O3'","O5'","C5'","C4'","C3'","OP1","OP2","O3*","O5*","C5*","C4*","C3*"],Ng={};Ng[1]={trace:"CA",direction1:"C",direction2:["O","OC1","O1","OX1","OXT"],backboneStart:"N",backboneEnd:"C"},Ng[2]={trace:["C4'","C4*"],direction1:["C1'","C1*"],direction2:["C3'","C3*"],backboneStart:"P",backboneEnd:["O3'","O3*"]},Ng[3]={trace:["C3'","C3*"],direction1:["C2'","C2*"],direction2:["O4'","O4*"],backboneStart:"P",backboneEnd:["O3'","O3*"]},Ng[4]={trace:["CA","BB"],backboneStart:["CA","BB"],backboneEnd:["CA","BB"]},Ng[5]={trace:["C4'","C4*","P"],backboneStart:["C4'","C4*","P"],backboneEnd:["C4'","C4*","P"]},Ng[6]={trace:["C3'","C3*","C2'","P"],backboneStart:["C3'","C3*","C2'","P"],backboneEnd:["C3'","C3*","C2'","P"]},Ng[lg]={},ga.prototype={constructor:ga,atomRadius:function(t){var e,i=this.type,r=this.scale;switch(i){case"vdw":e=_g[t.element]||2;break;case"covalent":e=wg[t.element]||1.6;break;case"bfactor":e=t.bfactor||1;break;case"sstruc":var n=t.sstruc;e="h"===n?.25:"g"===n?.25:"i"===n?.25:"e"===n?.25:"b"===n?.25:Dg.includes(t.atomname)?.4:.1;break;default:e=i||1}return Math.min(e*r,this.max)}},ga.types={"":"",vdw:"by vdW radius",covalent:"by covalent radius",sstruc:"by secondary structure",bfactor:"by bfactor",size:"size"},va.prototype={copyTo:function(t){t.data.set(this.data)}};var kg=1.192092896e-7,Bg=1e-37;Oa.__deps=[La],Da.__deps=[La],Na.__deps=[La],Ba.__deps=[ia,ra];var Fg=new g(-1,-1,-1),zg=new v,Ug=function(t){var e=t.rows,i=e/3,r=new va(e,3),n=new va(3,3),o=new va(1,3),a=new va(3,3),s=new va(3,3),c=Sa(t);Aa(t,c),ya(r,t),ba(n,r,r),Ca(n,o,a,s);var u=new g(c[0],c[1],c[2]),h=new g(a.data[0],a.data[3],a.data[6]),l=new g(a.data[1],a.data[4],a.data[7]),p=new g(a.data[2],a.data[5],a.data[8]),d=h.clone().multiplyScalar(Math.sqrt(o.data[0]/i)),f=l.clone().multiplyScalar(Math.sqrt(o.data[1]/i)),m=p.clone().multiplyScalar(Math.sqrt(o.data[2]/i));this.begA=u.clone().sub(d),this.endA=u.clone().add(d),this.begB=u.clone().sub(f),this.endB=u.clone().add(f),this.begC=u.clone().sub(m),this.endC=u.clone().add(m),this.center=u,this.vecA=d,this.vecB=f,this.vecC=m,this.normVecA=h,this.normVecB=l,this.normVecC=p};Ug.prototype.getBasisMatrix=function(t){var e=t||new v;return e.makeBasis(this.normVecB,this.normVecA,this.normVecC),e.determinant()<0&&e.scale(Fg),e},Ug.prototype.getRotationQuaternion=function(t){var e=t||new m;return e.setFromRotationMatrix(this.getBasisMatrix(zg)),e.inverse()},Ug.prototype.getProjectedScaleForAtoms=function(t){var e=-1/0,i=-1/0,r=-1/0,n=-1/0,o=-1/0,a=-1/0,s=new g,c=new g,u=this.center,h=this.normVecA,l=this.normVecB,p=this.normVecC;return t.eachAtom(function(t){Ko(s.copy(t),h,u);var d=c.subVectors(s,u).normalize().dot(h),f=s.distanceTo(u);d>0?f>e&&(e=f):f>i&&(i=f),Ko(s.copy(t),l,u);var m=c.subVectors(s,u).normalize().dot(l),g=s.distanceTo(u);m>0?g>r&&(r=g):g>n&&(n=g),Ko(s.copy(t),p,u);var v=c.subVectors(s,u).normalize().dot(p),y=s.distanceTo(u);v>0?y>o&&(o=y):y>a&&(a=y)}),{d1a:e,d2a:r,d3a:o,d1b:-i,d2b:-n,d3b:-a}},za.prototype.constructor=za,Ua.prototype.constructor=Ua,$a.__deps=[ja,Ga,Va,Cn],Ha.__deps=[Wa],Wa.__deps=[na,ra,oa,ea],qa.__deps=[Gn,ha,la,sa,ca,pa,da,na,fa,Ia,Ra,Da,Oa,Na];var jg=function(t,e,i){this.name=t||"",this.path=e||"",this.info={},this.center=new g,this.boundingBox=new st,i instanceof Et||i instanceof Ct||i instanceof Re?this.fromGeometry(i):i&&(this.set(i.position,i.index,i.normal,i.color,i.atomindex,i.contour),this.boundingBox.setFromArray(i.position),this.boundingBox.getCenter(this.center))},Gg={type:{}};Gg.type.get=function(){return"Surface"},jg.prototype.set=function(t,e,i,r,n,o){this.position=t,this.index=e,this.normal=i,this.color=r,this.atomindex=n,this.size=t.length/3,this.contour=o},jg.prototype.fromGeometry=function(e){t.Debug&&cf.time("GeometrySurface.fromGeometry");var i;e instanceof Et?(e.computeVertexNormals(!0),i=(new Ct).fromGeometry(e)):i=e instanceof Ct?e:e[0],i.boundingBox||i.computeBoundingBox(),this.boundingBox.copy(i.boundingBox),this.boundingBox.getCenter(this.center);var r,n,o;if(i instanceof Ct){var a=i.attributes,s=!!a.normal&&a.normal.array;(!s||0===s[0]&&0===s[1]&&0===s[2])&&i.computeVertexNormals(),r=a.position.array,n=a.index?a.index.array:null,o=a.normal.array}this.set(r,n,o,void 0,void 0),t.Debug&&cf.timeEnd("GeometrySurface.setGeometry")},jg.prototype.getPosition=function(){return this.position},jg.prototype.getColor=function(t){var e=t||{};e.surface=this;var i=this.size,r=new Float32Array(3*i),n=lf.getScheme(e);if(n.volumeColor||"random"===e.scheme)for(var o=0;o<i;++o)n.volumeColorToArray(o,r,3*o);else if(n.positionColor)for(var a=new g,s=this.position,c=0;c<i;++c){var u=3*c;a.set(s[u],s[u+1],s[u+2]),n.positionColorToArray(a,r,u)}else if(n.atomColor&&this.atomindex)for(var h=e.structure.getAtomProxy(),l=this.atomindex,p=0;p<i;++p)h.index=l[p],n.atomColorToArray(h,r,3*p);else{var d=new tt(e.value);To(i,d.r,d.g,d.b,r)}return r},jg.prototype.getPicking=function(t){return this.atomindex&&t?new $m(this.atomindex,t):new eg(Co(this.size),this)},jg.prototype.getNormal=function(){return this.normal},jg.prototype.getSize=function(t,e){return Po(this.size,t*e)},jg.prototype.getIndex=function(){return this.index},jg.prototype.getFilteredIndex=function(t,e){if(t&&this.atomindex){for(var i=new Kd(t),r=e.getAtomSet(i),n=[],o=this.atomindex,a=this.index,s=a.length,c=this.contour?2:3,u=0,h=0;h<s;h+=c){for(var l=!0,p=0;p<c;p++){var d=o[a[h+p]];if(!r.get(d)){l=!1;break}}if(l)for(var f=0;f<c;f++,u++)n[u]=a[h+f]}return Cn(n,this.position.length/3)}return this.index},jg.prototype.getAtomindex=function(){return this.atomindex},jg.prototype.dispose=function(){},Object.defineProperties(jg.prototype,Gg),Ya.__deps=[Ha,Wa,$a,Jo,ta,ka,Ba],hf.add("surf",function(t,e){var i=t.data.args,r=t.data.params;if(i&&(self.volsurf=new Ya(i[0],i[1],i[2],i[3],i[4])),r){var n=self.volsurf.getSurface(r.isolevel,r.smooth,r.box,r.matrix,r.contour,r.wrap),o=[n.position.buffer,n.index.buffer];n.normal&&o.push(n.normal.buffer),n.atomindex&&o.push(n.atomindex.buffer),e({sd:n,p:r},o)}},[Ya]);var Vg=function(t,e,i,r,n,o,a){this.name=t,this.path=e,this.matrix=new v,this.normalMatrix=new ut,this.inverseMatrix=new v,this.center=new g,this.boundingBox=new st,this.setData(i,r,n,o,a)},$g={type:{},position:{},min:{},max:{},sum:{},mean:{},rms:{}};$g.type.get=function(){return"Volume"},Vg.prototype.setData=function(t,e,i,r,n){this.nx=e||1,this.ny=i||1,this.nz=r||1,this.data=t||new Float32Array(1),this.setAtomindex(n),delete this._position,delete this._min,delete this._max,delete this._mean,delete this._rms,this.worker&&this.worker.terminate()},Vg.prototype.setMatrix=function(t){this.matrix.copy(t);var e=this.boundingBox,i=this.center,r=this.nx-1,n=this.ny-1,o=this.nz-1;e.makeEmpty(),e.expandByPoint(i.set(r,n,o)),e.expandByPoint(i.set(r,n,0)),e.expandByPoint(i.set(r,0,o)),e.expandByPoint(i.set(r,0,0)),e.expandByPoint(i.set(0,n,o)),e.expandByPoint(i.set(0,0,o)),e.expandByPoint(i.set(0,n,0)),e.expandByPoint(i.set(0,0,0)),e.applyMatrix4(this.matrix),e.getCenter(this.center);var a=this.matrix.elements,s=new g(a[0],a[1],a[2]),c=new g(a[4],a[5],a[6]),u=new g(a[8],a[9],a[10]),h=new g,l=this.normalMatrix.elements;h.crossVectors(c,u),l[0]=h.x,l[1]=h.y,l[2]=h.z,h.crossVectors(u,s),l[3]=h.x,l[4]=h.y,l[5]=h.z,h.crossVectors(s,c),l[6]=h.x,l[7]=h.y,l[8]=h.z,this.inverseMatrix.getInverse(this.matrix)},Vg.prototype.setAtomindex=function(t){this.atomindex=t},Vg.prototype.getBox=function(t,e,i){return i||(i=new st),i.set(t,t),i.expandByScalar(e),i.applyMatrix4(this.inverseMatrix),i.min.round(),i.max.round(),i},Vg.prototype._getBox=function(t,e){if(t&&e){this.__box||(this.__box=new st);var i=this.getBox(t,e,this.__box);return[i.min.toArray(),i.max.toArray()]}},Vg.prototype._makeSurface=function(t,e,i){var r=this.name+"@"+e.toPrecision(2),n=new jg(r,"",t);return n.info.isolevel=e,n.info.smooth=i,n.info.volume=this,n},Vg.prototype.getSurface=function(t,e,i,r,n,o){t=isNaN(t)?this.getValueForSigma(2):t,e=dn(e,0),void 0===this.volsurf&&(this.volsurf=new Ya(this.data,this.nx,this.ny,this.nz,this.atomindex));var a=this._getBox(i,r),s=this.volsurf.getSurface(t,e,a,this.matrix.elements,n,o);return this._makeSurface(s,t,e)},Vg.prototype.getSurfaceWorker=function(t,e,i,r,n,o,a){var s=this;if(t=isNaN(t)?this.getValueForSigma(2):t,e=e||0,window.Worker){void 0===this.workerPool&&(this.workerPool=new Ua("surf",2));var c={},u=this.workerPool.getNextWorker();0===u.postCount&&(c.args=[this.data,this.nx,this.ny,this.nz,this.atomindex]),c.params={isolevel:t,smooth:e,box:this._getBox(i,r),matrix:this.matrix.elements,contour:n,wrap:o},u.post(c,void 0,function(t){var e=t.data.sd,i=t.data.p;a(s._makeSurface(e,i.isolevel,i.smooth))},function(c){console.warn("Volume.getSurfaceWorker error - trying without worker",c);var u=s.getSurface(t,e,i,r,n,o);a(u)})}else{var h=this.getSurface(t,e,i,r,n,o);a(h)}},Vg.prototype.getValueForSigma=function(t){return this.mean+dn(t,2)*this.rms},Vg.prototype.getSigmaForValue=function(t){return(dn(t,0)-this.mean)/this.rms},$g.position.get=function(){if(!this._position){for(var t=this.nz,e=this.ny,i=this.nx,r=new Float32Array(i*e*t*3),n=0,o=0;o<t;++o)for(var a=0;a<e;++a)for(var s=0;s<i;++s)r[n+0]=s,r[n+1]=a,r[n+2]=o,n+=3;Jo(this.matrix.elements,r),this._position=r}return this._position},Vg.prototype.getDataAtomindex=function(){return this.atomindex},Vg.prototype.getDataPosition=function(){return this.position},Vg.prototype.getDataColor=function(t){var e=t||{};e.volume=this,e.scale=e.scale||"Spectral",e.domain=e.domain||[this.min,this.max];for(var i=lf.getScheme(e),r=this.position.length/3,n=new Float32Array(3*r),o=0;o<r;++o)i.volumeColorToArray(o,n,3*o);return n},Vg.prototype.getDataPicking=function(){var t=Co(this.position.length/3);return new rg(t,this)},Vg.prototype.getDataSize=function(t,e){var i,r=this.data,n=this.position.length/3;switch(t){case"value":i=new Float32Array(r);break;case"abs-value":i=new Float32Array(r);for(var o=0;o<n;++o)i[o]=Math.abs(i[o]);break;case"value-min":i=new Float32Array(r);for(var a=this.min,s=0;s<n;++s)i[s]-=a;break;case"deviation":i=new Float32Array(r);break;default:i=Po(n,t)}if(1!==e)for(var c=0;c<n;++c)i[c]*=e;return i},$g.min.get=function(){return void 0===this._min&&(this._min=ko(this.data)),this._min},$g.max.get=function(){return void 0===this._max&&(this._max=No(this.data)),this._max},$g.sum.get=function(){return void 0===this._sum&&(this._sum=Bo(this.data)),this._sum},$g.mean.get=function(){return void 0===this._mean&&(this._mean=Fo(this.data)),this._mean},$g.rms.get=function(){return void 0===this._rms&&(this._rms=zo(this.data)),this._rms},Vg.prototype.clone=function(){var t=new Vg(this.name,this.path,this.data,this.nx,this.ny,this.nz,this.atomindex);return t.matrix.copy(this.matrix),t.header=Object.assign({},this.header),t},Vg.prototype.dispose=function(){this.workerPool&&this.workerPool.terminate()},Object.defineProperties(Vg.prototype,$g);var Hg=function(t,e,i,r){this.volume=t,this.setFilter(e,i,r)},Wg={header:{},matrix:{},normalMatrix:{},inverseMatrix:{},center:{},boundingBox:{},min:{},max:{},mean:{},rms:{}};Wg.header.get=function(){return this.volume.header},Wg.matrix.get=function(){return this.volume.matrix},Wg.normalMatrix.get=function(){return this.volume.normalMatrix},Wg.inverseMatrix.get=function(){return this.volume.inverseMatrix},Wg.center.get=function(){return this.volume.center},Wg.boundingBox.get=function(){return this.volume.boundingBox},Wg.min.get=function(){return this.volume.min},Wg.max.get=function(){return this.volume.max},Wg.mean.get=function(){return this.volume.mean},Wg.rms.get=function(){return this.volume.rms},Hg.prototype._getFilterHash=function(t,e,i){return JSON.stringify([t,e,i])},Hg.prototype.setFilter=function(t,e,i){isNaN(t)&&this.header&&(t=this.header.DMEAN+2*this.header.ARMS),t=void 0===t||isNaN(t)?-1/0:t,e=dn(e,1/0),i=dn(i,!1);var r=this.volume.data,n=this.volume.position,o=this.volume.atomindex,a=this._getFilterHash(t,e,i);if(a!==this._filterHash){if(t===-1/0&&e===1/0)this.data=r,this.position=n,this.atomindex=o;else{var s=r.length;this._dataBuffer||(this._dataBuffer=new ArrayBuffer(4*s),this._positionBuffer=new ArrayBuffer(3*s*4),o&&(this._atomindexBuffer=new ArrayBuffer(4*s)));var c,u=new Float32Array(this._dataBuffer),h=new Float32Array(this._positionBuffer);o&&(c=new Uint32Array(this._atomindexBuffer));for(var l=0,p=0;p<s;++p){var d=3*p,f=r[p];if(!i&&f>=t&&f<=e||i&&(f<t||f>e)){var m=3*l;u[l]=f,h[m+0]=n[d+0],h[m+1]=n[d+1],h[m+2]=n[d+2],o&&(c[l]=o[p]),l+=1}}this.data=new Float32Array(this._dataBuffer,0,l),this.position=new Float32Array(this._positionBuffer,0,3*l),o&&(this.atomindex=new Float32Array(this._atomindexBuffer,0,l))}this._filterHash=a}},Object.defineProperties(Hg.prototype,Wg),Hg.prototype.getValueForSigma=Vg.prototype.getValueForSigma,Hg.prototype.getSigmaForValue=Vg.prototype.getSigmaForValue,Hg.prototype.getDataAtomindex=Vg.prototype.getDataAtomindex,Hg.prototype.getDataPosition=Vg.prototype.getDataPosition,Hg.prototype.getDataColor=Vg.prototype.getDataColor,Hg.prototype.getDataPicking=Vg.prototype.getDataPicking,Hg.prototype.getDataSize=Vg.prototype.getDataSize;var Xg=function(e,i){t.Debug&&cf.time("BondHash init");for(var r=e.count,n=e.atomIndex1,o=e.atomIndex2,a=new Uint8Array(i),s=new Int32Array(i),c=0;c<r;++c)a[n[c]]+=1,a[o[c]]+=1;for(var u=1;u<i;++u)s[u]+=s[u-1]+a[u-1];for(var h=2*r,l=new Int32Array(h),p=0;p<h;++p)l[p]=-1;for(var d=0;d<r;++d){for(var f=n[d],m=o[d],g=s[f];-1!==l[g];)g+=1;l[g]=d;for(var v=s[m];-1!==l[v];)v+=1;l[v]=d}t.Debug&&cf.timeEnd("BondHash init"),this.countArray=a,this.offsetArray=s,this.indexArray=l},qg=function(t){Number.isInteger(t)?this.init(t):this.init(0)};qg.prototype.init=function(t){var e=this;this.length=t,this.count=0;for(var i=0,r=this.__fields.length;i<r;++i){var n=e.__fields[i][0],o=e.__fields[i][1],a=e.__fields[i][2],s=e.length*o;e[n]=En(a,s)}},qg.prototype.resize=function(t){var e=this;this.length=Math.round(t||0),this.count=Math.min(this.count,this.length);for(var i=0,r=this.__fields.length;i<r;++i){var n=e.__fields[i][0],o=e.__fields[i][1],a=e.length*o,s=new e[n].constructor(a);e[n].length>a?s.set(e[n].subarray(0,a)):s.set(e[n]),e[n]=s}},qg.prototype.growIfFull=function(){if(this.count>=this.length){var t=Math.round(1.5*this.length);this.resize(Math.max(256,t))}},qg.prototype.copyFrom=function(t,e,i,r){for(var n=this,o=0,a=this.__fields.length;o<a;++o)for(var s=n.__fields[o][0],c=n.__fields[o][1],u=n[s],h=t[s],l=0;l<r;++l)for(var p=c*(e+l),d=c*(i+l),f=0;f<c;++f)u[p+f]=h[d+f]},qg.prototype.copyWithin=function(t,e,i){for(var r=this,n=0,o=this.__fields.length;n<o;++n)for(var a=r.__fields[n][0],s=r.__fields[n][1],c=r[a],u=0;u<i;++u)for(var h=s*(t+u),l=s*(e+u),p=0;p<s;++p)c[h+p]=c[l+p]},qg.prototype.sort=function(t){function e(t,e){t!==e&&(n.copyFrom(r,0,t,1),r.copyWithin(t,e,1),r.copyFrom(n,e,0,1))}function i(r,n){if(r<n){var o=Math.floor((r+n)/2),a=r,s=n;do{for(;t(a,o)<0;)a+=1;for(;t(s,o)>0;)s-=1;a<=s&&(a===o?o=s:s===o&&(o=a),e(a,s),a+=1,s-=1)}while(a<=s);i(r,s),i(a,n)}}cf.time("Store.sort");var r=this,n=new this.constructor(1);i(0,this.count-1),cf.timeEnd("Store.sort")},qg.prototype.clear=function(){this.count=0},qg.prototype.dispose=function(){var t=this;delete this.length,delete this.count;for(var e=0,i=this.__fields.length;e<i;++e)delete t[t.__fields[e][0]]};var Yg=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={__fields:{}};return i.__fields.get=function(){return[["atomIndex1",1,"int32"],["atomIndex2",1,"int32"],["bondOrder",1,"int8"]]},e.prototype.addBond=function(t,e,i){this.growIfFull();var r=this.count,n=t.index,o=e.index;n<o?(this.atomIndex1[r]=n,this.atomIndex2[r]=o):(this.atomIndex2[r]=n,this.atomIndex1[r]=o),i&&(this.bondOrder[r]=i),this.count+=1},e.prototype.addBondIfConnected=function(t,e,i){return!!t.connectedTo(e)&&(this.addBond(t,e,i),!0)},Object.defineProperties(e.prototype,i),e}(qg),Zg=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={__fields:{}};return i.__fields.get=function(){return[["residueIndex",1,"uint32"],["atomTypeId",1,"uint16"],["x",1,"float32"],["y",1,"float32"],["z",1,"float32"],["serial",1,"int32"],["bfactor",1,"float32"],["altloc",1,"uint8"],["occupancy",1,"float32"]]},e.prototype.setAltloc=function(t,e){this.altloc[t]=e.charCodeAt(0)},e.prototype.getAltloc=function(t){var e=this.altloc[t];return e?String.fromCharCode(e):""},Object.defineProperties(e.prototype,i),e}(qg),Kg=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={__fields:{}};return i.__fields.get=function(){return[["chainIndex",1,"uint32"],["atomOffset",1,"uint32"],["atomCount",1,"uint16"],["residueTypeId",1,"uint16"],["resno",1,"int32"],["sstruc",1,"uint8"],["inscode",1,"uint8"]]},e.prototype.setSstruc=function(t,e){this.sstruc[t]=e.charCodeAt(0)},e.prototype.getSstruc=function(t){var e=this.sstruc[t];return e?String.fromCharCode(e):""},e.prototype.setInscode=function(t,e){this.inscode[t]=e.charCodeAt(0)},e.prototype.getInscode=function(t){var e=this.inscode[t];return e?String.fromCharCode(e):""},Object.defineProperties(e.prototype,i),e}(qg),Qg=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={__fields:{}};return i.__fields.get=function(){return[["entityIndex",1,"uint16"],["modelIndex",1,"uint16"],["residueOffset",1,"uint32"],["residueCount",1,"uint32"],["chainname",4,"uint8"],["chainid",4,"uint8"]]},e.prototype.setChainname=function(t,e){var i=4*t;this.chainname[i]=e.charCodeAt(0),this.chainname[i+1]=e.charCodeAt(1),this.chainname[i+2]=e.charCodeAt(2),this.chainname[i+3]=e.charCodeAt(3)},e.prototype.getChainname=function(t){for(var e=this,i="",r=0;r<4;++r){var n=e.chainname[4*t+r];if(!n)break;i+=String.fromCharCode(n)}return i},e.prototype.setChainid=function(t,e){var i=4*t;this.chainid[i]=e.charCodeAt(0),this.chainid[i+1]=e.charCodeAt(1),this.chainid[i+2]=e.charCodeAt(2),this.chainid[i+3]=e.charCodeAt(3)},e.prototype.getChainid=function(t){for(var e=this,i="",r=0;r<4;++r){var n=e.chainid[4*t+r];if(!n)break;i+=String.fromCharCode(n)}return i},Object.defineProperties(e.prototype,i),e}(qg),Jg=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={__fields:{}};return i.__fields.get=function(){return[["chainOffset",1,"uint32"],["chainCount",1,"uint32"]]},Object.defineProperties(e.prototype,i),e}(qg);Za.prototype={constructor:Za,getCenterIterator:function(t){function e(){var t=this.get(s);return s+=1,t}function i(e){e=Math.min(o-1,Math.max(0,e));var i=c[a%4],r=3*e;if(i.fromArray(n,r),t){var s,u,h,l=Math.min(t,e,o-e-1);for(u=1;u<=l;++u)s=3*u,h=(l+1-u)/(l+1),i.x+=h*n[r-s+0]+h*n[r+s+0],i.y+=h*n[r-s+1]+h*n[r+s+1],i.z+=h*n[r-s+2]+h*n[r+s+2];i.x/=l+1,i.y/=l+1,i.z/=l+1}return a+=1,i}function r(){a=0,s=-1}var n=this.getPosition().center,o=n.length/3,a=0,s=-1,c=[new g,new g,new g,new g];return{size:o,next:e,get:i,reset:r}},getColor:function(t){var e=this.polymer,i=e.structure,r=e.residueCount,n=e.residueIndexStart,o=new Float32Array(3*r),a=t||{};a.structure=i;for(var s=lf.getScheme(a),c=i.getResidueProxy(),u=i.getAtomProxy(),h=0;h<r;++h)c.index=n+h,u.index=c.traceAtomIndex,s.atomColorToArray(u,o,3*h);return{color:o}},getPicking:function(){for(var t=this.polymer,e=t.structure,i=t.residueCount,r=t.residueIndexStart,n=new Float32Array(i),o=e.getResidueProxy(),a=0;a<i;++a)o.index=r+a,n[a]=o.traceAtomIndex;return{picking:new $m(n,e)}},getSize:function(t,e){for(var i=this.polymer,r=i.structure,n=i.residueCount,o=i.residueIndexStart,a=new Float32Array(n),s=new ga(t,e),c=r.getResidueProxy(),u=r.getAtomProxy(),h=0;h<n;++h)c.index=o+h,u.index=c.traceAtomIndex,a[h]=s.atomRadius(u);return{size:a}},getPosition:function(){var t,e,i,r,n,o=this.polymer,a=o.structure,s=o.residueCount,c=s-3,u=new Float32Array(3*s),h=new Float32Array(3*s),l=new Float32Array(s),p=new Float32Array(s),d=new Float32Array(s),f=new Float32Array(s),m=new Float32Array(3*s),v=new g,y=new g,b=new g,x=new g,_=new g,w=new g,S=new g,A=new g,M=new g,P=new g,T=new g,E=new g(0,0,0),C="trace",I=a.getAtomProxy(),L=a.getAtomProxy(o.getAtomIndexByType(0,C)),R=a.getAtomProxy(o.getAtomIndexByType(1,C)),O=a.getAtomProxy(o.getAtomIndexByType(2,C));for(i=0;i<c;++i)I.index=L.index,L.index=R.index,R.index=O.index,O.index=o.getAtomIndexByType(i+3,C),e=3*i,v.subVectors(L,I),y.subVectors(R,L),b.subVectors(O,R),x.subVectors(v,y),_.subVectors(y,b),M.crossVectors(x,_).normalize(),M.toArray(h,e),i>0&&(l[i]=M.angleTo(P)),t=Math.cos(x.angleTo(_)),f[i]=180/Math.PI*Math.acos(t),r=x.length(),n=_.length(),p[i]=Math.sqrt(n*r)/Math.max(2,2*(1-t)),d[i]=Math.abs(y.dot(M)),w.copy(x).multiplyScalar(p[i]/r),S.copy(_).multiplyScalar(p[i]/n),w.subVectors(L,w),S.subVectors(R,S),w.toArray(u,e+3),S.toArray(u,e+6),T.subVectors(I,E),T.toArray(m,e),P.copy(M),E.copy(w);for(w.fromArray(u,3),S.fromArray(u,6),M.subVectors(w,S).normalize(),I.index=o.getAtomIndexByType(0,C),E.copy(I),A.copy(I),Ko(A,M,w),A.toArray(u,0),T.subVectors(E,w),T.toArray(m,0),w.fromArray(u,3*s-6),S.fromArray(u,3*s-9),M.subVectors(w,S).normalize(),I.index=o.getAtomIndexByType(s-1,C),E.copy(I),A.copy(I),Ko(A,M,w),A.toArray(u,3*s-3),i=s-3;i<s;++i)w.fromArray(u,3*i),I.index=o.getAtomIndexByType(i,C),E.copy(I),T.subVectors(E,w),T.toArray(m,3*i);var D=new Float32Array(s),N=new Float32Array(s),k=new Float32Array(s),B=new Float32Array(s);for(D[1]=p[0],N[1]=f[0],k[1]=p[0],i=2;i<s-2;++i)D[i]=.5*(p[i-2]+p[i-1]),N[i]=.5*(f[i-2]+f[i-1]),k[i]=.5*(d[i-2]+d[i-1]),w.fromArray(h,3*(i-2)),S.fromArray(h,3*(i-1)),B[i]=180/Math.PI*Math.acos(Math.cos(w.angleTo(S)));D[s-2]=p[s-4],N[s-2]=f[s-4],k[s-2]=d[s-4];var F=new Float32Array(3*s);for(Ro(h,F,0,0,3),Ro(h,F,0,3,3),i=2;i<s-2;++i)w.fromArray(h,3*(i-2)),S.fromArray(h,3*(i-1)),M.addVectors(S,w).multiplyScalar(.5).normalize(),M.toArray(F,3*i);return Ro(h,F,3*s-12,3*s-6,3),Ro(h,F,3*s-12,3*s-3,3),{center:u,axis:F,bending:B,radius:D,rise:k,twist:N,resdir:m}}},Ka.prototype={constructor:Ka,getAxis:function(t,e,i,r,n,o){t=t||30,e=e||2.5,i=void 0!==i&&i;var a=this.polymer,s=a.structure,c=a.residueCount,u=a.residueIndexStart,h=this.position,l=r||{};l.structure=s;for(var p,d,f=lf.getScheme(l),m=new ga(n,o),v=0,y=0,b=[],x=[],_=[],w=[],S=[],A=[],M=[],P=[],T=[],E=[],C=[],I=new g,L=new g,R=s.getResidueProxy(),O=s.getResidueProxy(),D=s.getAtomProxy(),N=new g,k=new g,B=!1,F=0;F<c;++F)if(R.index=u+F,N.fromArray(h.center,3*F),F===c-1?B=!0:(O.index=u+F+1,k.fromArray(h.center,3*F+3),i&&R.sstruc!==O.sstruc?B=!0:N.distanceTo(k)>e?B=!0:h.bending[F]>t&&(B=!0)),B){if(F-v<4){v=F,B=!1;continue}D.index=R.traceAtomIndex,E=h.axis.subarray(3*v+3,3*F),C=h.center.subarray(3*v,3*F+3),p=Zo(E).normalize(),d=Zo(C),I.fromArray(C),Ko(I,p,d),L.fromArray(C,C.length-3),Ko(L,p,d),p.subVectors(L,I),p.toArray(b,y),d.toArray(x,y),I.toArray(_,y),L.toArray(w,y),f.atomColorToArray(D,S,y),A.push(D.index),M.push(m.atomRadius(D)),P.push(u+v),T.push(u+F+1-v),y+=3,v=F,B=!1}var z=new Float32Array(A);return{axis:new Float32Array(b),center:new Float32Array(x),begin:new Float32Array(_),end:new Float32Array(w),color:new Float32Array(S),picking:new $m(z,s),size:new Float32Array(M),residueOffset:P,residueCount:T}}},Qa.prototype={push:function(t){this.content.push(t),this.bubbleUp(this.content.length-1)},pop:function(){var t=this.content[0],e=this.content.pop();return this.content.length>0&&(this.content[0]=e,this.sinkDown(0)),t},peek:function(){return this.content[0]},remove:function(t){for(var e=this,i=this.content.length,r=0;r<i;r++)if(e.content[r]==t){var n=e.content.pop();return void(r!=i-1&&(e.content[r]=n,e.scoreFunction(n)<e.scoreFunction(t)?e.bubbleUp(r):e.sinkDown(r)))}throw new Error("Node not found.")},size:function(){return this.content.length},bubbleUp:function(t){for(var e=this,i=this.content[t];t>0;){var r=Math.floor((t+1)/2)-1,n=e.content[r];if(!(e.scoreFunction(i)<e.scoreFunction(n)))break;e.content[r]=i,e.content[t]=n,t=r}},sinkDown:function(t){for(var e,i=this,r=this.content.length,n=this.content[t],o=this.scoreFunction(n);;){var a=2*(t+1),s=a-1,c=null;if(s<r){var u=i.content[s];(e=i.scoreFunction(u))<o&&(c=s)}if(a<r){var h=i.content[a];i.scoreFunction(h)<(null===c?o:e)&&(c=a)}if(null===c)break;i.content[t]=i.content[c],i.content[c]=n,t=c}}},ts.prototype={nearest:function(){var t=new Float32Array(3);return function(e,i,r){e.toArray?e.toArray(t):e.positionToArray&&e.positionToArray(t);for(var n=this.kdtree.nearest(t,i,r),o=this.kdtree.indices,a=this.kdtree.nodes,s=this.atomIndices,c=[],u=0,h=n.length;u<h;++u){var l=n[u],p=l[0],d=l[1];c.push({index:s[o[a[p]]],distance:d})}return c}}()};var tv={" ":"X","!":"Y","#":"Z",$:"-X","%":"-Y","&":"-Z","'":"Y+1/2","(":"1/2+X",")":"1/2+Y","*":"1/2-X","+":"1/2+Z",",":"1/2-Y","-":"1/2-Z",".":"X+1/2","/":"Z+1/2",0:"-X+1/2",1:"-Y+1/2",2:"-Z+1/2",3:"1/4+X",4:"1/4-Y",5:"1/4+Z",6:"1/4-X",7:"1/4+Y",8:"3/4-Y",9:"3/4+Z",":":"3/4+Y",";":"3/4+X","<":"3/4-X","=":"1/4-Z",">":"3/4-Z","?":"X-Y","@":"Y-X",A:"Z+1/3",B:"Z+2/3",C:"X+2/3",D:"Y+1/3",E:"-Y+2/3",F:"X-Y+1/3",G:"Y-X+2/3",H:"-X+1/3",I:"X+1/3",J:"Y+2/3",K:"-Y+1/3",L:"X-Y+2/3",M:"Y-X+1/3",N:"-X+2/3",O:"2/3+X",P:"1/3+Y",Q:"1/3+Z",R:"2/3-Y",S:"1/3+X-Y",T:"2/3+Y-X",U:"1/3-X",V:"2/3-X",W:"1/3-Y",X:"1/3-Z",Y:"2/3+Y",Z:"1/3+Y-X","[":"2/3+X-Y","]":"1/3+X","^":"2/3+Z",_:"2/3-Z","`":"5/6+Z",a:"1/6+Z",b:"5/6-Z",c:"1/6-Z",d:"Z+5/6",e:"Z+1/6",f:"Z+1/4",g:"+Y"},ev={"P 1":" !#","P -1":" !#$%&","P 1 2 1":" !#$!&","P 1 21 1":" !#$'&","C 1 2 1":" !#$!&()#*)&","P 1 m 1":" !# %#","P 1 c 1":" !# %+","C 1 m 1":" !# %#()#(,#","C 1 c 1":" !# %+()#(,+","P 1 2/m 1":" !# %#$!&$%&","P 1 21/m 1":" !#$)&$%& ,#","C 1 2/m 1":" !# %#$!&$%&()#(,#*)&*,&","P 1 2/c 1":" !#$!-$%& %+","P 1 21/c 1":" !#$%&$)- ,+","C 1 2/c 1":" !#$!-$%& %+()#*)-*,&(,+","P 2 2 2":" !#$%#$!& %&","P 2 2 21":" !#$%+$!- %&","P 21 21 2":" !#$%#*)&(,&","P 21 21 21":" !#*%+$)-(,&","C 2 2 21":" !#$%+$!- %&()#*,+*)-(,&","C 2 2 2":" !#$%#$!& %&()#*,#*)&(,&","F 2 2 2":" !#$%#$!& %& )+$,+$)- ,-(!+*%+*!-(%-()#*,#*)&(,&","I 2 2 2":" !#$%# %&$!&.'/01/.120'2","I 21 21 21":" !#*%+$)-(,&()+$,#*!& %-","P m m 2":" !#$%# %#$!#","P m c 21":" !#$%+ %+$!#","P c c 2":" !#$%# %+$!+","P m a 2":" !#$%#(%#*!#","P c a 21":" !#$%+(%#*!+","P n c 2":" !#$%# ,+$)+","P m n 21":" !#*%+(%+$!#","P b a 2":" !#$%#(,#*)#","P n a 21":" !#$%+(,#*)+","P n n 2":" !#$%#(,+*)+","C m m 2":" !#$%# %#$!#()#*,#(,#*)#","C m c 21":" !#$%+ %+$!#()#*,+(,+*)#","C c c 2":" !#$%# %+$!+()#*,#(,+*)+","A m m 2":" !#$%# %#$!# )+$,+ ,+$)+","A b m 2":" !#$%# ,#$)# )+$,+ %+$!+","A m a 2":" !#$%#(%#*!# )+$,+(,+*)+","A b a 2":" !#$%#(,#*)# )+$,+(%+*!+","F m m 2":" !#$%# %#$!# )+$,+ ,+$)+(!+*%+(%+*!+()#*,#(,#*)#","F d d 2":" !#$%#345675 )+$,+3896:9(!+*%+;49<79()#*,#;85<:5","I m m 2":" !#$%# %#$!#()+*,+(,+*)+","I b a 2":" !#$%#(,#*)#()+*,+ %+$!+","I m a 2":" !#$%#(%#*!#()+*,+ ,+$)+","P 2/m 2/m 2/m":" !#$%#$!& %&$%& !& %#$!#","P 2/n 2/n 2/n":" !#$%#$!& %&*,-()-(,+*)+","P 2/c 2/c 2/m":" !#$%#$!- %-$%& !& %+$!+","P 2/b 2/a 2/n":" !#$%#$!& %&*,&()&(,#*)#","P 21/m 2/m 2/a":" !#*%#$!&(%&$%&(!& %#*!#","P 2/n 21/n 2/a":" !#*%#*)- ,-$%&(!&(,+$)+","P 2/m 2/n 21/a":" !#*%+*!- %&$%&(!-(%+$!#","P 21/c 2/c 2/a":" !#*%#$!-(%-$%&(!& %+*!+","P 21/b 21/a 2/m":" !#$%#*)&(,&$%& !&(,#*)#","P 21/c 21/c 2/n":" !#*,#$)-(%-$%&()& ,+*!+","P 2/b 21/c 21/m":" !#$%+$)- ,&$%& !- ,+$)#","P 21/n 21/n 2/m":" !#$%#*)-(,-$%& !&(,+*)+","P 21/m 21/m 2/n":" !#$%#*'&.,&*,&.'& %#$!#","P 21/b 2/c 21/n":" !#*,+$!-(,&$%&()- %+*)#","P 21/b 21/c 21/a":" !#*%+$)-(,&$%&(!- ,+*)#","P 21/n 21/m 21/a":" !#0%/$'&.12$%&.!2 1#0'/","C 2/m 2/c 21/m":" !#$%+$!- %&$%& !- %+$!#()#*,+*)-(,&*,&()-(,+*)#","C 2/m 2/c 21/a":" !#$,+$)- %&$%& )- ,+$!#()#*%+*!-(,&*,&(!-(%+*)#","C 2/m 2/m 2/m":" !#$%#$!& %&$%& !& %#$!#()#*,#*)&(,&*,&()&(,#*)#","C 2/c 2/c 2/m":" !#$%#$!- %-$%& !& %+$!+()#*,#*)-(,-*,&()&(,+*)+","C 2/m 2/m 2/a":" !#$,#$)& %&$%& )& ,#$!#()#*%#*!&(,&*,&(!&(%#*)#","C 2/c 2/c 2/a":" !#*,#$!&(,&$,-(!- ,+*!+()#$%#*)& %&*%- )-(%+$)+","F 2/m 2/m 2/m":" !#$%#$!& %&$%& !& %#$!# )+$,+$)- ,-$,- )- ,+$)+(!+*%+*!-(%-*%-(!-(%+*!+()#*,#*)&(,&*,&()&(,#*)#","F 2/d 2/d 2/d":" !#$%#$!& %&64=37=345675 )+$,+$)- ,-68>3:>3896:9(!+*%+*!-(%-<4>;7>;49<79()#*,#*)&(,&<8=;:=;85<:5","I 2/m 2/m 2/m":" !#$%#$!& %&$%& !& %#$!#()+*,+*)-(,-*,-()-(,+*)+","I 2/b 2/a 2/m":" !#$%#*)&(,&$%& !&(,#*)#()+*,+$!- %-*,-()- %+$!+","I 21/b 21/c 21/a":" !#*%+$)-(,&$%&(!- ,+*)#()+$,#*!& %-*,- )&(%#$!+","I 21/m 21/m 21/a":" !#$,#$)& %&$%& )& ,#$!#()+*%+*!-(,-*,-(!-(%+*)+","P 4":" !#$%#% #!$#","P 41":" !#$%+% 5!$9","P 42":" !#$%#% +!$+","P 43":" !#$%+% 9!$5","I 4":" !#$%#% #!$#()+*,+,(+)*+","I 41":" !#*,+%(5)$9()+$%#, 9!*5","P -4":" !#$%#!$&% &","I -4":" !#$%#!$&% &()+*,+)*-,(-","P 4/m":" !#$%#% #!$#$%& !&!$&% &","P 42/m":" !#$%#% +!$+$%& !&!$-% -","P 4/n":" !#$%#,(#)*#*,&()&!$&% &","P 42/n":" !#$%#,(+)*+*,-()-!$&% &","I 4/m":" !#$%#% #!$#$%& !&!$&% &()+*,+,(+)*+*,-()-)*-,(-","I 41/a":" !#*,+%(5)$9$,=(!>!$&,(-()+$%#, 9!*5*%> )=)*-% &","P 4 2 2":" !#$%#% #!$#$!& %&! &%$&","P 4 21 2":" !#$%#,(#)*#*)&(,&! &%$&","P 41 2 2":" !#$%+% 5!$9$!& %-! >%$=","P 41 21 2":" !#$%+,(5)*9*)=(,>! &%$-","P 42 2 2":" !#$%#% +!$+$!& %&! -%$-","P 42 21 2":" !#$%#,(+)*+*)-(,-! &%$&","P 43 2 2":" !#$%+% 9!$5$!& %-! =%$>","P 43 21 2":" !#$%+,(9)*5*)>(,=! &%$-","I 4 2 2":" !#$%#% #!$#$!& %&! &%$&()+*,+,(+)*+*)-(,-)(-,*-","I 41 2 2":" !#*,+%(5)$9*!> ,=)(-%$&()+$%#, 9!*5$)=(%>! &,*-","P 4 m m":" !#$%#% #!$# %#$!#%$#! #","P 4 b m":" !#$%#% #!$#(,#*)#,*#)(#","P 42 c m":" !#$%#% +!$+ %+$!+%$#! #","P 42 n m":" !#$%#,(+)*+(,+*)+%$#! #","P 4 c c":" !#$%#% #!$# %+$!+%$+! +","P 4 n c":" !#$%#% #!$#(,+*)+,*+)(+","P 42 m c":" !#$%#% +!$+ %#$!#%$+! +","P 42 b c":" !#$%#% +!$+(,#*)#,*+)(+","I 4 m m":" !#$%#% #!$# %#$!#%$#! #()+*,+,(+)*+(,+*)+,*+)(+","I 4 c m":" !#$%#% #!$# %+$!+%$+! +()+*,+,(+)*+(,#*)#,*#)(#","I 41 m d":" !#*,+%(5)$9 %#*)+%*5) 9()+$%#, 9!*5(,+$!#,$9!(5","I 41 c d":" !#*,+%(5)$9 %+*)#%*9) 5()+$%#, 9!*5(,#$!+,$5!(9","P -4 2 m":" !#$%#% &!$&$!& %&%$#! #","P -4 2 c":" !#$%#% &!$&$!- %-%$+! +","P -4 21 m":" !#$%#% &!$&*)&(,&,*#)(#","P -4 21 c":" !#$%#% &!$&*)-(,-,*+)(+","P -4 m 2":" !#$%#!$&% & %#$!#! &%$&","P -4 c 2":" !#$%#% &!$& %+$!+! -%$-","P -4 b 2":" !#$%#% &!$&(,#*)#)(&,*&","P -4 n 2":" !#$%#% &!$&(,+*)+)(-,*-","I -4 m 2":" !#$%#% &!$& %#$!#! &%$&()+*,+,(-)*-(,+*)+)(-,*-","I -4 c 2":" !#$%#% &!$& %+$!+! -%$-()+*,+,(-)*-(,#*)#)(&,*&","I -4 2 m":" !#$%#% &!$&$!& %&%$#! #()+*,+,(-)*-*)-(,-,*+)(+","I -4 2 d":" !#$%#% &!$&*!>(%>,$9) 9()+*,+,(-)*-$)= ,=%*5!(5","P 4/m 2/m 2/m":" !#$%#% #!$#$!& %&! &%$&$%& !&!$&% & %#$!#%$#! #","P 4/m 2/c 2/c":" !#$%#% #!$#$!- %-! -%$-$%& !&!$&% & %+$!+%$+! +","P 4/n 2/b 2/m":" !#$%#% #!$#$!& %&! &%$&*,&()&)*&,(&(,#*)#,*#)(#","P 4/n 2/n 2/c":" !#$%#% #!$#$!& %&! &%$&*,-()-)*-,(-(,+*)+,*+)(+","P 4/m 21/b 2/m":" !#$%#% #!$#*)&(,&)(&,*&$%& !&!$&% &(,#*)#,*#)(#","P 4/m 21/n 2/c":" !#$%#% #!$#*)-(,-)(-,*-$%& !&!$&% &(,+*)+,*+)(+","P 4/n 21/m 2/m":" !#$%#,(#)*#*)&(,&! &%$&*,&()&!$&% & %#$!#,*#)(#","P 4/n 2/c 2/c":" !#$%#,(#)*#*)-(,-! -%$-*,&()&!$&% & %+$!+,*+)(+","P 42/m 2/m 2/c":" !#$%#% +!$+$!& %&! -%$-$%& !&!$-% - %#$!#%$+! +","P 42/m 2/c 2/m":" !#$%#% +!$+$!- %-! &%$&$%& !&!$-% - %+$!+%$#! #","P 42/n 2/b 2/c":" !#$%#,(+)*+$!- %-)(&,*&*,-()-!$&% &(,#*)#%$+! +","P 42/n 2/n 2/m":" !#$%#,(+)*+$!& %&)(-,*-*,-()-!$&% &(,+*)+%$#! #","P 42/m 21/b 2/c":" !#$%#% +!$+*)&(,&)(-,*-$%& !&!$-% -(,#*)#,*+)(+","P 42/m 21/n 2/m":" !#$%#,./'*/*'-.,-! &%$&$%& !&'*-,.-.,/*'/%$#! #","P 42/n 21/m 2/c":" !#$%#,(+)*+*)-(,-! &%$&*,-()-!$&% & %#$!#,*+)(+","P 42/n 21/c 2/m":" !#$%#,(+)*+*)&(,&! -%$-*,-()-!$&% & %+$!+,*#)(#","I 4/m 2/m 2/m":" !#$%#% #!$#$!& %&! &%$&$%& !&!$&% & %#$!#%$#! #()+*,+,(+)*+*)-(,-)(-,*-*,-()-)*-,(-(,+*)+,*+)(+","I 4/m 2/c 2/m":" !#$%#% #!$#$!- %-! -%$-$%& !&!$&% & %+$!+%$+! +()+*,+,(+)*+*)&(,&)(&,*&*,-()-)*-,(-(,#*)#,*#)(#","I 41/a 2/m 2/d":" !#*,+%(5)$9*!> ,=)(-%$&$,=(!>!$&,(-(,+$!#,$9!(5()+$%#, 9!*5$)=(%>! &,*-*%> )=)*-% & %#*)+%*5) 9","I 41/a 2/c 2/d":" !#*,+%(5)$9*!= ,>)(&%$-$,=(!>!$&,(-(,#$!+,$5!(9()+$%#, 9!*5$)>(%=! -,*&*%> )=)*-% & %+*)#%*9) 5","P 3":" !#%?#@$#","P 31":" !#%?A@$B","P 32":" !#%?B@$A","H 3":" !#%?#@$#CDAEFAGHAIJBKLBMNB","R 3":" !## !!# ","P -3":" !#%?#@$#$%&!@&? &","H -3":" !#%?#@$#$%&!@&? &OPQRSQTUQVWXYZX[]X]Y^W[^ZV^UR_PT_SO_","R -3":" !## !!# $%&&$%%&$","P 3 1 2":" !#%?#@$#%$&@!& ?&","P 3 2 1":" !#%?#@$#! &?%&$@&","P 31 1 2":" !#%?Q@$^%$_@!X ?&","P 31 2 1":" !#%?A@$B! &?%_$@X","P 32 1 2":" !#%?^@$Q%$X@!_ ?&","P 32 2 1":" !#%?B@$A! &?%X$@_","H 3 2":" !#%?#@$#! &?%&$@&OPQRSQTUQY]X[WXVZX]Y^W[^ZV^PO_SR_UT_","R 3 2":" !## !!# %$&$&%&%$","P 3 m 1":" !#%?#@$#%$#@!# ?#","P 3 1 m":" !#%?#@$#! #?%#$@#","P 3 c 1":" !#%?#@$#%$+@!+ ?+","P 3 1 c":" !#%?#@$#! +?%+$@+","H 3 m":" !#%?#@$#%$#@!# ?#OPQRSQTUQRUQTPQOSQ]Y^W[^ZV^WV^ZY^][^","R 3 m":" !## !!# ! # #!#! ","H 3 c":" !#%?#@$#%$+@!+ ?+OPQRSQTUQRU`TP`OS`]Y^W[^ZV^WVaZYa][a","R 3 c":" !## !!# '././'/'.","P -3 1 2/m":" !#%?#@$#%$&@!& ?&$%&!@&? &! #?%#$@#","P -3 1 2/c":" !#%?#@$#%$-@!- ?-$%&!@&? &! +?%+$@+","P -3 2/m 1":" !#%?#@$#! &?%&$@&$%&!@&? &%$#@!# ?#","P -3 2/c 1":" !#%?#@$#! -?%-$@-$%&!@&? &%$+@!+ ?+","H -3 2/m":" !#%?#@$#! &?%&$@&$%&!@&? &%$#@!# ?#OPQRSQTUQY]X[WXVZXVWXYZX[]XRUQTPQOSQ]Y^W[^ZV^PO_SR_UT_UR_PT_SO_WV^ZY^][^","R -3 2/m":" !## !!# %$&$&%&%$$%&&$%%&$! # #!#! ","H -3 2/c":" !#%?#@$#! -?%-$@-$%&!@&? &%$+@!+ ?+OPQRSQTUQY]b[WbVZbVWXYZX[]XRU`TP`OS`]Y^W[^ZV^POcSRcUTcUR_PT_SO_WVaZYa][a","R -3 2/c":" !## !!# 102021210$%&&$%%&$'././'/'.","P 6":" !#%?#@$#$%#!@#? #","P 61":" !#%?A@$B$%/!@d? e","P 65":" !#%?B@$A$%/!@e? d","P 62":" !#%?^@$Q$%#!@^? Q","P 64":" !#%?Q@$^$%#!@Q? ^","P 63":" !#%?#@$#$%+!@+? +","P -6":" !#%?#@$# !&%?&@$&","P 6/m":" !#%?#@$#$%#!@#? #$%&!@&? & !&%?&@$&","P 63/m":" !#%?#@$#$%+!@+? +$%&!@&? & !-%?-@$-","P 6 2 2":" !#%?#@$#$%#!@#? #! &?%&$@&%$&@!& ?&","P 61 2 2":" !#%?Q@$^$%+!@`? a! X?%&$@_%$b@!- ?c","P 65 2 2":" !#%?^@$Q$%+!@a? `! _?%&$@X%$c@!- ?b","P 62 2 2":" !#%?^@$Q$%#!@^? Q! _?%&$@X%$_@!& ?X","P 64 2 2":" !#%?Q@$^$%#!@Q? ^! X?%&$@_%$X@!& ?_","P 63 2 2":" !#%?#@$#$%+!@+? +! &?%&$@&%$-@!- ?-","P 6 m m":" !#%?#@$#$%#!@#? #%$#@!# ?#! #?%#$@#","P 6 c c":" !#%?#@$#$%#!@#? #%$+@!+ ?+! +?%+$@+","P 63 c m":" !#%?#@$#$%+!@+? +%$+@!+ ?+! #?%#$@#","P 63 m c":" !#%?#@$#$%+!@+? +%$#@!# ?#! +?%+$@+","P -6 m 2":" !#%?#@$# !&%?&@$&%$#@!# ?#%$&@!& ?&","P -6 c 2":" !#%?#@$# !-%?-@$-%$+@!+ ?+%$&@!& ?&","P -6 2 m":" !#%?#@$# !&%?&@$&! &?%&$@&! #?%#$@#","P -6 2 c":" !#%?#@$# !-%?-@$-! &?%&$@&! +?%+$@+","P 6/m 2/m 2/m":" !#%?#@$#$%#!@#? #! &?%&$@&%$&@!& ?&$%&!@&? & !&@$&%?&%$#@!# ?#! #?%#$@#","P 6/m 2/c 2/c":" !#%?#@$#$%#!@#? #! -?%-$@-%$-@!- ?-$%&!@&? & !&@$&%?&%$+@!+ ?+! +?%+$@+","P 63/m 2/c 2/m":" !#%?#@$#$%+!@+? +! -?%-$@-%$&@!& ?&$%&!@&? & !-@$-%?-%$+@!+ ?+! #?%#$@#","P 63/m 2/m 2/c":" !#%?#@$#$%+!@+? +! &?%&$@&%$-@!- ?-$%&!@&? & !-@$-%?-%$#@!# ?#! +?%+$@+","P 2 3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ","F 2 3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%&  )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-((!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&(()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- ","I 2 3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ()+*,+*)-(,-+()+*,-*)-(,)+(,+*)-*,-(","P 21 3":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&(","I 21 3":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&(()+$,#*!& %-+()#$,&*!- %)+(,#$!&*%- ","P 2/m -3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& $%& !& %#$!#&$%& !# %#$!%&$!& %# !#$","P 2/n -3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& *,-()-(,+*)+-*,-()+(,+*),-*)-(,+()+*","F 2/m -3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& $%& !& %#$!#&$%& !# %#$!%&$!& %# !#$ )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-($,- )- ,+$)+&*,&()#(,#*)%-*!-(%+(!+*(!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&(*%-(!-(%+*!+-$,- )+ ,+$),&*)&(,#()#*()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- *,&()&(,#*)#-*%-(!+(%+*!,-$)- ,+ )+$","F 2/d -3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& 64=37=345675=64=375345674=67=3453756 )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-(68>3:>3896:9=<8=;:5;85<:4><7>;49;79<(!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&(<4>;7>;49<79>68>3:93896:8=<:=;85;:5<()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- <8=;:=;8f<:f><4>;79;49<78>6:>3893:96","I 2/m -3":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& $%& !& %#$!#&$%& !# %#$!%&$!& %# !#$()+*,+*)-(,-+()+*,-*)-(,)+(,+*)-*,-(*,-()-(,+*)+-*,-()+(,+*),-*)-(,+()+*","P 21/a -3":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&($%&(!- ,+*)#&$%-(!+ ,#*)%&$!-(,+ )#*","I 21/a -3":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&($%&(!- ,+*)#&$%-(!+ ,#*)%&$!-(,+ )#*()+$,#*g& %-+()#$,&*!- %)+(,#$!&*%- *,- )&(%#$!+-*,& )#(%+$!,-*)& %#(!+$","P 4 3 2":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! &%$&!$#% # #%$#!$&% &!#!$#% &! &%$","P 42 3 2":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& )(-,*-)*+,(+(+,*+)*-,(-)+)*+,(-)(-,*","F 4 3 2":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! &%$&!$#% # #%$#!$&% &!#!$#% &! &%$ )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-(!(-%*-!*+%(+ +,$+)$-, -)#)*#,(&)(&,*(!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&() -,$-)$+, +(#,*#)*&,(&)+!*+%(-!(-%*()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- )(&,*&)*#,(#(+%*+!*-%(-!+)$+, -) -,$","F 41 3 2":" !#$,+*)&(%-# !+$,&*)-(%!# ,+$)&*%-(:3>46=7<98;5;58<976=43>:97<58;>:3=46 )+$%#*!-(,&#()+*%&$!- ,!+(,#*)-$%& :;=4<>765839;94<5:6>83=79:6543>7;=8<(!+*,#$)- %&+ )#$%-*!&(,)#(%+*!&$,- 73=86>:<54;935469:<=8;>7576983=:;>4<()#*%+$!& ,-+(!#*,-$)& %)+ %#$!-*,&(7;>8<=:69435398657<>4;=:5:<94;=73>86","I 4 3 2":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! &%$&!$#% # #%$#!$&% &!#!$#% &! &%$()+*,+*)-(,-+()+*,-*)-(,)+(,+*)-*,-()(-,*-)*+,(+(+,*+)*-,(-)+)*+,(-)(-,*","P 43 3 2":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&(7;>46=:<5839398<5:6=4;>75:<983>7;=46","P 41 3 2":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&(:3=8<>7694;5;54697<>83=:97654;=:3>8<","I 41 3 2":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&(:3=8<>7694;5;54697<>83=:97654;=:3>8<()+$,#*!& %-+()#$,&*!- %)+(,#$!&*%- 7;>46=:<5839398<5:6=4;>75:<983>7;=46","P -4 3 m":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! #%$#!$&% & #!$#%$&! &%#! #%$&!$&% ","F -4 3 m":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! #%$#!$&% & #!$#%$&! &%#! #%$&!$&%  )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-(!(+%*+!*-%(- +)$+,$-) -,#)(#,*&)*&,((!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&() +,$+)$-, -(#)*#,*&)(&,+!(+%*-!*-%(()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- )(#,*#)*&,(&(+!*+%*-!(-%+) +,$-)$-, ","I -4 3 m":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! #%$#!$&% & #!$#%$&! &%#! #%$&!$&% ()+*,+*)-(,-+()+*,-*)-(,)+(,+*)-*,-()(+,*+)*-,(-(+)*+,*-)(-,+)(+,*-)*-,(","P -4 3 n":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& )(+,*+)*-,(-(+)*+,*-)(-,+)(+,*-)*-,(","F -4 3 c":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& )(+,*+)*-,(-(+)*+,*-)(-,+)(+,*-)*-,( )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-() #,$#)$&, &(#!*#%*&!(&%+! +%$-!$-% (!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&(!(#%*#!*&%(& +!$+%$-! -%#) #,$&)$&, ()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- ! +%$+!$-% - #)$#,$&) &,#!(#%*&!*&%(","I -4 3 d":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&(7354<9:6>8;=357<946>:;=857394<>:6=8;()+$,#*!& %-+()#$,&*!- %)+(,#$!&*%- :;98657<=43>;9:658<=73>49:;586=7<>43","P 4/m -3 2/m":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! &%$&!$#% # #%$#!$&% &!#!$#% &! &%$$%& !& %#$!#&$%& !# %#$!%&$!& %# !#$%$#! #% &!$&$&! &% #!$#%&% &!$#%$#! ","P 4/n -3 2/n":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! &%$&!$#% # #%$#!$&% &!#!$#% &! &%$*,-()-(,+*)+-*,-()+(,+*),-*)-(,+()+*,*+)(+,(-)*-*-)(-,(+)*+,-,(-)*+,*+)(","P 42/m -3 2/n":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& )(-,*-)*+,(+(+,*+)*-,(-)+)*+,(-)(-,*$%& !& %#$!#&$%& !# %#$!%&$!& %# !#$,*+)(+,(-)*-*-)(-,(+)*+,-,(-)*+,*+)(","P 42/n -3 2/m":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& )(-,*-)*+,(+(+,*+)*-,(-)+)*+,(-)(-,**,-()-(,+*)+-*,-()+(,+*),-*)-(,+()+*%$#! #% &!$&$&! &% #!$#%&% &!$#%$#! ","F 4/m -3 2/m":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! &%$&!$#% # #%$#!$&% &!#!$#% &! &%$$%& !& %#$!#&$%& !# %#$!%&$!& %# !#$%$#! #% &!$&$&! &% #!$#%&% &!$#%$#!  )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-(!(-%*-!*+%(+ +,$+)$-, -)#)*#,(&)(&,*$,- )- ,+$)+&*,&()#(,#*)%-*!-(%+(!+*%*+!(+%(-!*-$-) -, +)$+,&,(&)*#,*#)((!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&() -,$-)$+, +(#,*#)*&,(&)+!*+%(-!(-%**%-(!-(%+*!+-$,- )+ ,+$),&*)&(,#()#*,$+) +, -)$-*&)(&,(#)*#,-%(-!*+%*+!(()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- )(&,*&)*#,(#(+%*+!*-%(-!+)$+, -) -,$*,&()&(,#*)#-*%-(!+(%+*!,-$)- ,+ )+$,*#)(#,(&)*&*-!(-%(+!*+%-, -)$+,$+) ","F 4/m -3 2/c":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& )(-,*-)*+,(+(+,*+)*-,(-)+)*+,(-)(-,*$%& !& %#$!#&$%& !# %#$!%&$!& %# !#$,*+)(+,(-)*-*-)(-,(+)*+,-,(-)*+,*+)( )+$,+$)- ,-#()#*,&*)&(,!+(%+*!-*%-() &,$&)$#, #(#%*#!*&%(&!+!$+% -! -%$$,- )- ,+$)+&*,&()#(,#*)%-*!-(%+(!+*,$#) #, &)$&*&!(&%(#!*#%-% -!$+%$+! (!+*%+*!-(%-+ )+$,-$)- ,)#(,#*)&*,&(!(&%*&!*#%(# +%$+!$-% -!#)$#, &) &,$*%-(!-(%+*!+-$,- )+ ,+$),&*)&(,#()#*%*#!(#%(&!*&$-! -% +!$+%&, &)$#,$#) ()#*,#*)&(,&+(!+*%-*!-(%)+ ,+$)-$,- ! -%$-!$+% + #,$#)$&, &)#!*#%(&!(&%**,&()&(,#*)#-*%-(!+(%+*!,-$)- ,+ )+$%$+! +% -!$-$&) &, #)$#,&%(&!*#%*#!(","F 41/d -3 2/m":" !#$,+*)&(%-# !+$,&*)-(%!# ,+$)&*%-(:3>46=7<98;5;58<976=43>:97<58;>:3=4664=3:>;85<79=64>3:5;89<74=6:>385;79<,$+! #%(-)*&*&)(-% #!$+,-%(&)*+,$#!  )+$%#*!-(,&#()+*%&$!- ,!+(,#*)-$%& :;=4<>765839;94<5:6>83=79:6543>7;=8<68>37=;49<:5=<8>;753496:4><:=;893756,*#!(+% &)$-*-!(&, +)$#%-, &!$+%*#)((!+*,#$)- %&+ )#$%-*!&(,)#(%+*!&$,- 73=86>:<54;935469:<=8;>7576983=:;>4<<4>;:=389675>68=379;45<:8=<7>;453:96%$#) +,(&!*-$&! -,(#)*+%&% -)$#,*+!(()#*%+$!& ,-+(!#*,-$)& %)+ %#$!-*,&(7;>8<=:69435398657<>4;=:5:<94;=73>86<8=;7>3456:9><4=;:9385678>67=349;:5<%*+)(#, -!$&$-) &%(+!*#,&,(-!*#%$+) ","F 41/d -3 2/c":" !#$,+*)&(%-# !+$,&*)-(%!# ,+$)&*%-(:3>46=7<98;5;58<976=43>:97<58;>:3=46<8>;7=3496:5><8=;793456:8><7=;493:56%*#)(+, &!$-$-! &,(+)*#%&, -!$#%*+)( )+$%#*!-(,&#()+*%&$!- ,!+(,#*)-$%& :;=4<>765839;94<5:6>83=79:6543>7;=8<<4=;:>385679>64=3:9;85<78=67>345;:9<%$+) #,(-!*&$&) -%(#!*+,&%(-)*#,$+! (!+*,#$)- %&+ )#$%-*!&(,)#(%+*!&$,- 73=86>:<54;935469:<=8;>7576983=:;>4<68=37>;45<:9=<4>;:5389674>6:=389;75<,*+!(#% -)$&*-)(&% +!$#,-,(&!*+%$#) ()#*%+$!& ,-+(!#*,-$)& %)+ %#$!-*,&(7;>8<=:69435398657<>4;=:5:<94;=73>8664>3:=;89<75=68>375;49<:4=<:>;853796,$#! +%(&)*-*&!(-, #)$+%-% &)$+,*#!(","I 4/m -3 2/m":" !#$%#$!& %&# !#$%&$!& %!# %#$!&$%& ! &%$&!$#% # #%$#!$&% &!#!$#% &! &%$$%& !& %#$!#&$%& !# %#$!%&$!& %# !#$%$#! #% &!$&$&! &% #!$#%&% &!$#%$#! ()+*,+*)-(,-+()+*,-*)-(,)+(,+*)-*,-()(-,*-)*+,(+(+,*+)*-,(-)+)*+,(-)(-,**,-()-(,+*)+-*,-()+(,+*),-*)-(,+()+*,*+)(+,(-)*-*-)(-,(+)*+,-,(-)*+,*+)(","I 41/a -3 2/d":" !#*%+$)-(,&# !+*%-$)&(,!# %+*)-$,&(:3=8<>7694;5;54697<>83=:97654;=:3>8<$%&(!- ,+*)#&$%-(!+ ,#*)%&$!-(,+ )#*4<97358;=:6>6>:;=8357<94=8;>:694<573()+$,#*!& %-+()#$,&*!- %)+(,#$!&*%- 7;>46=:<5839398<5:6=4;>75:<983>7;=46*,- )&(%#$!+-*,& )#(%+$!,-*)& %#(!+$865:;943>7<=<=73>4;9:658>43=7<5869:;","P 1 1 2":" !#$%#","P 1 1 21":" !#$%+","B 1 1 2":" !#$%#(g+*%+","A 1 2 1":" !#$!& )+$)-","C 1 21 1":" !#$)&()#*!&","I 1 2 1":" !#$!&.'/0'2","I 1 21 1":" !#$)&.'/0!-","P 1 1 m":" !# !&","P 1 1 b":" !# )&","B 1 1 m":" !# !&(!+(!-","B 1 1 b":" !# )&(!+()-","P 1 1 2/m":" !# !&$%#$%&","P 1 1 21/m":" !#$%+$%& !-","B 1 1 2/m":" !# !&$%#$%&(!+(!-*%+*%-","P 1 1 2/b":" !#$,#$%& )&","P 1 1 21/b":" !#$%&$,+ )-","B 1 1 2/b":" !#$,#$%& )&(!+*,+*%-()-","P 21 2 2":" !#$!&(%&*%#","P 2 21 2":" !# ,&$)&$%#","P 21 21 2 (a)":" !#*,#.%&$'&","P 21 2 21":" !#$!&(%-*%+","P 2 21 21":" !# %&$)-$,+","C 2 2 21a)":" !#*%+(,&$)-()#$,+ %&*!-","C 2 2 2a":" !#*,#.%&$'&()#$%# ,&*!&","F 2 2 2a":" !#*,#.%&$'& '/*%/.12$!2.!/$,/ %20'2.'#$%# 1&0!&","I 2 2 2a":" !#*,#.%&$'&()+$%+*!- ,-","P 21/m 21/m 2/n a":" !#*,#$)&(%&$%&.'& ,#*!#","P 42 21 2a":" !#*,#%.+'$+$'&.%&! -,*-","I 2 3a":" !#*,#.%&$'&!# ,- '&$%/$# !-*!/$%&.%()+$%+ ,-*!-)+(%&(!-*,#*+()&$)#*,- ,"},iv=function(t){this.name=t||"",this.partList=[]},rv={type:{}};rv.type.get=function(){return"Assembly"},iv.prototype.addPart=function(t,e){var i=new nv(t,e);return this.partList.push(i),i},iv.prototype._getCount=function(t,e){var i=0;return this.partList.forEach(function(r){i+=r[e](t)}),i},iv.prototype.getAtomCount=function(t){return this._getCount(t,"getAtomCount")},iv.prototype.getResidueCount=function(t){return this._getCount(t,"getResidueCount")},iv.prototype.getInstanceCount=function(){var t=0;return this.partList.forEach(function(e){t+=e.matrixList.length}),t},iv.prototype.isIdentity=function(t){if(1!==this.partList.length)return!1;var e=this.partList[0];if(1!==e.matrixList.length)return!1;if(!(new v).equals(e.matrixList[0]))return!1;var i=[];return t.eachChain(function(t){i.push(t.chainname)}),i=Mn(i),e.chainList.length===i.length},iv.prototype.getBoundingBox=function(t){var e=new st;return this.partList.forEach(function(i){var r=i.getBoundingBox(t);e.expandByPoint(r.min),e.expandByPoint(r.max)}),e},iv.prototype.getCenter=function(t){return this.getBoundingBox(t).getCenter()},iv.prototype.getSelection=function(){var t=[];return this.partList.forEach(function(e){t=t.concat(e.chainList)}),is(t)},Object.defineProperties(iv.prototype,rv);var nv=function(t,e){this.matrixList=t||[],this.chainList=e||[]},ov={type:{}};ov.type.get=function(){return"AssemblyPart"},nv.prototype._getCount=function(t,e){var i=0,r=this.chainList;return t.eachChain(function(t){(0===r.length||r.includes(t.chainname))&&(i+=t[e])}),this.matrixList.length*i},nv.prototype.getAtomCount=function(t){return this._getCount(t,"atomCount")},nv.prototype.getResidueCount=function(t){return this._getCount(t,"residueCount")},nv.prototype.getBoundingBox=function(t){var e=new st,i=new st,r=this.getSelection(),n=t.getBoundingBox(r);return this.matrixList.forEach(function(t){i.copy(n).applyMatrix4(t),e.expandByPoint(i.min),e.expandByPoint(i.max)}),e},nv.prototype.getSelection=function(){return is(this.chainList)},nv.prototype.getView=function(t){var e=this.getSelection();return e?t.getView(e):t},nv.prototype.getInstanceList=function(){for(var t=this,e=[],i=0,r=this.matrixList.length;i<r;++i)e.push({id:i+1,name:i,matrix:t.matrixList[i]});return e},Object.defineProperties(nv.prototype,ov);var av=function(){var e=function(t,e,i,r){for(var n=t.structure,o=t.residueIndexStart,a=n.getResidueProxy(),s=n.getResidueProxy(),c=n.getAtomProxy(),u=n.getAtomProxy(),h=Math.max(0,e-2);h<=e;++h)for(var l=2;l<5;++l)if(!(h+l>=t.residueCount)){a.index=o+h,s.index=o+h+l,c.index=a.traceAtomIndex,u.index=s.traceAtomIndex;var p=c.distanceTo(u);if(Math.abs(p-i[l-2])>r)return!1}return!0},i=function(t,i){return e(t,i,[5.45,5.18,6.37],2.1)},r=function(t,i){return e(t,i,[6.1,10.4,13],1.42)},n=function(t){for(var e=t.residueStore,n=t.residueIndexStart,o=0,a=t.residueCount;o<a;++o){var s="c";i(t,o)?s="h":r(t,o)&&(s="s"),e.sstruc[n+o]=s.charCodeAt(0)}},o=function(t){for(var e=t.residueStore,i=t.residueIndexStart,r=new Ka(t).position,n=new g,o=new g,a=0,s=t.residueCount;a<s;++a){n.fromArray(r.center,3*a),o.fromArray(r.center,3*a+3);var c=n.distanceTo(o);c<2&&c>1&&r.bending[a]<20&&(e.sstruc[i+a]="h".charCodeAt(0),e.sstruc[i+a+1]="h".charCodeAt(0))}};return function(e){t.Debug&&cf.time("calculateSecondaryStructure"),e.eachPolymer(function(t){if(!(t.residueCount<4)){if(t.isCg())o(t);else{if(!t.isProtein())return;n(t)}var e,i=0;t.eachResidue(function(t){t.sstruc===e?i+=1:(1===i&&(t.index-=1,t.sstruc="c"),i=1,e=t.sstruc)})}}),t.Debug&&cf.timeEnd("calculateSecondaryStructure")}}(),sv=["H","C","O","N","S","P"],cv=["NA","CL","FE"],uv=function(t,e,i){this.structure=t,i=i||ls(e),this.atomname=e,this.element=i,this.vdw=_g[i],this.covalent=wg[i]},hv=function(t){this.structure=t,this.dict={},this.list=[]};hv.prototype.add=function(t,e){var i=ds(t=t.toUpperCase(),e=e?e.toUpperCase():ls(t)),r=this.dict[i];if(void 0===r){var n=new uv(this.structure,t,e);r=this.list.length,this.dict[i]=r,this.list.push(n)}return r},hv.prototype.get=function(t){return this.list[t]};var lv=function(t,e,i,r,n,o){this.structure=t,this.resname=e,this.atomTypeIdList=i,this.hetero=r?1:0,this.chemCompType=n,this.bonds=o,this.rings=void 0,this.atomCount=i.length,this.moleculeType=this.getMoleculeType(),this.backboneType=this.getBackboneType(0),this.backboneEndType=this.getBackboneType(-1),this.backboneStartType=this.getBackboneType(1),this.backboneIndexList=this.getBackboneIndexList();var a=Ng[this.backboneType],s=Ng[this.backboneStartType],c=Ng[this.backboneEndType],u=this.getAtomIndexByName(a.trace);this.traceAtomIndex=void 0!==u?u:-1;var h=this.getAtomIndexByName(a.direction1);this.direction1AtomIndex=void 0!==h?h:-1;var l=this.getAtomIndexByName(a.direction2);this.direction2AtomIndex=void 0!==l?l:-1;var p=this.getAtomIndexByName(s.backboneStart);this.backboneStartAtomIndex=void 0!==p?p:-1;var d=this.getAtomIndexByName(c.backboneEnd);this.backboneEndAtomIndex=void 0!==d?d:-1;var f;f=Cg.includes(e)?this.getAtomIndexByName("N1"):this.getAtomIndexByName("N3"),this.rungEndAtomIndex=void 0!==f?f:-1,this.bondReferenceAtomIndices=[]};lv.prototype.getBackboneIndexList=function(){var t,e=[];switch(this.moleculeType){case 3:t=Og;break;case 4:case 5:t=Dg;break;default:return e}for(var i=this.structure.atomMap,r=this.atomTypeIdList,n=0,o=this.atomCount;n<o;++n){var a=i.get(r[n]);t.includes(a.atomname)&&e.push(n)}return e},lv.prototype.getMoleculeType=function(){return this.isProtein()?3:this.isRna()?4:this.isDna()?5:this.isWater()?1:this.isIon()?2:this.isSaccharide()?6:0},lv.prototype.getBackboneType=function(t){return this.hasProteinBackbone(t)?1:this.hasRnaBackbone(t)?2:this.hasDnaBackbone(t)?3:this.hasCgProteinBackbone(t)?4:this.hasCgRnaBackbone(t)?5:this.hasCgDnaBackbone(t)?6:lg},lv.prototype.isProtein=function(){return this.chemCompType?pg.includes(this.chemCompType):this.hasAtomWithName("CA","C","N")||Pg.includes(this.resname)},lv.prototype.isCg=function(){var t=this.backboneType;return 4===t||5===t||6===t},lv.prototype.isNucleic=function(){return this.isRna()||this.isDna()},lv.prototype.isRna=function(){return this.chemCompType?dg.includes(this.chemCompType):this.hasAtomWithName(["P","O3'","O3*"],["C4'","C4*"],["O2'","O2*","F2'","F2*"])||Tg.includes(this.resname)&&this.hasAtomWithName(["O2'","O2*","F2'","F2*"])},lv.prototype.isDna=function(){return this.chemCompType?fg.includes(this.chemCompType):this.hasAtomWithName(["P","O3'","O3*"],["C3'","C3*"])&&!this.hasAtomWithName(["O2'","O2*","F2'","F2*"])||Eg.includes(this.resname)},lv.prototype.isHetero=function(){return 1===this.hetero},lv.prototype.isIon=function(){return Lg.includes(this.resname)},lv.prototype.isWater=function(){return Ig.includes(this.resname)},lv.prototype.isSaccharide=function(){return this.chemCompType?mg.includes(this.chemCompType):Rg.includes(this.resname)},lv.prototype.hasBackboneAtoms=function(t,e){var i=Ng[e];return-1===t?this.hasAtomWithName(i.trace,i.backboneEnd,i.direction1,i.direction2):0===t?this.hasAtomWithName(i.trace,i.direction1,i.direction2):1===t?this.hasAtomWithName(i.trace,i.backboneStart,i.direction1,i.direction2):this.hasAtomWithName(i.trace,i.backboneStart,i.backboneEnd,i.direction1,i.direction2)},lv.prototype.hasProteinBackbone=function(t){return this.isProtein()&&this.hasBackboneAtoms(t,1)},lv.prototype.hasRnaBackbone=function(t){return this.isRna()&&this.hasBackboneAtoms(t,2)},lv.prototype.hasDnaBackbone=function(t){return this.isDna()&&this.hasBackboneAtoms(t,3)},lv.prototype.hasCgProteinBackbone=function(t){return this.isProtein()&&this.hasBackboneAtoms(t,4)},lv.prototype.hasCgRnaBackbone=function(t){return this.isRna()&&this.hasBackboneAtoms(t,5)},lv.prototype.hasCgDnaBackbone=function(t){return this.isDna()&&this.hasBackboneAtoms(t,6)},lv.prototype.hasBackbone=function(t){return this.hasProteinBackbone(t)||this.hasRnaBackbone(t)||this.hasDnaBackbone(t)||this.hasCgProteinBackbone(t)||this.hasCgRnaBackbone(t)||this.hasCgDnaBackbone(t)},lv.prototype.getAtomIndexByName=function(t){var e=this.atomCount,i=this.structure.atomMap,r=this.atomTypeIdList;if(Array.isArray(t))for(var n=0;n<e;++n){var o=r[n];if(t.includes(i.get(o).atomname))return n}else for(var a=0;a<e;++a){var s=r[a];if(t===i.get(s).atomname)return a}},lv.prototype.hasAtomWithName=function(){for(var t=arguments,e=this,i=arguments.length,r=0;r<i;++r)if(void 0!==t[r]&&void 0===e.getAtomIndexByName(t[r]))return!1;return!0},lv.prototype.getBonds=function(t){return void 0===this.bonds&&(this.bonds=as(t)),this.bonds},lv.prototype.getRings=function(){return void 0===this.rings&&this.calculateRings(),this.rings},lv.prototype.getBondGraph=function(){return void 0===this.bondGraph&&this.calculateBondGraph(),this.bondGraph},lv.prototype.calculateBondGraph=function(){for(var t=this.bondGraph={},e=this.getBonds(),i=e.atomIndices1.length,r=e.atomIndices1,n=e.atomIndices2,o=0;o<i;++o){var a=r[o],s=n[o];(t[a]=t[a]||[]).push(s),(t[s]=t[s]||[]).push(a)}},lv.prototype.calculateRings=function(){function t(a,s,c){if(i[a])throw Error("DFS revisited atom");i[a]=1,o.push(a);for(var u=s.length,h=0;h<u;++h){var l=s[h];if(0===i[l])e[l]&&e[l].length>=2?t(l,e[l],a):i[l]=2;else if(1===i[l]&&c&&c!=l){var p=[l];r[l]=1,n.push(p);for(var d=o.length-1;d>=0;--d){var f=o[d];if(f===l)break;p.push(f),r[f]=1}}}i[a]=2,o.pop()}for(var e=this.getBondGraph(),i=new Int8Array(this.atomCount),r=new Int8Array(this.atomCount),n=[],o=[],a=0;a<this.atomCount;++a)if(!i[a]){var s=e[a];!s||s.length<2?i[a]=2:(o.length=0,t(a,s))}this.rings={flags:r,rings:n}},lv.prototype.assignBondReferenceAtomIndices=function(){var t=this.getBondGraph(),e=this.getRings(),i=e.flags,r=e.rings,n=this.bonds.atomIndices1,o=this.bonds.atomIndices2,a=this.bonds.bondOrders,s=this.bondReferenceAtomIndices,c=this.bonds.atomIndices1.length;s.length=0;for(var u=0;u<c;++u)if(!(a[u]<=1)){var h=n[u],l=o[u];if(i[h]&&i[l]){for(var p=0;p<r.length&&void 0===s[u];++p)for(var d=r[p],f=null,m=!1,g=0;g<d.length;++g){var v=d[g];if(v===h||v===l?m=!0:f=v,m&&null!==f){s[u]=f;break}}if(void 0!==s[u])continue}if(t[h].length>1)for(var y=0;y<t[h].length;++y){var b=t[h][y];if(b!==l){s[u]=b;break}}else if(t[l].length>1)for(var x=0;x<t[l].length;++x){var _=t[l][x];if(_!==h){s[u]=_;break}}else;}},lv.prototype.getBondIndex=function(t,e){for(var i=this.bonds,r=i.atomIndices1,n=i.atomIndices2,o=r.indexOf(t),a=n.indexOf(e),s=a;-1!==o;){for(;-1!==a;){if(o===a)return o;a=n.indexOf(e,a+1)}o=r.indexOf(t,o+1),a=s}},lv.prototype.getBondReferenceAtomIndex=function(t,e){var i=this.getBondIndex(t,e);if(void 0!==i)return 0===this.bondReferenceAtomIndices.length&&this.assignBondReferenceAtomIndices(),this.bondReferenceAtomIndices[i]};var pv=function(t){this.structure=t,this.dict={},this.list=[]};pv.prototype.add=function(t,e,i,r,n){var o=fs(t=t.toUpperCase(),e,i,r),a=this.dict[o];if(void 0===a){var s=new lv(this.structure,t,e,i,r,n);a=this.list.length,this.dict[o]=a,this.list.push(s)}return a},pv.prototype.get=function(t){return this.list[t]};var dv=function(t,e){this.structure=t,this.bondStore=t.bondStore,this.index=e,this._v12=new g,this._v13=new g,this._ap1=this.structure.getAtomProxy(),this._ap2=this.structure.getAtomProxy(),this._ap3=this.structure.getAtomProxy()},fv={atom1:{},atom2:{},atomIndex1:{},atomIndex2:{},bondOrder:{}};fv.atom1.get=function(){return this.structure.getAtomProxy(this.atomIndex1)},fv.atom2.get=function(){return this.structure.getAtomProxy(this.atomIndex2)},fv.atomIndex1.get=function(){return this.bondStore.atomIndex1[this.index]},fv.atomIndex1.set=function(t){this.bondStore.atomIndex1[this.index]=t},fv.atomIndex2.get=function(){return this.bondStore.atomIndex2[this.index]},fv.atomIndex2.set=function(t){this.bondStore.atomIndex2[this.index]=t},fv.bondOrder.get=function(){return this.bondStore.bondOrder[this.index]},fv.bondOrder.set=function(t){this.bondStore.bondOrder[this.index]=t},dv.prototype.getReferenceAtomIndex=function(){var t=this._ap1,e=this._ap2;if(t.index=this.atomIndex1,e.index=this.atomIndex2,t.residueIndex===e.residueIndex){var i=t.index-t.residueAtomOffset,r=e.index-e.residueAtomOffset,n=t.residueType.getBondReferenceAtomIndex(i,r);if(void 0!==n)return n+t.residueAtomOffset;console.warn("No reference atom found",t.index,e.index)}},dv.prototype.calculateShiftDir=function(t){t||(t=new g);var e=this._ap1,i=this._ap2,r=this._ap3,n=this._v12,o=this._v13;e.index=this.atomIndex1,i.index=this.atomIndex2;var a=this.getReferenceAtomIndex();n.subVectors(e,i).normalize(),void 0!==a?(r.index=a,o.subVectors(e,r)):o.copy(e),o.normalize();var s=n.dot(o);return 1-Math.abs(s)<1e-5&&(o.set(1,0,0),s=n.dot(o),1-Math.abs(s)<1e-5&&(o.set(0,1,0),s=n.dot(o))),t.copy(o.sub(n.multiplyScalar(s))).normalize()},dv.prototype.qualifiedName=function(){return this.atomIndex1+"="+this.atomIndex2},dv.prototype.clone=function(){return new this.constructor(this.structure,this.index)},dv.prototype.toObject=function(){return{atomIndex1:this.atomIndex1,atomIndex2:this.atomIndex2,bondOrder:this.bondOrder}},Object.defineProperties(dv.prototype,fv);var mv=function(t,e){this.structure=t,this.chainStore=t.chainStore,this.residueStore=t.residueStore,this.atomStore=t.atomStore,this.residueMap=t.residueMap,this.atomMap=t.atomMap,this.index=e},gv={bondHash:{},entity:{},entityIndex:{},modelIndex:{},chainIndex:{},residue:{},residueIndex:{},sstruc:{},inscode:{},resno:{},chainname:{},chainid:{},residueType:{},atomType:{},residueAtomOffset:{},resname:{},hetero:{},atomname:{},element:{},vdw:{},covalent:{},x:{},y:{},z:{},serial:{},bfactor:{},occupancy:{},altloc:{}};gv.bondHash.get=function(){return this.structure.bondHash},gv.entity.get=function(){return this.structure.entityList[this.entityIndex]},gv.entityIndex.get=function(){return this.chainStore.entityIndex[this.chainIndex]},gv.modelIndex.get=function(){return this.chainStore.modelIndex[this.chainIndex]},gv.chainIndex.get=function(){return this.residueStore.chainIndex[this.residueIndex]},gv.residue.get=function(){return console.warn("residue - might be expensive"),this.structure.getResidueProxy(this.residueIndex)},gv.residueIndex.get=function(){return this.atomStore.residueIndex[this.index]},gv.residueIndex.set=function(t){this.atomStore.residueIndex[this.index]=t},gv.sstruc.get=function(){return this.residueStore.getSstruc(this.residueIndex)},gv.inscode.get=function(){return this.residueStore.getInscode(this.residueIndex)},gv.resno.get=function(){return this.residueStore.resno[this.residueIndex]},gv.chainname.get=function(){return this.chainStore.getChainname(this.chainIndex)},gv.chainid.get=function(){return this.chainStore.getChainid(this.chainIndex)},gv.residueType.get=function(){return this.residueMap.get(this.residueStore.residueTypeId[this.residueIndex])},gv.atomType.get=function(){return this.atomMap.get(this.atomStore.atomTypeId[this.index])},gv.residueAtomOffset.get=function(){return this.residueStore.atomOffset[this.residueIndex]},gv.resname.get=function(){return this.residueType.resname},gv.hetero.get=function(){return this.residueType.hetero},gv.atomname.get=function(){return this.atomType.atomname},gv.element.get=function(){return this.atomType.element},gv.vdw.get=function(){return this.atomType.vdw},gv.covalent.get=function(){return this.atomType.covalent},gv.x.get=function(){return this.atomStore.x[this.index]},gv.x.set=function(t){this.atomStore.x[this.index]=t},gv.y.get=function(){return this.atomStore.y[this.index]},gv.y.set=function(t){this.atomStore.y[this.index]=t},gv.z.get=function(){return this.atomStore.z[this.index]},gv.z.set=function(t){this.atomStore.z[this.index]=t},gv.serial.get=function(){return this.atomStore.serial[this.index]},gv.serial.set=function(t){this.atomStore.serial[this.index]=t},gv.bfactor.get=function(){return this.atomStore.bfactor[this.index]},gv.bfactor.set=function(t){this.atomStore.bfactor[this.index]=t},gv.occupancy.get=function(){return this.atomStore.occupancy[this.index]},gv.occupancy.set=function(t){this.atomStore.occupancy[this.index]=t},gv.altloc.get=function(){return this.atomStore.getAltloc(this.index)},gv.altloc.set=function(t){this.atomStore.setAltloc(this.index,t)},mv.prototype.eachBond=function(t,e){e=e||this.structure._bp;for(var i=this.index,r=this.bondHash,n=r.indexArray,o=r.countArray[i],a=r.offsetArray[i],s=0;s<o;++s)e.index=n[a+s],t(e)},mv.prototype.eachBondedAtom=function(t,e){e=e||this.structure._ap;var i=this.index;this.eachBond(function(r){i!==r.atomIndex1?e.index=r.atomIndex1:e.index=r.atomIndex2,t(e)})},mv.prototype.isBackbone=function(){var t=this.residueType.backboneIndexList;if(t.length>0){var e=this.residueStore.atomOffset[this.residueIndex];return t.includes(this.index-e)}return!1},mv.prototype.isPolymer=function(){if(this.structure.entityList.length>0)return this.entity.isPolymer();var t=this.residueType.moleculeType;return 3===t||4===t||5===t},mv.prototype.isSidechain=function(){return this.isPolymer()&&!this.isBackbone()},mv.prototype.isCg=function(){var t=this.residueType.backboneType;return 4===t||5===t||6===t},mv.prototype.isHetero=function(){return 1===this.residueType.hetero},mv.prototype.isProtein=function(){return 3===this.residueType.moleculeType},mv.prototype.isNucleic=function(){var t=this.residueType.moleculeType;return 4===t||5===t},mv.prototype.isRna=function(){return 4===this.residueType.moleculeType},mv.prototype.isDna=function(){return 5===this.residueType.moleculeType},mv.prototype.isWater=function(){return 1===this.residueType.moleculeType},mv.prototype.isIon=function(){return 2===this.residueType.moleculeType},mv.prototype.isSaccharide=function(){return 6===this.residueType.moleculeType},mv.prototype.isHelix=function(){return yg.includes(this.sstruc)},mv.prototype.isSheet=function(){return bg.includes(this.sstruc)},mv.prototype.isTurn=function(){return xg.includes(this.sstruc)&&this.isProtein()},mv.prototype.isBonded=function(){return 0!==this.bondHash.countArray[this.index]},mv.prototype.isRing=function(){return 1===this.residueType.getRings().flags[this.index-this.residueAtomOffset]},mv.prototype.distanceTo=function(t){var e=this.atomStore,i=t.atomStore,r=this.index,n=t.index,o=e.x[r]-i.x[n],a=e.y[r]-i.y[n],s=e.z[r]-i.z[n],c=o*o+a*a+s*s;return Math.sqrt(c)},mv.prototype.connectedTo=function(t){var e=this.atomStore,i=t.atomStore,r=this.index,n=t.index;if(e.altloc&&i.altloc){var o=e.altloc[r],a=i.altloc[n];if(0!==o&&0!==a&&32!==o&&32!==a&&o!==a)return!1}var s=e.x[r]-i.x[n],c=e.y[r]-i.y[n],u=e.z[r]-i.z[n],h=s*s+c*c+u*u;if(h<64&&this.isCg())return!0;if(isNaN(h))return!1;var l=this.covalent+t.covalent,p=l+.3,d=l-.5;return h<p*p&&h>d*d},mv.prototype.positionFromArray=function(t,e){return void 0===e&&(e=0),this.x=t[e+0],this.y=t[e+1],this.z=t[e+2],this},mv.prototype.positionToArray=function(t,e){void 0===t&&(t=[]),void 0===e&&(e=0);var i=this.index,r=this.atomStore;return t[e+0]=r.x[i],t[e+1]=r.y[i],t[e+2]=r.z[i],t},mv.prototype.positionToVector3=function(t){return void 0===t&&(t=new g),t.x=this.x,t.y=this.y,t.z=this.z,t},mv.prototype.positionFromVector3=function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this},mv.prototype.getResidueBonds=function(t){var e,i,r,n,o=this.residueAtomOffset,a=this.index-this.residueAtomOffset,s=this.residueType.getBonds(),c=s.atomIndices1,u=s.atomIndices2;for(t||(n=[]),e=c.indexOf(a);-1!==e;){if(r=u[e]+o,t)return r;n.push(r),e=c.indexOf(a,e+1)}for(i=u.indexOf(a);-1!==i;){if(r=c[i]+o,t)return r;n.push(r),i=u.indexOf(a,i+1)}return n},mv.prototype.qualifiedName=function(t){var e="";return this.resname&&!t&&(e+="["+this.resname+"]"),void 0!==this.resno&&(e+=this.resno),this.inscode&&(e+="^"+this.inscode),this.chainname&&(e+=":"+this.chainname),this.atomname&&(e+="."+this.atomname),this.altloc&&(e+="%"+this.altloc),this.structure.modelStore.count>1&&(e+="/"+this.modelIndex),e},mv.prototype.clone=function(){return new this.constructor(this.structure,this.index)},mv.prototype.toObject=function(){return{index:this.index,residueIndex:this.residueIndex,atomno:this.atomno,resname:this.resname,x:this.x,y:this.y,z:this.z,element:this.element,chainname:this.chainname,resno:this.resno,serial:this.serial,vdw:this.vdw,covalent:this.covalent,hetero:this.hetero,bfactor:this.bfactor,altloc:this.altloc,atomname:this.atomname,modelindex:this.modelindex}},Object.defineProperties(mv.prototype,gv);var vv=function(t,e){this.structure=t,this.chainStore=t.chainStore,this.residueStore=t.residueStore,this.atomStore=t.atomStore,this.residueMap=t.residueMap,this.atomMap=t.atomMap,this.index=e},yv={entity:{},entityIndex:{},chain:{},chainIndex:{},atomOffset:{},atomCount:{},atomEnd:{},modelIndex:{},chainname:{},chainid:{},resno:{},sstruc:{},inscode:{},residueType:{},resname:{},hetero:{},moleculeType:{},backboneType:{},backboneStartType:{},backboneEndType:{},traceAtomIndex:{},direction1AtomIndex:{},direction2AtomIndex:{},backboneStartAtomIndex:{},backboneEndAtomIndex:{},rungEndAtomIndex:{}};yv.entity.get=function(){return this.structure.entityList[this.entityIndex]},yv.entityIndex.get=function(){return this.chainStore.entityIndex[this.chainIndex]},yv.chain.get=function(){return this.structure.getChainProxy(this.chainIndex)},yv.chainIndex.get=function(){return this.residueStore.chainIndex[this.index]},yv.chainIndex.set=function(t){this.residueStore.chainIndex[this.index]=t},yv.atomOffset.get=function(){return this.residueStore.atomOffset[this.index]},yv.atomOffset.set=function(t){this.residueStore.atomOffset[this.index]=t},yv.atomCount.get=function(){return this.residueStore.atomCount[this.index]},yv.atomCount.set=function(t){this.residueStore.atomCount[this.index]=t},yv.atomEnd.get=function(){return this.atomOffset+this.atomCount-1},yv.modelIndex.get=function(){return this.chainStore.modelIndex[this.chainIndex]},yv.chainname.get=function(){return this.chainStore.getChainname(this.chainIndex)},yv.chainid.get=function(){return this.chainStore.getChainid(this.chainIndex)},yv.resno.get=function(){return this.residueStore.resno[this.index]},yv.resno.set=function(t){this.residueStore.resno[this.index]=t},yv.sstruc.get=function(){return this.residueStore.getSstruc(this.index)},yv.sstruc.set=function(t){this.residueStore.setSstruc(this.index,t)},yv.inscode.get=function(){return this.residueStore.getInscode(this.index)},yv.inscode.set=function(t){this.residueStore.getInscode(this.index,t)},yv.residueType.get=function(){return this.residueMap.get(this.residueStore.residueTypeId[this.index])},yv.resname.get=function(){return this.residueType.resname},yv.hetero.get=function(){return this.residueType.hetero},yv.moleculeType.get=function(){return this.residueType.moleculeType},yv.backboneType.get=function(){return this.residueType.backboneType},yv.backboneStartType.get=function(){return this.residueType.backboneStartType},yv.backboneEndType.get=function(){return this.residueType.backboneEndType},yv.traceAtomIndex.get=function(){return this.residueType.traceAtomIndex+this.atomOffset},yv.direction1AtomIndex.get=function(){return this.residueType.direction1AtomIndex+this.atomOffset},yv.direction2AtomIndex.get=function(){return this.residueType.direction2AtomIndex+this.atomOffset},yv.backboneStartAtomIndex.get=function(){return this.residueType.backboneStartAtomIndex+this.atomOffset},yv.backboneEndAtomIndex.get=function(){return this.residueType.backboneEndAtomIndex+this.atomOffset},yv.rungEndAtomIndex.get=function(){return this.residueType.rungEndAtomIndex+this.atomOffset},vv.prototype.eachAtom=function(t,e){var i,r=this.atomCount,n=this.atomOffset,o=this.structure._ap,a=n+r;if(e&&e.atomOnlyTest){var s=e.atomOnlyTest;for(i=n;i<a;++i)o.index=i,s(o)&&t(o)}else for(i=n;i<a;++i)o.index=i,t(o)},vv.prototype.isProtein=function(){return 3===this.residueType.moleculeType},vv.prototype.isNucleic=function(){var t=this.residueType.moleculeType;return 4===t||5===t},vv.prototype.isRna=function(){return 4===this.residueType.moleculeType},vv.prototype.isDna=function(){return 5===this.residueType.moleculeType},vv.prototype.isCg=function(){var t=this.residueType.backboneType;return 4===t||5===t||6===t},vv.prototype.isPolymer=function(){if(this.structure.entityList.length>0)return this.entity.isPolymer();var t=this.residueType.moleculeType;return 3===t||4===t||5===t},vv.prototype.isHetero=function(){return 1===this.residueType.hetero},vv.prototype.isWater=function(){return 1===this.residueType.moleculeType},vv.prototype.isIon=function(){return 2===this.residueType.moleculeType},vv.prototype.isSaccharide=function(){return 6===this.residueType.moleculeType},vv.prototype.isHelix=function(){return yg.includes(this.sstruc)},vv.prototype.isSheet=function(){return bg.includes(this.sstruc)},vv.prototype.isTurn=function(){return xg.includes(this.sstruc)&&this.isProtein()},vv.prototype.getAtomType=function(t){return this.atomMap.get(this.atomStore.atomTypeId[t])},vv.prototype.getResname1=function(){return Mg[this.resname.toUpperCase()]||"X"},vv.prototype.getBackboneType=function(t){switch(t){case-1:return this.residueType.backboneStartType;case 1:return this.residueType.backboneEndType;default:return this.residueType.backboneType}},vv.prototype.getAtomIndexByName=function(t){var e=this.residueType.getAtomIndexByName(t);return void 0!==e&&(e+=this.atomOffset),e},vv.prototype.getAtomByName=function(t){return this.residueType.getAtomByName(t)},vv.prototype.hasAtomWithName=function(t){return this.residueType.hasAtomWithName(t)},vv.prototype.getAtomnameList=function(){var t=this;console.warn("getAtomnameList - might be expensive");for(var e=this.atomCount,i=this.atomOffset,r=new Array(e),n=0;n<e;++n)r[n]=t.getAtomType(i+n).atomname;return r},vv.prototype.connectedTo=function(t){var e=this.structure.getAtomProxy(this.backboneEndAtomIndex),i=this.structure.getAtomProxy(t.backboneStartAtomIndex);return!(!e||!i)&&e.connectedTo(i)},vv.prototype.getNextConnectedResidue=function(){var t=this.chainStore.residueOffset[this.chainIndex],e=this.chainStore.residueCount[this.chainIndex],i=this.index+1;if(i<t+e){var r=this.structure.getResidueProxy(i);if(this.connectedTo(r))return r}else if(i===t+e){var n=this.structure.getResidueProxy(t);if(this.connectedTo(n))return n}},vv.prototype.getPreviousConnectedResidue=function(){var t=this.chainStore.residueOffset[this.chainIndex],e=this.index-1;if(e>=t){var i=this.structure.getResidueProxy(e);if(i.connectedTo(this))return i}else if(e===t-1){var r=this.chainStore.residueCount[this.chainIndex],n=this.structure.getResidueProxy(t+r-1);if(n.connectedTo(this))return n}},vv.prototype.getBonds=function(){return this.residueType.getBonds(this)},vv.prototype.getRings=function(){return this.residueType.getRings()},vv.prototype.qualifiedName=function(t){var e="";return this.resname&&!t&&(e+="["+this.resname+"]"),void 0!==this.resno&&(e+=this.resno),this.inscode&&(e+="^"+this.inscode),this.chain&&(e+=":"+this.chainname),e+="/"+this.modelIndex},vv.prototype.clone=function(){return new this.constructor(this.structure,this.index)},vv.prototype.toObject=function(){return{index:this.index,chainIndex:this.chainIndex,atomOffset:this.atomOffset,atomCount:this.atomCount,resno:this.resno,resname:this.resname,sstruc:this.sstruc}},Object.defineProperties(vv.prototype,yv);var bv=function(t,e,i){this.structure=t,this.chainStore=t.chainStore,this.residueStore=t.residueStore,this.atomStore=t.atomStore,this.residueIndexStart=e,this.residueIndexEnd=i,this.residueCount=i-e+1;var r=this.structure.getResidueProxy(this.residueIndexStart),n=this.structure.getResidueProxy(this.residueIndexEnd);this.isPrevConnected=void 0!==r.getPreviousConnectedResidue();var o=n.getNextConnectedResidue();this.isNextConnected=void 0!==o,this.isNextNextConnected=this.isNextConnected&&void 0!==o.getNextConnectedResidue(),this.isCyclic=n.connectedTo(r),this.__residueProxy=this.structure.getResidueProxy()},xv={chainIndex:{},modelIndex:{},chainname:{}};xv.chainIndex.get=function(){return this.residueStore.chainIndex[this.residueIndexStart]},xv.modelIndex.get=function(){return this.chainStore.modelIndex[this.chainIndex]},xv.chainname.get=function(){return this.chainStore.getChainname(this.chainIndex)},bv.prototype.isProtein=function(){return this.__residueProxy.index=this.residueIndexStart,this.__residueProxy.isProtein()},bv.prototype.isCg=function(){return this.__residueProxy.index=this.residueIndexStart,this.__residueProxy.isCg()},bv.prototype.isNucleic=function(){return this.__residueProxy.index=this.residueIndexStart,this.__residueProxy.isNucleic()},bv.prototype.getMoleculeType=function(){return this.__residueProxy.index=this.residueIndexStart,this.__residueProxy.moleculeType},bv.prototype.getBackboneType=function(t){return this.__residueProxy.index=this.residueIndexStart,this.__residueProxy.getBackboneType(t)},bv.prototype.getAtomIndexByType=function(t,e){this.isCyclic?-1===t?t=this.residueCount-1:t===this.residueCount&&(t=0):(-1!==t||this.isPrevConnected||(t+=1),t!==this.residueCount||this.isNextNextConnected||(t-=1));var i=this.__residueProxy;i.index=this.residueIndexStart+t;var r;switch(e){case"trace":r=i.traceAtomIndex;break;case"direction1":r=i.direction1AtomIndex;break;case"direction2":r=i.direction2AtomIndex;break;default:var n=i.getAtomByName(e);r=n?n.index:void 0}return r},bv.prototype.eachAtom=function(t,e){this.eachResidue(function(i){i.eachAtom(t,e)},e)},bv.prototype.eachAtomN=function(t,e,i){var r,n=this,o=this.residueCount,a=new Array(t);for(r=0;r<t;++r)a[r]=n.structure.getAtomProxy(n.getAtomIndexByType(r,i));e.apply(this,a);for(var s=t;s<o;++s){for(r=1;r<t;++r)a[r-1].index=a[r].index;a[t-1].index=n.getAtomIndexByType(s,i),e.apply(n,a)}},bv.prototype.eachAtomN2=function(t,e,i){var r=this,n=this.atomOffset,o=this.atomCount,a=n+o;if(!(o<t)){for(var s=new Array(t),c=0;c<t;++c)s[c]=r.structure.getAtomProxy();var u=this.structure.atomSetCache["__"+i];void 0===u&&(cf.warn("no precomputed atomSet for: "+i),u=this.structure.getAtomSet(!1),this.eachResidue(function(t){var e=t.getAtomByName(i);u.set(e.index)}));var h=0;u.forEach(function(i){if(i>=n&&i<a){for(var r=1;r<t;++r)s[r-1].index=s[r].index;s[t-1].index=i,(h+=1)>=t&&e.apply(this,s)}})}},bv.prototype.eachResidue=function(t){for(var e=this.structure.getResidueProxy(),i=this.residueCount,r=this.residueIndexStart,n=0;n<i;++n)e.index=r+n,t(e)},bv.prototype.qualifiedName=function(){var t=this.structure.getResidueProxy(this.residueIndexStart),e=this.structure.getResidueProxy(this.residueIndexEnd);return t.qualifiedName()+" - "+e.qualifiedName()},Object.defineProperties(bv.prototype,xv);var _v=function(t,e){this.structure=t,this.chainStore=t.chainStore,this.residueStore=t.residueStore,this.index=e},wv={entity:{},model:{},entityIndex:{},modelIndex:{},residueOffset:{},residueCount:{},residueEnd:{},atomOffset:{},atomEnd:{},atomCount:{},chainname:{},chainid:{}};wv.entity.get=function(){return this.structure.entityList[this.entityIndex]},wv.model.get=function(){return this.structure.getModelProxy(this.modelIndex)},wv.entityIndex.get=function(){return this.chainStore.entityIndex[this.index]},wv.entityIndex.set=function(t){this.chainStore.entityIndex[this.index]=t},wv.modelIndex.get=function(){return this.chainStore.modelIndex[this.index]},wv.modelIndex.set=function(t){this.chainStore.modelIndex[this.index]=t},wv.residueOffset.get=function(){return this.chainStore.residueOffset[this.index]},wv.residueOffset.set=function(t){this.chainStore.residueOffset[this.index]=t},wv.residueCount.get=function(){return this.chainStore.residueCount[this.index]},wv.residueCount.set=function(t){this.chainStore.residueCount[this.index]=t},wv.residueEnd.get=function(){return this.residueOffset+this.residueCount-1},wv.atomOffset.get=function(){return this.residueStore.atomOffset[this.residueOffset]},wv.atomEnd.get=function(){return this.residueStore.atomOffset[this.residueEnd]+this.residueStore.atomCount[this.residueEnd]-1},wv.atomCount.get=function(){return 0===this.residueCount?0:this.atomEnd-this.atomOffset+1},wv.chainname.get=function(){return this.chainStore.getChainname(this.index)},wv.chainname.set=function(t){this.chainStore.setChainname(this.index,t)},wv.chainid.get=function(){return this.chainStore.getChainid(this.index)},wv.chainid.set=function(t){this.chainStore.setChainid(this.index,t)},_v.prototype.eachAtom=function(t,e){this.eachResidue(function(i){i.eachAtom(t,e)},e)},_v.prototype.eachResidue=function(t,e){var i,r=this.residueCount,n=this.residueOffset,o=this.structure._rp,a=n+r;if(e&&e.test){var s=e.residueOnlyTest;if(s)for(i=n;i<a;++i)o.index=i,s(o)&&t(o,e);else for(i=n;i<a;++i)o.index=i,t(o,e)}else for(i=n;i<a;++i)o.index=i,t(o)},_v.prototype.eachResidueN=function(t,e){var i,r=this,n=this.residueCount,o=this.residueOffset,a=o+n;if(!(n<t)){var s=new Array(t);for(i=0;i<t;++i)s[i]=r.structure.getResidueProxy(o+i);e.apply(this,s);for(var c=o+t;c<a;++c){for(i=0;i<t;++i)s[i].index+=1;e.apply(r,s)}}},_v.prototype.eachPolymer=function(t,e){for(var i,r,n=e?e.residueOnlyTest:void 0,o=this.model.structure,a=this.residueCount,s=this.residueOffset,c=s+a,u=this.structure.getResidueProxy(),h=this.structure.getResidueProxy(s),l=this.structure.getAtomProxy(),p=this.structure.getAtomProxy(),d=!0,f=s+1;f<c;++f){u.index=h.index,h.index=f,d&&(i=u.index,d=!1),r=h.index;var m=d?u.backboneEndType:u.backboneType,g=h.backboneType;m!==lg&&m===g?(l.index=u.backboneEndAtomIndex,p.index=h.backboneStartAtomIndex,l&&p&&l.connectedTo(p)&&(!n||n(u)&&n(h))||(u.index-i>1&&t(new bv(o,i,u.index)),i=r)):(m!==lg&&u.index-i>1&&t(new bv(o,i,u.index)),i=r)}r-i>1&&this.structure.getResidueProxy(i).backboneStartType&&t(new bv(o,i,r))},_v.prototype.qualifiedName=function(){return":"+this.chainname+"/"+this.modelIndex},_v.prototype.clone=function(){return new this.constructor(this.structure,this.index)},_v.prototype.toObject=function(){return{index:this.index,residueOffset:this.residueOffset,residueCount:this.residueCount,chainname:this.chainname}},Object.defineProperties(_v.prototype,wv);var Sv=function(t,e){this.structure=t,this.modelStore=t.modelStore,this.chainStore=t.chainStore,this.residueStore=t.residueStore,this.index=e},Av={chainOffset:{},chainCount:{},residueOffset:{},atomOffset:{},chainEnd:{},residueEnd:{},atomEnd:{},residueCount:{},atomCount:{}};Av.chainOffset.get=function(){return this.modelStore.chainOffset[this.index]},Av.chainOffset.set=function(t){this.modelStore.chainOffset[this.index]=t},Av.chainCount.get=function(){return this.modelStore.chainCount[this.index]},Av.chainCount.set=function(t){this.modelStore.chainCount[this.index]=t},Av.residueOffset.get=function(){return this.chainStore.residueOffset[this.chainOffset]},Av.atomOffset.get=function(){return this.residueStore.atomOffset[this.residueOffset]},Av.chainEnd.get=function(){return this.chainOffset+this.chainCount-1},Av.residueEnd.get=function(){return this.chainStore.residueOffset[this.chainEnd]+this.chainStore.residueCount[this.chainEnd]-1},Av.atomEnd.get=function(){return this.residueStore.atomOffset[this.residueEnd]+this.residueStore.atomCount[this.residueEnd]-1},Av.residueCount.get=function(){return 0===this.chainCount?0:this.residueEnd-this.residueOffset+1},Av.atomCount.get=function(){return 0===this.residueCount?0:this.atomEnd-this.atomOffset+1},Sv.prototype.eachAtom=function(t,e){this.eachChain(function(i){i.eachAtom(t,e)},e)},Sv.prototype.eachResidue=function(t,e){this.eachChain(function(i){i.eachResidue(t,e)},e)},Sv.prototype.eachPolymer=function(t,e){if(e&&e.chainOnlyTest){var i=e.chainOnlyTest;this.eachChain(function(r){i(r)&&r.eachPolymer(t,e)})}else this.eachChain(function(i){i.eachPolymer(t,e)})},Sv.prototype.eachChain=function(t,e){var i,r=this.chainCount,n=this.chainOffset,o=this.structure._cp,a=n+r;if(e&&e.test){var s=e.chainOnlyTest;if(s)for(i=n;i<a;++i)o.index=i,s(o)&&t(o,e);else for(i=n;i<a;++i)o.index=i,t(o,e)}else for(i=n;i<a;++i)o.index=i,t(o)},Sv.prototype.qualifiedName=function(){return"/"+this.index},Sv.prototype.clone=function(){return new this.constructor(this.structure,this.index)},Sv.prototype.toObject=function(){return{index:this.index,chainOffset:this.chainOffset,chainCount:this.chainCount}},Object.defineProperties(Sv.prototype,Av);var Mv=function(t,e){this.signals={refreshed:new io},this.init(t,e)},Pv={type:{}};Mv.prototype.init=function(t,e){this.name=t,this.path=e,this.title="",this.id="",this.header={},this.extraData={},this.atomSetCache=void 0,this.atomSetDict={},this.biomolDict={},this.entityList=[],this.unitcell=void 0,this.frames=[],this.boxes=[],this.validation=void 0,this.bondStore=new Yg(0),this.backboneBondStore=new Yg(0),this.rungBondStore=new Yg(0),this.atomStore=new Zg(0),this.residueStore=new Kg(0),this.chainStore=new Qg(0),this.modelStore=new Jg(0),this.atomMap=new hv(this),this.residueMap=new pv(this),this.bondHash=void 0,this.spatialHash=void 0,this.atomSet=void 0,this.bondSet=void 0,this.center=void 0,this.boundingBox=void 0,this._bp=this.getBondProxy(),this._ap=this.getAtomProxy(),this._rp=this.getResidueProxy(),this._cp=this.getChainProxy()},Pv.type.get=function(){return"Structure"},Mv.prototype.finalizeAtoms=function(){this.atomSet=this.getAtomSet(),this.atomCount=this.atomStore.count,this.boundingBox=this.getBoundingBox(),this.center=this.boundingBox.getCenter(),this.spatialHash=new Fa(this.atomStore,this.boundingBox)},Mv.prototype.finalizeBonds=function(){var t=this;this.bondSet=this.getBondSet(),this.bondCount=this.bondStore.count,this.bondHash=new Xg(this.bondStore,this.atomStore.count),this.atomSetCache={},this.atomSetDict.rung||(this.atomSetDict.rung=this.getAtomSet(!1));for(var e in t.atomSetDict)t.atomSetCache["__"+e]=t.atomSetDict[e].clone()},Mv.prototype.getBondProxy=function(t){return new dv(this,t)},Mv.prototype.getAtomProxy=function(t){return new mv(this,t)},Mv.prototype.getResidueProxy=function(t){return new vv(this,t)},Mv.prototype.getChainProxy=function(t){return new _v(this,t)},Mv.prototype.getModelProxy=function(t){return new Sv(this,t)},Mv.prototype.getBondSet=function(){var t=this.bondStore.count,e=new og(t),i=this.atomSet;if(i)for(var r=this.getBondProxy(),n=0;n<t;++n)r.index=n,i.isSet(r.atomIndex1,r.atomIndex2)&&e.set(r.index);else e.setAll();return e},Mv.prototype.getBackboneBondSet=function(){var t=this.backboneBondStore.count,e=new og(t),i=this.atomSetCache.__backbone;if(i){var r=this.getBondProxy();r.bondStore=this.backboneBondStore;for(var n=0;n<t;++n)r.index=n,i.isSet(r.atomIndex1,r.atomIndex2)&&e.set(r.index)}else e.set_all(!0);return e},Mv.prototype.getRungBondSet=function(){var t=this.rungBondStore.count,e=new og(t),i=this.atomSetCache.__rung;if(i){var r=this.getBondProxy();r.bondStore=this.rungBondStore;for(var n=0;n<t;++n)r.index=n,i.isSet(r.atomIndex1,r.atomIndex2)&&e.set(r.index)}else e.set_all(!0);return e},Mv.prototype.getAtomSet=function(t){var e,i=this.atomStore.count;if(t instanceof og)e=t;else if(t&&t.test){var r=t.string;r in this.atomSetCache?e=this.atomSetCache[r]:(e=new og(i),this.eachAtom(function(t){e.set(t.index)},t),this.atomSetCache[r]=e)}else e=!1===t?new og(i):new og(i,!0);return e},Mv.prototype.getAtomSetWithinSelection=function(t,e){var i=this.spatialHash,r=this.getAtomSet(!1),n=this.getAtomProxy();return this.getAtomSet(t).forEach(function(t){n.index=t,i.within(n.x,n.y,n.z,e).forEach(function(t){r.set(t)})}),r},Mv.prototype.getAtomSetWithinPoint=function(t,e){var i=t,r=this.getAtomSet(!1);return this.spatialHash.within(i.x,i.y,i.z,e).forEach(function(t){r.set(t)}),r},Mv.prototype.getAtomSetWithinVolume=function(t,e,i,r,n){for(var o=this,a=new Hg(t,i,r,n),s=a.getDataPosition(),c=s.length,u=a.matrix.getMaxScaleOnAxis(),h=this.getAtomSet(!1),l=0;l<c;l+=3)o.spatialHash.within(s[l],s[l+1],s[l+2],u).forEach(function(t){h.set(t)});return h},Mv.prototype.getAtomSetWithinGroup=function(t){var e=this.atomStore.residueIndex,i=this.getAtomSet(!1),r=this.getResidueProxy();return this.getAtomSet(t).forEach(function(t){r.index=e[t];for(var n=r.atomOffset;n<=r.atomEnd;++n)i.set(n)}),i},Mv.prototype.getSelection=function(){return!1},Mv.prototype.getStructure=function(){return this},Mv.prototype.eachEntity=function(t,e){this.entityList.forEach(function(i){void 0!==e&&i.getEntityType()!==e||t(i)})},Mv.prototype.eachBond=function(t,e){var i,r=this.getBondProxy();if(e&&e.test&&(i=this.getBondSet(e),this.bondSet&&i.intersection(this.bondSet)),i)i.forEach(function(e){r.index=e,t(r)});else for(var n=this.bondStore.count,o=0;o<n;++o)r.index=o,t(r)},Mv.prototype.eachAtom=function(t,e){if(e&&e.test)this.eachModel(function(i){i.eachAtom(t,e)},e);else for(var i=this.atomStore.count,r=this.getAtomProxy(),n=0;n<i;++n)r.index=n,t(r)},Mv.prototype.eachResidue=function(t,e){var i;if(e&&e.test){var r=this.modelStore.count,n=this.getModelProxy(),o=e.modelOnlyTest;if(o)for(i=0;i<r;++i)n.index=i,o(n)&&n.eachResidue(t,e);else for(i=0;i<r;++i)n.index=i,n.eachResidue(t,e)}else{var a=this.residueStore.count,s=this.getResidueProxy();for(i=0;i<a;++i)s.index=i,t(s)}},Mv.prototype.eachResidueN=function(t,e){var i,r,n=this,o=this.residueStore.count;if(!(o<t)){var a=new Array(t);for(i=0;i<t;++i)a[i]=n.getResidueProxy(i);for(e.apply(this,a),r=t;r<o;++r){for(i=0;i<t;++i)a[i].index+=1;e.apply(n,a)}}},Mv.prototype.eachPolymer=function(t,e){if(e&&e.modelOnlyTest){var i=e.modelOnlyTest;this.eachModel(function(r){i(r)&&r.eachPolymer(t,e)})}else this.eachModel(function(i){i.eachPolymer(t,e)})},Mv.prototype.eachChain=function(t,e){if(e&&e.test)this.eachModel(function(i){i.eachChain(t,e)});else for(var i=this.chainStore.count,r=this.getChainProxy(),n=0;n<i;++n)r.index=n,t(r)},Mv.prototype.eachModel=function(t,e){var i,r=this.modelStore.count,n=this.getModelProxy();if(e&&e.test){var o=e.modelOnlyTest;if(o)for(i=0;i<r;++i)n.index=i,o(n)&&t(n,e);else for(i=0;i<r;++i)n.index=i,t(n,e)}else for(i=0;i<r;++i)n.index=i,t(n)},Mv.prototype.getAtomData=function(t){var e=Object.assign({},t);e.colorParams&&(e.colorParams.structure=this.getStructure());var i,r,n,o,a,s,c,u=e.what,h=dn(e.atomSet,this.atomSet),l={},p=this.getAtomProxy(),d=h.getSize();return u&&!u.position||(n=new Float32Array(3*d),l.position=n),u&&!u.color||(o=new Float32Array(3*d),l.color=o,r=lf.getScheme(e.colorParams)),u&&!u.picking||(a=new Float32Array(d),l.picking=new $m(a,this.getStructure())),u&&!u.radius||(s=new Float32Array(d),l.radius=s,i=new ga(e.radiusParams.radius,e.radiusParams.scale)),u&&!u.index||(c=new Float32Array(d),l.index=c),h.forEach(function(t,e){var u=3*e;p.index=t,n&&p.positionToArray(n,u),o&&r.atomColorToArray(p,o,u),a&&(a[e]=t),s&&(s[e]=i.atomRadius(p)),c&&(c[e]=t)}),l},Mv.prototype.getBondData=function(t){var e=Object.assign({},t);e.colorParams&&(e.colorParams.structure=this.getStructure());var i,r,n,o,a,s,c,u,h,l=e.what,p=dn(e.bondSet,this.bondSet),d=dn(e.multipleBond,"off"),f="off"!==d,m="offset"===d,v=dn(e.bondScale,.4),y=dn(e.bondSpacing,1),b={},x=this.getBondProxy();e.bondStore&&(x.bondStore=e.bondStore);var _,w=this.getAtomProxy(),S=this.getAtomProxy();if(f){var A=x.bondStore.bondOrder;_=0,p.forEach(function(t){_+=A[t]})}else _=p.getSize();l&&!l.position||(n=new Float32Array(3*_),o=new Float32Array(3*_),b.position1=n,b.position2=o),l&&!l.color||(a=new Float32Array(3*_),s=new Float32Array(3*_),b.color=a,b.color2=s,r=lf.getScheme(e.colorParams)),l&&!l.picking||(c=new Float32Array(_),b.picking=new Wm(c,this.getStructure(),e.bondStore)),(!l||l.radius||f&&l.position)&&(i=new ga(e.radiusParams.radius,e.radiusParams.scale)),l&&!l.radius||(u=new Float32Array(_),b.radius=u,e.radius2&&(h=new Float32Array(_),b.radius2=h));var M,P,T,E,C,I,L,R=0,O=new g,D=new g,N=new g;return p.forEach(function(t){if(P=3*R,x.index=t,w.index=x.atomIndex1,S.index=x.atomIndex2,E=x.bondOrder,n&&(f&&E>1?(C=i.atomRadius(w),I=C*v/(.5*E),x.calculateShiftDir(N),m?(L=2*y*C,N.multiplyScalar(L),N.negate(),D.subVectors(S,w).multiplyScalar(Math.max(.1,L/1.88)),w.positionToArray(n,P),S.positionToArray(o,P),E>=2&&(O.addVectors(w,N).add(D).toArray(n,P+3),O.addVectors(S,N).sub(D).toArray(o,P+3),E>=3&&(O.subVectors(w,N).add(D).toArray(n,P+6),O.subVectors(S,N).sub(D).toArray(o,P+6)))):(L=(y-v)*C,N.multiplyScalar(L),2===E?(O.addVectors(w,N).toArray(n,P),O.subVectors(w,N).toArray(n,P+3),O.addVectors(S,N).toArray(o,P),O.subVectors(S,N).toArray(o,P+3)):3===E?(w.positionToArray(n,P),O.addVectors(w,N).toArray(n,P+3),O.subVectors(w,N).toArray(n,P+6),S.positionToArray(o,P),O.addVectors(S,N).toArray(o,P+3),O.subVectors(S,N).toArray(o,P+6)):(w.positionToArray(n,P),S.positionToArray(o,P)))):(w.positionToArray(n,P),S.positionToArray(o,P))),a&&(r.bondColorToArray(x,1,a,P),r.bondColorToArray(x,0,s,P),f&&E>1))for(M=1;M<E;++M)Oo(a,P,T=3*M+P,3),Oo(s,P,T,3);if(c&&(c[R]=t,f&&E>1))for(M=1;M<E;++M)c[R+M]=t;if(u&&(u[R]=i.atomRadius(w),f&&E>1))for(I=u[R]*v/(m?1:.5*E),M=m?1:0;M<E;++M)u[R+M]=I;if(h&&(h[R]=i.atomRadius(S),f&&E>1))for(I=h[R]*v/(m?1:.5*E),M=m?1:0;M<E;++M)h[R+M]=I;R+=f?E:1}),b},Mv.prototype.getBackboneAtomData=function(t){return t=Object.assign({atomSet:this.atomSetCache.__backbone},t),this.getAtomData(t)},Mv.prototype.getBackboneBondData=function(t){return t=Object.assign({bondSet:this.getBackboneBondSet(),bondStore:this.backboneBondStore},t),this.getBondData(t)},Mv.prototype.getRungAtomData=function(t){return t=Object.assign({atomSet:this.atomSetCache.__rung},t),this.getAtomData(t)},Mv.prototype.getRungBondData=function(t){return t=Object.assign({bondSet:this.getRungBondSet(),bondStore:this.rungBondStore},t),this.getBondData(t)},Mv.prototype.getBoundingBox=function(e,i){t.Debug&&cf.time("getBoundingBox"),i=i||new st;var r=1/0,n=1/0,o=1/0,a=-1/0,s=-1/0,c=-1/0;return this.eachAtom(function(t){var e=t.x,i=t.y,u=t.z;e<r&&(r=e),i<n&&(n=i),u<o&&(o=u),e>a&&(a=e),i>s&&(s=i),u>c&&(c=u)},e),i.min.set(r,n,o),i.max.set(a,s,c),t.Debug&&cf.timeEnd("getBoundingBox"),i},Mv.prototype.getPrincipalAxes=function(e){t.Debug&&cf.time("getPrincipalAxes");var i=0,r=new va(3,this.atomCount),n=r.data;return this.eachAtom(function(t){n[i+0]=t.x,n[i+1]=t.y,n[i+2]=t.z,i+=3},e),t.Debug&&cf.timeEnd("getPrincipalAxes"),new Ug(r)},Mv.prototype.atomCenter=function(t){return t?this.getBoundingBox(t).getCenter():this.center.clone()},Mv.prototype.getSequence=function(t){var e=[],i=this.getResidueProxy();return this.eachAtom(function(t){i.index=t.residueIndex,t.index===i.traceAtomIndex&&e.push(i.getResname1())},t),e},Mv.prototype.getAtomIndices=function(t){var e;if(t&&t.string)e=[],this.eachAtom(function(t){e.push(t.index)},t);else{var i={what:{index:!0}};e=this.getAtomData(i).index}return e},Mv.prototype.getChainnameCount=function(t){var e=new Set;return this.eachChain(function(t){t.residueCount&&e.add(t.chainname)},t),e.size},Mv.prototype.updatePosition=function(t){var e=0;this.eachAtom(function(i){i.positionFromArray(t,e),e+=3})},Mv.prototype.refreshPosition=function(){this.getBoundingBox(void 0,this.boundingBox),this.boundingBox.getCenter(this.center),this.spatialHash=new Fa(this.atomStore,this.boundingBox)},Mv.prototype.dispose=function(){this.frames&&(this.frames.length=0),this.boxes&&(this.boxes.length=0),this.bondStore.dispose(),this.backboneBondStore.dispose(),this.rungBondStore.dispose(),this.atomStore.dispose(),this.residueStore.dispose(),this.chainStore.dispose(),this.modelStore.dispose(),delete this.bondStore,delete this.atomStore,delete this.residueStore,delete this.chainStore,delete this.modelStore,delete this.frames,delete this.boxes,delete this.cif,delete this.bondSet,delete this.atomSet},Object.defineProperties(Mv.prototype,Pv);var Tv=function(t,e){var i;"function"==typeof t.eachAtom?i=t.atomCount:t instanceof Float32Array&&(i=t.length/3);var r=new va(3,i),n=new va(3,i);this.coords1t=new va(i,3),this.coords2t=new va(i,3),this.A=new va(3,3),this.W=new va(1,3),this.U=new va(3,3),this.V=new va(3,3),this.VH=new va(3,3),this.R=new va(3,3),this.tmp=new va(3,3),this.c=new va(3,3),this.c.data.set([1,0,0,0,1,0,0,0,-1]),this.prepCoords(t,r),this.prepCoords(e,n),this._superpose(r,n)};Tv.prototype._superpose=function(e,i){this.mean1=Sa(e),this.mean2=Sa(i),Aa(e,this.mean1),Aa(i,this.mean2),ya(this.coords1t,e),ya(this.coords2t,i),ba(this.A,this.coords2t,this.coords1t),Ca(this.A,this.W,this.U,this.V),xa(this.V,this.VH),wa(this.R,this.U,this.VH),_a(this.R)<0&&(t.Debug&&cf.log("R not a right handed system"),wa(this.tmp,this.c,this.VH),wa(this.R,this.U,this.tmp))},Tv.prototype.prepCoords=function(t,e){var i=0,r=e.data;"function"==typeof t.eachAtom?t.eachAtom(function(t){r[i+0]=t.x,r[i+1]=t.y,r[i+2]=t.z,i+=3}):t instanceof Float32Array?r.set(t):cf.warn("prepCoords: input type unknown")},Tv.prototype.transform=function(t){var e;"function"==typeof t.eachAtom?e=t.atomCount:t instanceof Float32Array&&(e=t.length/3);var i=new va(3,e),r=new va(e,3);this.prepCoords(t,i),Aa(i,this.mean1),ba(r,this.R,i),ya(i,r),Ma(i,this.mean2);var n=0,o=i.data;"function"==typeof t.eachAtom?t.eachAtom(function(t){t.x=o[n+0],t.y=o[n+1],t.z=o[n+2],n+=3}):t instanceof Float32Array?t.set(o.subarray(0,3*e)):cf.warn("transform: input type unknown")};var Ev=function(t,e){this.signals={startedRunning:new io,haltedRunning:new io};var i=Object.assign({},e);t.signals.playerChanged.add(function(t){t!==this&&this.pause()},this);var r=dn(t.numframes,1);this.traj=t,this.start=dn(i.start,0),this.end=Math.min(dn(i.end,r-1),r-1),this.step=dn(i.step,Math.ceil((r+1)/100)),this.timeout=dn(i.timeout,50),this.interpolateType=dn(i.interpolateType,""),this.interpolateStep=dn(i.interpolateStep,5),this.mode=dn(i.mode,"loop"),this.direction=dn(i.direction,"forward"),this._stopFlag=!1,this._running=!1,t.signals.gotNumframes.add(function(t){this.end=Math.min(dn(i.end,t-1),t-1)},this)};Ev.prototype._animate=function(){var t;if(this._running=!0,this.traj.inProgress||this._stopFlag||(((t="forward"===this.direction?this.traj.currentFrame+this.step:this.traj.currentFrame-this.step)>=this.end||t<this.start)&&("once"===this.mode?(this.pause(),t="forward"===this.direction?this.end:this.start):t="forward"===this.direction?this.start:this.end),this.interpolateType||this.traj.setFrame(t)),this._stopFlag)this._running=!1;else if(!this.traj.inProgress&&this.interpolateType){var e,i,r;"forward"===this.direction?(e=Math.max(this.start,t-this.step),i=Math.max(this.start,t-2*this.step),r=Math.max(this.start,t-3*this.step)):(e=Math.min(this.end,t+this.step),i=Math.min(this.end,t+2*this.step),r=Math.min(this.end,t+3*this.step)),this._interpolate(t,e,i,r,1/this.interpolateStep,0)}else setTimeout(this._animate.bind(this),this.timeout)},Ev.prototype._interpolate=function(t,e,i,r,n,o){if((o+=n)<=1){var a=Math.round(this.timeout*n);this.traj.setFrameInterpolated(t,e,i,r,o,this.interpolateType,function(){setTimeout(function(){this._interpolate(t,e,i,r,n,o)}.bind(this),a)}.bind(this))}else setTimeout(this._animate.bind(this),0)},Ev.prototype.toggle=function(){this._running?this.pause():this.play()},Ev.prototype.play=function(){if(!this._running){this.traj.player!==this&&this.traj.setPlayer(this);var t=this.traj.currentFrame,e=Math.ceil(t/this.step)*this.step;"forward"===this.direction&&t>=this.end?e=this.start:"backward"===this.direction&&t<=this.start&&(e=this.end),this.traj.setFrame(e),this._stopFlag=!1,this._animate(),this.signals.startedRunning.dispatch()}},Ev.prototype.pause=function(){this._running&&(this._stopFlag=!0,this.signals.haltedRunning.dispatch())},Ev.prototype.stop=function(){this.traj.setFrame(this.start),this.pause()};var Cv=function(t,e,i){this.signals={gotNumframes:new io,frameChanged:new io,selectionChanged:new io,playerChanged:new io};var r=i||{};r.centerPbc=dn(r.centerPbc,!0),r.removePbc=dn(r.removePbc,!0),r.superpose=dn(r.superpose,!0),this.setParameters(r),this.name=t.replace(/^.*[\\\/]/,""),this.selection=new Kd(dn(r.sele,"backbone and not hydrogen")),this.selection.signals.stringChanged.add(function(){this.makeIndices(),this.resetCache()},this),this.setStructure(e),this.setPlayer(new Ev(this)),this.trajPath=t,this.numframes=void 0,this.getNumframes()};Cv.prototype.setStructure=function(t){this.structure=t,this.atomCount=t.atomCount,this.makeAtomIndices(),this.saveInitialStructure(),this.backboneIndices=this.getIndices(new Kd("backbone and not hydrogen")),this.makeIndices(),this.frameCache=[],this.boxCache=[],this.pathCache=[],this.frameCacheSize=0,this.currentFrame=-1},Cv.prototype.saveInitialStructure=function(){var t=0,e=new Float32Array(3*this.atomCount);this.structure.eachAtom(function(i){e[t+0]=i.x,e[t+1]=i.y,e[t+2]=i.z,t+=3}),this.initialStructure=e},Cv.prototype.setSelection=function(t){return this.selection.setString(t),this},Cv.prototype.getIndices=function(t){var e;if(t&&t.test){var i=0,r=t.test;e=[],this.structure.eachAtom(function(t){r(t)&&e.push(i),i+=1})}else e=this.structure.getAtomIndices(this.selection);return e},Cv.prototype.makeIndices=function(){var t=this;this.indices=this.getIndices(this.selection);var e,i,r=3*this.indices.length;this.coords1=new Float32Array(r),this.coords2=new Float32Array(r);var n=this.initialStructure,o=this.coords2;for(e=0;e<r;e+=3)i=3*t.indices[e/3],o[e+0]=n[i+0],o[e+1]=n[i+1],o[e+2]=n[i+2]},Cv.prototype.makeAtomIndices=function(){cf.error("Trajectory.makeAtomIndices not implemented")},Cv.prototype.getNumframes=function(){cf.error("Trajectory.loadFrame not implemented")},Cv.prototype.resetCache=function(){return this.frameCache=[],this.boxCache=[],this.pathCache=[],this.frameCacheSize=0,this.setFrame(this.currentFrame),this},Cv.prototype.setParameters=function(t){var e=t,i=!1;void 0!==e.centerPbc&&e.centerPbc!==this.centerPbc&&(this.centerPbc=e.centerPbc,i=!0),void 0!==e.removePbc&&e.removePbc!==this.removePbc&&(this.removePbc=e.removePbc,i=!0),void 0!==e.superpose&&e.superpose!==this.superpose&&(this.superpose=e.superpose,i=!0),i&&this.resetCache()},Cv.prototype.setFrame=function(t,e){return void 0===t?this:(this.inProgress=!0,t=parseInt(t),-1===t||this.frameCache[t]?this.updateStructure(t,e):this.loadFrame(t,function(){this.updateStructure(t,e)}.bind(this)),this)},Cv.prototype.interpolate=function(t,e,i,r,n,o,a){var s,c=this.frameCache,u=c[t],h=c[e],l=c[i],p=c[r],d=u.length,f=new Float32Array(d);if("spline"===o)for(s=0;s<d;s+=3)f[s+0]=Kn(p[s+0],l[s+0],h[s+0],u[s+0],n,1),f[s+1]=Kn(p[s+1],l[s+1],h[s+1],u[s+1],n,1),f[s+2]=Kn(p[s+2],l[s+2],h[s+2],u[s+2],n,1);else for(s=0;s<d;s+=3)f[s+0]=Zn(h[s+0],u[s+0],n),f[s+1]=Zn(h[s+1],u[s+1],n),f[s+2]=Zn(h[s+2],u[s+2],n);this.structure.updatePosition(f),this.currentFrame=t,this.signals.frameChanged.dispatch(t),"function"==typeof a&&a()},Cv.prototype.setFrameInterpolated=function(t,e,i,r,n,o,a){if(void 0===t)return this;var s=this.frameCache,c=[];return s[r]||c.push(r),s[i]||c.push(i),s[e]||c.push(e),s[t]||c.push(t),c.length?this.loadFrame(c,function(){this.interpolate(t,e,i,r,n,o,a)}.bind(this)):this.interpolate(t,e,i,r,n,o,a),this},Cv.prototype.loadFrame=function(t,e){if(Array.isArray(t)){var i,r=function(t,r){this._loadFrame(t,r),0===i.length()&&"function"==typeof e&&e()}.bind(this);i=new ms(r,t)}else this._loadFrame(t,e)},Cv.prototype._loadFrame=function(t,e){cf.error("Trajectory._loadFrame not implemented",t,e)},Cv.prototype.updateStructure=function(t,e){this._disposed||(-1===t?this.structure.updatePosition(this.initialStructure):this.structure.updatePosition(this.frameCache[t]),this.structure.trajectory={name:this.trajPath,frame:t},"function"==typeof e&&e(),this.currentFrame=t,this.inProgress=!1,this.signals.frameChanged.dispatch(t))},Cv.prototype.getCircularMean=function(t,e,i){return[Ao(e,i[0],3,0,t),Ao(e,i[1],3,1,t),Ao(e,i[2],3,2,t)]},Cv.prototype.doSuperpose=function(t){var e,i,r=this,n=3*this.indices.length,o=this.coords1,a=this.coords2;for(e=0;e<n;e+=3)i=3*r.indices[e/3],o[e+0]=t[i+0],o[e+1]=t[i+1],o[e+2]=t[i+2];new Tv(o,a).transform(t)},Cv.prototype.process=function(t,e,i,r){if(this.setNumframes(r),e){if(this.backboneIndices.length>0&&this.centerPbc){var n=[e[0],e[4],e[8]];gs(i,this.getCircularMean(this.backboneIndices,i,n),n)}this.removePbc&&vs(i,e)}this.indices.length>0&&this.superpose&&this.doSuperpose(i),this.frameCache[t]=i,this.boxCache[t]=e,this.frameCacheSize+=1},Cv.prototype.setNumframes=function(t){t!==this.numframes&&(this.numframes=t,this.signals.gotNumframes.dispatch(t))},Cv.prototype.dispose=function(){this.frameCache=[],this._disposed=!0,this.player&&this.player.stop()},Cv.prototype.setPlayer=function(t){this.player=t,this.signals.playerChanged.dispatch(t)},Cv.prototype.getPath=function(t,e){cf.error("Trajectory.getPath not implemented",t,e)},mf.add("shader/Mesh.vert","#define STANDARD\nuniform float nearClip;\nuniform vec3 clipCenter;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || ( !defined( PICKING ) && !defined( NOLIGHT ) )\nvarying vec3 vViewPosition;\n#endif\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#if defined( PICKING )\n#include unpack_color\nattribute float primitiveId;\nvarying vec3 vPickingColor;\n#elif defined( NOLIGHT )\nvarying vec3 vColor;\n#else\n#include color_pars_vertex\n#ifndef FLAT_SHADED\nvarying vec3 vNormal;\n#endif\n#endif\n#include common\nvoid main(){\n#if defined( PICKING )\nvPickingColor = unpackColor( primitiveId );\n#elif defined( NOLIGHT )\nvColor = color;\n#else\n#include color_vertex\n#include beginnormal_vertex\n#include defaultnormal_vertex\n#ifndef FLAT_SHADED\nvNormal = normalize( transformedNormal );\n#endif\n#endif\n#include begin_vertex\n#include project_vertex\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || ( !defined( PICKING ) && !defined( NOLIGHT ) )\nvViewPosition = -mvPosition.xyz;\n#endif\n#if defined( RADIUS_CLIP )\nvClipCenter = -( modelViewMatrix * vec4( clipCenter, 1.0 ) ).xyz;\n#endif\n#include nearclip_vertex\n}"),mf.add("shader/Mesh.frag","#define STANDARD\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\nuniform float nearClip;\nuniform float clipRadius;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || ( !defined( PICKING ) && !defined( NOLIGHT ) )\nvarying vec3 vViewPosition;\n#endif\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#if defined( PICKING )\nuniform float objectId;\nvarying vec3 vPickingColor;\n#elif defined( NOLIGHT )\nvarying vec3 vColor;\n#else\n#ifndef FLAT_SHADED\nvarying vec3 vNormal;\n#endif\n#include common\n#include color_pars_fragment\n#include fog_pars_fragment\n#include bsdfs\n#include lights_pars\n#include lights_physical_pars_fragment\n#endif\nvoid main(){\n#include nearclip_fragment\n#include radiusclip_fragment\n#if defined( PICKING )\nif( opacity < 0.7 )\ndiscard;\ngl_FragColor = vec4( vPickingColor, objectId );\n#elif defined( NOLIGHT )\ngl_FragColor = vec4( vColor, opacity );\n#else\nvec4 diffuseColor = vec4( diffuse, opacity );\nReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\nvec3 totalEmissiveLight = emissive;\n#include color_fragment\n#include roughnessmap_fragment\n#include metalnessmap_fragment\n#include normal_flip\n#include normal_fragment\n#include dull_interior_fragment\n#include lights_physical_fragment\n#include lights_template\nvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n#include opaque_back_fragment\n#endif\n}");var Iv={f:1,v2:2,v3:3,c:3},Lv=function(t,e){var i=t||{},r=e||{};this.opaqueBack=dn(r.opaqueBack,!1),this.dullInterior=dn(r.dullInterior,!1),this.side=dn(r.side,"double"),this.opacity=dn(r.opacity,1),this.depthWrite=dn(r.depthWrite,!0),this.clipNear=dn(r.clipNear,0),this.clipRadius=dn(r.clipRadius,0),this.clipCenter=dn(r.clipCenter,new g),this.flatShaded=dn(r.flatShaded,!1),this.background=dn(r.background,!1),this.linewidth=dn(r.linewidth,1),this.wireframe=dn(r.wireframe,!1),this.wireframeLinewidth=dn(r.wireframeLinewidth,1),this.roughness=dn(r.roughness,.4),this.metalness=dn(r.metalness,0),this.diffuse=dn(r.diffuse,16777215),this.forceTransparent=dn(r.forceTransparent,!1),this.geometry=new Ct,this.indexVersion=0,this.wireframeIndexVersion=-1,this.uniforms=Ll.merge([Il.common,{fogColor:{value:null},fogNear:{value:0},fogFar:{value:0},opacity:{value:this.opacity},nearClip:{value:0},clipRadius:{value:this.clipRadius},clipCenter:{value:this.clipCenter}},{emissive:{value:new tt(0)},roughness:{value:this.roughness},metalness:{value:this.metalness}},Il.ambient,Il.lights]),this.uniforms.diffuse.value.set(this.diffuse),this.pickingUniforms={nearClip:{value:0},objectId:{value:0},opacity:{value:this.opacity}},this.group=new Re,this.wireframeGroup=new Re,this.pickingGroup=new Re,this.matrix=dn(r.matrix,new v);var n=i.position||i.position1;this._positionDataSize=n?n.length/3:0,this.addAttributes({position:{type:"v3",value:i.position},color:{type:"c",value:i.color},primitiveId:{type:"f",value:i.primitiveId}}),i.index&&this.initIndex(i.index),this.picking=i.picking,this.makeWireframeGeometry()},Rv={parameters:{},matrix:{},transparent:{},size:{},attributeSize:{},pickable:{},dynamic:{},vertexShader:{},fragmentShader:{}};Rv.parameters.get=function(){return{opaqueBack:{updateShader:!0},dullInterior:{updateShader:!0},side:{updateShader:!0,property:!0},opacity:{uniform:!0},depthWrite:{property:!0},clipNear:{updateShader:!0,property:!0},clipRadius:{updateShader:!0,property:!0,uniform:!0},clipCenter:{uniform:!0},flatShaded:{updateShader:!0},background:{updateShader:!0},linewidth:{property:!0},wireframe:{updateVisibility:!0},roughness:{uniform:!0},metalness:{uniform:!0},diffuse:{uniform:!0},matrix:{}}},Rv.matrix.set=function(t){this.setMatrix(t)},Rv.matrix.get=function(){return this.group.matrix.clone()},Rv.transparent.get=function(){return this.opacity<1||this.forceTransparent},Rv.size.get=function(){return this._positionDataSize},Rv.attributeSize.get=function(){return this.size},Rv.pickable.get=function(){return!!this.picking},Rv.dynamic.get=function(){return!0},Rv.vertexShader.get=function(){},Rv.fragmentShader.get=function(){},Lv.prototype.setMatrix=function(t){bs(this.group,t),bs(this.wireframeGroup,t),bs(this.pickingGroup,t)},Lv.prototype.initIndex=function(t){this.geometry.setIndex(new _t(t,1)),this.geometry.getIndex().setDynamic(this.dynamic)},Lv.prototype.makeMaterial=function(){var t=ys(this.side),e=new ot({uniforms:this.uniforms,vertexShader:"",fragmentShader:"",depthTest:!0,transparent:this.transparent,depthWrite:this.depthWrite,lights:!0,fog:!0,side:t,linewidth:this.linewidth});e.vertexColors=Lu,e.extensions.derivatives=this.flatShaded,e.extensions.fragDepth=this.isImpostor,e.clipNear=this.clipNear;var i=new ot({uniforms:this.uniforms,vertexShader:"",fragmentShader:"",depthTest:!0,transparent:this.transparent,depthWrite:this.depthWrite,lights:!1,fog:!0,side:t,linewidth:this.linewidth});i.vertexColors=Lu,i.clipNear=this.clipNear;var r=new ot({uniforms:this.pickingUniforms,vertexShader:"",fragmentShader:"",depthTest:!0,transparent:!1,depthWrite:this.depthWrite,lights:!1,fog:!1,side:t,linewidth:this.linewidth,blending:Ru});r.vertexColors=Lu,r.extensions.fragDepth=this.isImpostor,r.clipNear=this.clipNear,this.material=e,this.wireframeMaterial=i,this.pickingMaterial=r,this.updateShader()},Lv.prototype.makeWireframeGeometry=function(){this.makeWireframeIndex();var t=this.geometry,e=this.wireframeIndex,i=new Ct;i.attributes=t.attributes,e&&(i.setIndex(new _t(e,1).setDynamic(this.dynamic)),i.setDrawRange(0,this.wireframeIndexCount)),this.wireframeGeometry=i},Lv.prototype.makeWireframeIndex=function(){function t(t,i){if(t>i){var r=t;t=i,i=r}var n=e[t];return void 0===n?(e[t]=[i],!0):!n.includes(i)&&(n.push(i),!0)}var e=[],i=this.geometry,r=i.index;if(this.wireframe)if(r){var n=r.array,o=n.length;i.drawRange.count!==1/0&&(o=i.drawRange.count);var a;a=this.wireframeIndex&&this.wireframeIndex.length>2*o?this.wireframeIndex:Cn(2*o,i.attributes.position.count);var s=0;e.length=0;for(var c=0;c<o;c+=3){var u=n[c+0],h=n[c+1],l=n[c+2];t(u,h)&&(a[s+0]=u,a[s+1]=h,s+=2),t(h,l)&&(a[s+0]=h,a[s+1]=l,s+=2),t(l,u)&&(a[s+0]=l,a[s+1]=u,s+=2)}this.wireframeIndex=a,this.wireframeIndexCount=s,this.wireframeIndexVersion=this.indexVersion}else{var p,d=i.attributes.position.count;p=this.wireframeIndex&&this.wireframeIndex.length>2*d?this.wireframeIndex:Cn(2*d,d);for(var f=0,m=0;f<d;f+=3)p[m+0]=f,p[m+1]=f+1,p[m+2]=f+1,p[m+3]=f+2,p[m+4]=f+2,p[m+5]=f,m+=6;this.wireframeIndex=p,this.wireframeIndexCount=2*d,this.wireframeIndexVersion=this.indexVersion}else this.wireframeIndex=new Uint16Array(0),this.wireframeIndexCount=0},Lv.prototype.updateWireframeIndex=function(){if(this.wireframeGeometry.setDrawRange(0,1/0),this.wireframeIndexVersion<this.indexVersion&&this.makeWireframeIndex(),this.wireframeIndex.length>this.wireframeGeometry.index.array.length)this.wireframeGeometry.setIndex(new _t(this.wireframeIndex,1).setDynamic(this.dynamic));else{var t=this.wireframeGeometry.getIndex();t.set(this.wireframeIndex),t.needsUpdate=this.wireframeIndexCount>0,t.updateRange.count=this.wireframeIndexCount}this.wireframeGeometry.setDrawRange(0,this.wireframeIndexCount)},Lv.prototype.getRenderOrder=function(){var t=0;return this.isText?t=1:this.transparent&&(t=this.isSurface?3:2),t},Lv.prototype._getMesh=function(t){this.material||this.makeMaterial();var e,i=this.geometry,r=this[t];return this.isLine?e=new Ee(i,r):this.isPoint?(e=new Le(i,r),this.sortParticles&&(e.sortParticles=!0)):e=new It(i,r),e.frustumCulled=!1,e.renderOrder=this.getRenderOrder(),e},Lv.prototype.getMesh=function(){return this._getMesh("material")},Lv.prototype.getWireframeMesh=function(){var t;return this.material||this.makeMaterial(),this.wireframeGeometry||this.makeWireframeGeometry(),t=new Ee(this.wireframeGeometry,this.wireframeMaterial),t.frustumCulled=!1,t.renderOrder=this.getRenderOrder(),t},Lv.prototype.getPickingMesh=function(){return this._getMesh("pickingMaterial")},Lv.prototype.getShader=function(t,e){return wo(t,this.getDefines(e))},Lv.prototype.getVertexShader=function(t){return this.getShader(this.vertexShader,t)},Lv.prototype.getFragmentShader=function(t){return this.getShader(this.fragmentShader,t)},Lv.prototype.getDefines=function(t){var e={};return this.clipNear&&(e.NEAR_CLIP=1),this.clipRadius&&(e.RADIUS_CLIP=1),"picking"===t?e.PICKING=1:(("background"===t||this.background)&&(e.NOLIGHT=1),this.flatShaded&&(e.FLAT_SHADED=1),this.opaqueBack&&(e.OPAQUE_BACK=1),this.dullInterior&&(e.DULL_INTERIOR=1)),e},Lv.prototype.getParameters=function(){var t=this,e={};for(var i in t.parameters)e[i]=t[i];return e},Lv.prototype.addUniforms=function(t){this.uniforms=Ll.merge([this.uniforms,t]),this.pickingUniforms=Ll.merge([this.pickingUniforms,t])},Lv.prototype.addAttributes=function(t){var e=this;for(var i in t){var r=void 0,n=t[i],o=e.attributeSize*Iv[n.type];n.value?(o!==n.value.length&&cf.error("attribute value has wrong length",i),r=n.value):r=En("float32",o),e.geometry.addAttribute(i,new _t(r,Iv[n.type]).setDynamic(e.dynamic))}},Lv.prototype.updateRenderOrder=function(){function t(t){t.renderOrder=e}var e=this.getRenderOrder();this.group.children.forEach(t),this.pickingGroup&&this.pickingGroup.children.forEach(t)},Lv.prototype.updateShader=function(){var t=this.material,e=this.wireframeMaterial,i=this.pickingMaterial;t.vertexShader=this.getVertexShader(),t.fragmentShader=this.getFragmentShader(),t.needsUpdate=!0,e.vertexShader=this.getShader("Line.vert"),e.fragmentShader=this.getShader("Line.frag"),e.needsUpdate=!0,i.vertexShader=this.getVertexShader("picking"),i.fragmentShader=this.getFragmentShader("picking"),i.needsUpdate=!0},Lv.prototype.setParameters=function(t){var e=this;if(t){var i=t,r=this.parameters,n={},o={},a=!1,s=!1;for(var c in i){var u=i[c];void 0!==u&&(void 0!==r[c]&&(e[c]=u,r[c].property&&(!0!==r[c].property?n[r[c].property]=u:n[c]=u),r[c].uniform&&(!0!==r[c].uniform?o[r[c].uniform]=u:o[c]=u),r[c].updateShader&&(a=!0),r[c].updateVisibility&&(s=!0),e.dynamic&&"wireframe"===c&&!0===u&&e.updateWireframeIndex(),"flatShaded"===c&&(e.material.extensions.derivatives=e.flatShaded),"forceTransparent"===c&&(n.transparent=e.transparent)))}this.setProperties(n),this.setUniforms(o),a&&this.updateShader(),s&&this.setVisibility(this.visible)}},Lv.prototype.setAttributes=function(t){var e=this,i=this.geometry,r=i.attributes;for(var n in t)if("picking"!==n){var o=t[n],a=o.length;if("index"===n){var s=i.getIndex();i.setDrawRange(0,1/0),a>s.array.length?i.setIndex(new _t(o,1).setDynamic(e.dynamic)):(s.set(o),s.needsUpdate=a>0,s.updateRange.count=a,i.setDrawRange(0,a)),e.indexVersion++,e.wireframe&&e.updateWireframeIndex()}else{var c=r[n];a>c.array.length?i.addAttribute(n,new _t(o,c.itemSize).setDynamic(e.dynamic)):(r[n].set(o),r[n].needsUpdate=a>0,r[n].updateRange.count=a)}}},Lv.prototype.setUniforms=function(t){var e=this;if(t){var i=this.material.uniforms,r=this.wireframeMaterial.uniforms,n=this.pickingMaterial.uniforms;for(var o in t)"opacity"===o&&e.setProperties({transparent:e.transparent}),void 0!==i[o]&&(i[o].value.isVector3?i[o].value.copy(t[o]):i[o].value.set?i[o].value.set(t[o]):i[o].value=t[o]),void 0!==r[o]&&(r[o].value.isVector3?r[o].value.copy(t[o]):r[o].value.set?r[o].value.set(t[o]):r[o].value=t[o]),void 0!==n[o]&&(n[o].value.isVector3?n[o].value.copy(t[o]):n[o].value.set?n[o].value.set(t[o]):n[o].value=t[o])}},Lv.prototype.setProperties=function(t){var e=this;if(t){var i=this.material,r=this.wireframeMaterial,n=this.pickingMaterial;for(var o in t){var a=t[o];"transparent"===o?e.updateRenderOrder():"side"===o&&(a=ys(a)),void 0!==i[o]&&(i[o]=a),void 0!==r[o]&&(r[o]=a),void 0!==n[o]&&(n[o]=a)}i.needsUpdate=!0,r.needsUpdate=!0,n.needsUpdate=!0}},Lv.prototype.setVisibility=function(t){this.visible=t,this.wireframe?(this.group.visible=!1,this.wireframeGroup.visible=t,this.pickable&&(this.pickingGroup.visible=!1)):(this.group.visible=t,this.wireframeGroup.visible=!1,this.pickable&&(this.pickingGroup.visible=t))},Lv.prototype.dispose=function(){this.material&&this.material.dispose(),this.wireframeMaterial&&this.wireframeMaterial.dispose(),this.pickingMaterial&&this.pickingMaterial.dispose(),this.geometry.dispose(),this.wireframeGeometry&&this.wireframeGeometry.dispose()},Object.defineProperties(Lv.prototype,Rv);var Ov=function(t){function e(e,i){var r=e||{};!r.primitiveId&&r.position&&(r.primitiveId=Co(r.position.length/3)),t.call(this,r,i),this.addAttributes({normal:{type:"v3",value:r.normal}}),void 0===r.normal&&this.geometry.computeVertexNormals()}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={vertexShader:{},fragmentShader:{}};return i.vertexShader.get=function(){return"Mesh.vert"},i.fragmentShader.get=function(){return"Mesh.frag"},Object.defineProperties(e.prototype,i),e}(Lv),Dv=new v,Nv=new ut,kv=function(t){function e(e,i,r){var n,o=e||{},a=i||{},s=r.attributes.position.array,c=r.attributes.normal.array,u=r.index?r.index.array:void 0,h=o.position.length/3,l=s.length/3,p=h*l,d=new Float32Array(3*p),f=new Float32Array(3*p),m=new Float32Array(3*p);u&&(n=Cn(h*u.length,p)),t.call(this,{position:d,color:m,index:n,normal:f,primitiveId:o.primitiveId||Io(h,l),picking:o.picking},a),this.setAttributes(o),this.geoPosition=s,this.geoNormal=c,this.geoIndex=u,this.positionCount=h,this.geoPositionCount=l,this.transformedGeoPosition=new Float32Array(3*l),this.transformedGeoNormal=new Float32Array(3*l),this.meshPosition=d,this.meshColor=m,this.meshIndex=n,this.meshNormal=f,this.meshIndex=n,this.makeIndex()}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={updateNormals:{}};return e.prototype.applyPositionTransform=function(){},e.prototype.setAttributes=function(t,e){var i,r,n,o,a,s,c,u,h,l=this,p=this.geometry.attributes,d=this.updateNormals;t.position&&(i=t.position,n=this.geoPosition,c=this.meshPosition,a=this.transformedGeoPosition,p.position.needsUpdate=!0,(d||e)&&(o=this.geoNormal,h=this.meshNormal,s=this.transformedGeoNormal,p.normal.needsUpdate=!0)),t.color&&(r=t.color,u=this.meshColor,p.color.needsUpdate=!0);for(var f=this.positionCount,m=this.geoPositionCount,g=0;g<f;++g){var v=void 0,y=void 0,b=g*m*3,x=3*g;if(i&&(a.set(n),Dv.makeTranslation(i[x],i[x+1],i[x+2]),l.applyPositionTransform(Dv,g,x),Jo(Dv.elements,a),c.set(a,b),d?(s.set(o),Nv.getNormalMatrix(Dv),ta(Nv.elements,s),h.set(s,b)):e&&h.set(o,b)),r)for(v=0;v<m;++v)u[y=b+3*v]=r[x],u[y+1]=r[x+1],u[y+2]=r[x+2]}},e.prototype.makeIndex=function(){var t=this.geoIndex,e=this.meshIndex;if(t)for(var i=this.positionCount,r=this.geoPositionCount,n=3*(t.length/3),o=0;o<i;++o){var a=o*n,s=a+n;e.set(t,a);for(var c=a;c<s;++c)e[c]+=o*r}},i.updateNormals.get=function(){return!1},Object.defineProperties(e.prototype,i),e}(Ov),Bv=new g,Fv=function(t){function e(e,i){var r=i||{},n=new He(1,dn(r.sphereDetail,1));t.call(this,e,r,n),this.setAttributes(e,!0)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.applyPositionTransform=function(t,e){var i=this._radius[e];Bv.set(i,i,i),t.scale(Bv)},e.prototype.setAttributes=function(e,i){e.radius&&(this._radius=e.radius),t.prototype.setAttributes.call(this,e,i)},e}(kv);mf.add("shader/SphereImpostor.vert","uniform mat4 projectionMatrixInverse;\nuniform float nearClip;\nvarying float vRadius;\nvarying float vRadiusSq;\nvarying vec3 vPoint;\nvarying vec3 vPointViewPosition;\nattribute vec2 mapping;\nattribute float radius;\n#ifdef PICKING\n#include unpack_color\nattribute float primitiveId;\nvarying vec3 vPickingColor;\n#else\n#include color_pars_vertex\n#endif\n#include matrix_scale\nconst mat4 D = mat4(\n1.0, 0.0, 0.0, 0.0,\n0.0, 1.0, 0.0, 0.0,\n0.0, 0.0, 1.0, 0.0,\n0.0, 0.0, 0.0, -1.0\n);\nmat4 transpose( in mat4 inMatrix ) {\nvec4 i0 = inMatrix[0];\nvec4 i1 = inMatrix[1];\nvec4 i2 = inMatrix[2];\nvec4 i3 = inMatrix[3];\nmat4 outMatrix = mat4(\nvec4(i0.x, i1.x, i2.x, i3.x),\nvec4(i0.y, i1.y, i2.y, i3.y),\nvec4(i0.z, i1.z, i2.z, i3.z),\nvec4(i0.w, i1.w, i2.w, i3.w)\n);\nreturn outMatrix;\n}\nvoid ComputePointSizeAndPositionInClipCoordSphere(){\nvec2 xbc;\nvec2 ybc;\nmat4 T = mat4(\nradius, 0.0, 0.0, 0.0,\n0.0, radius, 0.0, 0.0,\n0.0, 0.0, radius, 0.0,\nposition.x, position.y, position.z, 1.0\n);\nmat4 R = transpose( projectionMatrix * modelViewMatrix * T );\nfloat A = dot( R[ 3 ], D * R[ 3 ] );\nfloat B = -2.0 * dot( R[ 0 ], D * R[ 3 ] );\nfloat C = dot( R[ 0 ], D * R[ 0 ] );\nxbc[ 0 ] = ( -B - sqrt( B * B - 4.0 * A * C ) ) / ( 2.0 * A );\nxbc[ 1 ] = ( -B + sqrt( B * B - 4.0 * A * C ) ) / ( 2.0 * A );\nfloat sx = abs( xbc[ 0 ] - xbc[ 1 ] ) * 0.5;\nA = dot( R[ 3 ], D * R[ 3 ] );\nB = -2.0 * dot( R[ 1 ], D * R[ 3 ] );\nC = dot( R[ 1 ], D * R[ 1 ] );\nybc[ 0 ] = ( -B - sqrt( B * B - 4.0 * A * C ) ) / ( 2.0 * A );\nybc[ 1 ] = ( -B + sqrt( B * B - 4.0 * A * C ) ) / ( 2.0 * A );\nfloat sy = abs( ybc[ 0 ] - ybc[ 1 ] ) * 0.5;\ngl_Position.xy = vec2( 0.5 * ( xbc.x + xbc.y ), 0.5 * ( ybc.x + ybc.y ) );\ngl_Position.xy -= mapping * vec2( sx, sy );\ngl_Position.xy *= gl_Position.w;\n}\nvoid main(void){\n#ifdef PICKING\nvPickingColor = unpackColor( primitiveId );\n#else\n#include color_vertex\n#endif\nvRadius = radius * matrixScale( modelViewMatrix );\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nmvPosition.z -= vRadius;\ngl_Position = projectionMatrix * vec4( mvPosition.xyz, 1.0 );\nComputePointSizeAndPositionInClipCoordSphere();\nvRadiusSq = vRadius * vRadius;\nvec4 vPoint4 = projectionMatrixInverse * gl_Position;\nvPoint = vPoint4.xyz / vPoint4.w;\nvPointViewPosition = -mvPosition.xyz / mvPosition.w;\n}"),mf.add("shader/SphereImpostor.frag","#define STANDARD\n#define IMPOSTOR\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\nuniform float nearClip;\nuniform mat4 projectionMatrix;\nuniform float ortho;\nvarying float vRadius;\nvarying float vRadiusSq;\nvarying vec3 vPoint;\nvarying vec3 vPointViewPosition;\n#ifdef PICKING\nuniform float objectId;\nvarying vec3 vPickingColor;\n#else\n#include common\n#include color_pars_fragment\n#include fog_pars_fragment\n#include bsdfs\n#include lights_pars\n#include lights_physical_pars_fragment\n#endif\nbool flag2 = false;\nbool interior = false;\nvec3 cameraPos;\nvec3 cameraNormal;\nfloat calcDepth( in vec3 cameraPos ){\nvec2 clipZW = cameraPos.z * projectionMatrix[2].zw + projectionMatrix[3].zw;\nreturn 0.5 + 0.5 * clipZW.x / clipZW.y;\n}\nfloat calcClip( vec3 cameraPos ){\nreturn dot( vec4( cameraPos, 1.0 ), vec4( 0.0, 0.0, 1.0, nearClip - 0.5 ) );\n}\nbool Impostor( out vec3 cameraPos, out vec3 cameraNormal ){\nvec3 cameraSpherePos = -vPointViewPosition;\ncameraSpherePos.z += vRadius;\nvec3 rayOrigin = mix( vec3( 0.0, 0.0, 0.0 ), vPoint, ortho );\nvec3 rayDirection = mix( normalize( vPoint ), vec3( 0.0, 0.0, 1.0 ), ortho );\nvec3 cameraSphereDir = mix( cameraSpherePos, rayOrigin - cameraSpherePos, ortho );\nfloat B = dot( rayDirection, cameraSphereDir );\nfloat det = B * B + vRadiusSq - dot( cameraSphereDir, cameraSphereDir );\nif( det < 0.0 ){\ndiscard;\nreturn false;\n}else{\nfloat sqrtDet = sqrt( det );\nfloat posT = mix( B + sqrtDet, B + sqrtDet, ortho );\nfloat negT = mix( B - sqrtDet, sqrtDet - B, ortho );\ncameraPos = rayDirection * negT + rayOrigin;\n#ifdef NEAR_CLIP\nif( calcDepth( cameraPos ) <= 0.0 ){\ncameraPos = rayDirection * posT + rayOrigin;\ninterior = true;\nreturn false;\n}else if( calcClip( cameraPos ) > 0.0 ){\ncameraPos = rayDirection * posT + rayOrigin;\ninterior = true;\nflag2 = true;\nreturn false;\n}else{\ncameraNormal = normalize( cameraPos - cameraSpherePos );\n}\n#else\nif( calcDepth( cameraPos ) <= 0.0 ){\ncameraPos = rayDirection * posT + rayOrigin;\ninterior = true;\nreturn false;\n}else{\ncameraNormal = normalize( cameraPos - cameraSpherePos );\n}\n#endif\nreturn true;\n}\nreturn false;\n}\nvoid main(void){\nbool flag = Impostor( cameraPos, cameraNormal );\n#ifdef NEAR_CLIP\nif( calcClip( cameraPos ) > 0.0 )\ndiscard;\n#endif\ngl_FragDepthEXT = calcDepth( cameraPos );\nif( !flag ){\n#ifdef NEAR_CLIP\nif( flag2 ){\ngl_FragDepthEXT = max( 0.0, calcDepth( vec3( - ( nearClip - 0.5 ) ) ) + ( 0.0000001 / vRadius ) );\n}else if( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = 0.0 + ( 0.0000001 / vRadius );\n}\n#else\nif( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = 0.0 + ( 0.0000001 / vRadius );\n}\n#endif\n}\nif (gl_FragDepthEXT < 0.0)\ndiscard;\nif (gl_FragDepthEXT > 1.0)\ndiscard;\n#ifdef PICKING\ngl_FragColor = vec4( vPickingColor, objectId );\n#else\nvec3 vNormal = cameraNormal;\nvec3 vViewPosition = -cameraPos;\nvec4 diffuseColor = vec4( diffuse, opacity );\nReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\nvec3 totalEmissiveLight = emissive;\n#include color_fragment\n#include roughnessmap_fragment\n#include metalnessmap_fragment\n#include normal_flip\n#include normal_fragment\nif( interior ){\nnormal = vec3( 0.0, 0.0, 0.4 );\n}\n#include lights_physical_fragment\n#include lights_template\nvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n#endif\n}");var zv=function(t){function e(e,i){t.call(this,e,i),this.index=Cn(this.indexSize,this.attributeSize),this.makeIndex(),this.initIndex(this.index,1),this.addAttributes({mapping:{type:this.mappingType,value:null}}),this.setAttributes({primitiveId:Co(this.size)})}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={attributeSize:{},indexSize:{},mapping:{},mappingIndices:{},mappingIndicesSize:{},mappingType:{},mappingSize:{},mappingItemSize:{}};return i.attributeSize.get=function(){return this.size*this.mappingSize},i.indexSize.get=function(){return this.size*this.mappingIndicesSize},i.mapping.get=function(){},i.mappingIndices.get=function(){},i.mappingIndicesSize.get=function(){},i.mappingType.get=function(){},i.mappingSize.get=function(){},i.mappingItemSize.get=function(){},e.prototype.addAttributes=function(e){var i={};for(var r in e){var n=e[r];i[r]={type:n.type,value:null}}t.prototype.addAttributes.call(this,i)},e.prototype.getAttributeIndex=function(t){return 3*t*this.mappingSize},e.prototype.setAttributes=function(t){t&&!t.position&&t.position1&&t.position2&&(t.position=Mo(t.position1,t.position2));var e,i,r,n,o,a,s,c=this.size,u=this.mappingSize,h=this.geometry.attributes;for(var l in t)if("index"!==l&&"picking"!==l){i=t[l],r=(e=h[l]).itemSize,n=e.array;for(var p=0;p<c;++p){a=(o=p*r)*u;for(var d=0;d<u;++d){s=a+r*d;for(var f=0;f<r;++f)n[s+f]=i[o+f]}}e.needsUpdate=!0}},e.prototype.makeMapping=function(){for(var t=this.size,e=this.mapping,i=this.mappingSize,r=this.mappingItemSize,n=this.geometry.attributes.mapping.array,o=0;o<t;o++)n.set(e,o*r*i)},e.prototype.makeIndex=function(){for(var t,e,i=this.size,r=this.mappingSize,n=this.mappingIndices,o=this.mappingIndicesSize,a=this.index,s=0;s<i;s++){t=s*o,e=s*r,a.set(n,t);for(var c=0;c<o;++c)a[t+c]+=e}},Object.defineProperties(e.prototype,i),e}(Lv),Uv=new Float32Array([-1,1,-1,-1,1,1,1,-1]),jv=new Uint16Array([0,1,2,1,3,2]),Gv=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={mapping:{},mappingIndices:{},mappingIndicesSize:{},mappingType:{},mappingSize:{},mappingItemSize:{}};return i.mapping.get=function(){return Uv},i.mappingIndices.get=function(){return jv},i.mappingIndicesSize.get=function(){return 6},i.mappingType.get=function(){return"v2"},i.mappingSize.get=function(){return 4},i.mappingItemSize.get=function(){return 2},Object.defineProperties(e.prototype,i),e}(zv),Vv=function(t){function e(e,i){t.call(this,e,i),this.addUniforms({projectionMatrixInverse:{value:new v},ortho:{value:0}}),this.addAttributes({radius:{type:"f",value:null}}),this.setAttributes(e),this.makeMapping()}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={isImpostor:{},vertexShader:{},fragmentShader:{}};return i.isImpostor.get=function(){return!0},i.vertexShader.get=function(){return"SphereImpostor.vert"},i.fragmentShader.get=function(){return"SphereImpostor.frag"},Object.defineProperties(e.prototype,i),e}(Gv),$v=function(t,e){return!sf||e&&e.disableImpostor?new Fv(t,e):new Vv(t,e)},Hv=new g,Wv=new g,Xv=new g,qv=new g(0,0,0),Yv=function(t){function e(e,i){var r=i||{},n=new He(1,dn(r.sphereDetail,2));t.call(this,e,r,n),this.setAttributes(e,!0)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={updateNormals:{}};return e.prototype.applyPositionTransform=function(t,e,i){Wv.fromArray(this._majorAxis,i),Xv.fromArray(this._minorAxis,i),t.lookAt(qv,Wv,Xv),Hv.set(this._radius[e],Xv.length(),Wv.length()),t.scale(Hv)},e.prototype.setAttributes=function(e,i){e.radius&&(this._radius=e.radius),e.majorAxis&&(this._majorAxis=e.majorAxis),e.minorAxis&&(this._minorAxis=e.minorAxis),t.prototype.setAttributes.call(this,e,i)},i.updateNormals.get=function(){return!0},Object.defineProperties(e.prototype,i),e}(kv),Zv=function(t,e){return new Yv(t,e)},Kv=new g,Qv=new g,Jv=new g,ty=new g(0,1,0),ey=function(t){function e(e,i){var r=e||{},n=i||{},o=dn(n.radialSegments,10),a=dn(n.openEnded,!0),s=(new v).makeRotationX(Math.PI/2),c=new fi(1,1,1,o,1,a);c.applyMatrix(s);var u=r.position1.length,h=r.radius.length,l=c.attributes.position.array.length/3,p=u/3,d=new Float32Array(2*p*l);Io(p,l,0,d),Io(p,l,p*l,d);var f=new Float32Array(2*u),m=new Float32Array(2*u);t.call(this,{position:f,color:m,primitiveId:d,picking:r.picking},n,c),this.__center=new Float32Array(u),this._position=f,this._color=m,this._from=new Float32Array(2*u),this._to=new Float32Array(2*u),this._radius=new Float32Array(2*h),this.setAttributes(r,!0)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={updateNormals:{}};return e.prototype.applyPositionTransform=function(t,e,i){Qv.fromArray(this._from,i),Jv.fromArray(this._to,i),t.lookAt(Qv,Jv,ty);var r=this._radius[e];Kv.set(r,r,Qv.distanceTo(Jv)),t.scale(Kv)},e.prototype.setAttributes=function(e,i){var r={};e.position1&&e.position2&&(Mo(e.position1,e.position2,this.__center),Mo(e.position1,this.__center,this._position),Mo(this.__center,e.position2,this._position,e.position1.length),this._from.set(e.position1),this._from.set(this.__center,e.position1.length),this._to.set(this.__center),this._to.set(e.position2,this.__center.length),r.position=this._position),e.color&&e.color2&&(this._color.set(e.color),this._color.set(e.color2,e.color.length),r.color=this._color),e.radius&&(this._radius.set(e.radius),this._radius.set(e.radius,e.radius.length),r.radius=this._radius),t.prototype.setAttributes.call(this,r,i)},i.updateNormals.get=function(){return!0},Object.defineProperties(e.prototype,i),e}(kv);mf.add("shader/CylinderImpostor.vert","\nattribute vec3 mapping;\nattribute vec3 position1;\nattribute vec3 position2;\nattribute float radius;\nvarying vec3 axis;\nvarying vec4 base_radius;\nvarying vec4 end_b;\nvarying vec3 U;\nvarying vec3 V;\nvarying vec4 w;\n#ifdef PICKING\n#include unpack_color\nattribute float primitiveId;\nvarying vec3 vPickingColor;\n#else\nattribute vec3 color2;\nvarying vec3 vColor1;\nvarying vec3 vColor2;\n#endif\nuniform mat4 modelViewMatrixInverse;\nuniform float ortho;\n#include matrix_scale\nvoid main(){\n#ifdef PICKING\nvPickingColor = unpackColor( primitiveId );\n#else\nvColor1 = color;\nvColor2 = color2;\n#endif\nbase_radius.w = radius * matrixScale( modelViewMatrix );\nvec3 center = position;\nvec3 dir = normalize( position2 - position1 );\nfloat ext = length( position2 - position1 ) / 2.0;\nvec3 cam_dir;\nif( ortho == 0.0 ){\ncam_dir = ( modelViewMatrixInverse * vec4( 0, 0, 0, 1 ) ).xyz - center;\n}else{\ncam_dir = ( modelViewMatrixInverse * vec4( 0, 0, 1, 0 ) ).xyz;\n}\ncam_dir = normalize( cam_dir );\nvec3 ldir;\nfloat b = dot( cam_dir, dir );\nend_b.w = b;\nif( b < 0.0 )\nldir = -ext * dir;\nelse\nldir = ext * dir;\nvec3 left = normalize( cross( cam_dir, ldir ) );\nleft = radius * left;\nvec3 up = radius * normalize( cross( left, ldir ) );\naxis = normalize( normalMatrix * ldir );\nU = normalize( normalMatrix * up );\nV = normalize( normalMatrix * left );\nvec4 base4 = modelViewMatrix * vec4( center - ldir, 1.0 );\nbase_radius.xyz = base4.xyz / base4.w;\nvec4 top_position = modelViewMatrix * vec4( center + ldir, 1.0 );\nvec4 end4 = top_position;\nend_b.xyz = end4.xyz / end4.w;\nw = modelViewMatrix * vec4(\ncenter + mapping.x*ldir + mapping.y*left + mapping.z*up, 1.0\n);\ngl_Position = projectionMatrix * w;\ngl_Position.z = 0.99;\n}"),mf.add("shader/CylinderImpostor.frag","#define STANDARD\n#define IMPOSTOR\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\nuniform float nearClip;\nuniform mat4 projectionMatrix;\nuniform float ortho;\nvarying vec3 axis;\nvarying vec4 base_radius;\nvarying vec4 end_b;\nvarying vec3 U;\nvarying vec3 V;\nvarying vec4 w;\n#ifdef PICKING\nuniform float objectId;\nvarying vec3 vPickingColor;\n#else\nvarying vec3 vColor1;\nvarying vec3 vColor2;\n#include common\n#include fog_pars_fragment\n#include bsdfs\n#include lights_pars\n#include lights_physical_pars_fragment\n#endif\nbool interior = false;\nfloat distSq3( vec3 v3a, vec3 v3b ){\nreturn (\n( v3a.x - v3b.x ) * ( v3a.x - v3b.x ) +\n( v3a.y - v3b.y ) * ( v3a.y - v3b.y ) +\n( v3a.z - v3b.z ) * ( v3a.z - v3b.z )\n);\n}\nfloat calcDepth( in vec3 cameraPos ){\nvec2 clipZW = cameraPos.z * projectionMatrix[2].zw + projectionMatrix[3].zw;\nreturn 0.5 + 0.5 * clipZW.x / clipZW.y;\n}\nfloat calcClip( vec3 cameraPos ){\nreturn dot( vec4( cameraPos, 1.0 ), vec4( 0.0, 0.0, 1.0, nearClip - 0.5 ) );\n}\nvoid main(){\nvec3 point = w.xyz / w.w;\nvec3 base = base_radius.xyz;\nfloat vRadius = base_radius.w;\nvec3 end = end_b.xyz;\nfloat b = end_b.w;\nvec3 end_cyl = end;\nvec3 surface_point = point;\nvec3 ray_target = surface_point;\nvec3 ray_origin = vec3(0.0);\nvec3 ray_direction = mix(normalize(ray_origin - ray_target), vec3(0.0, 0.0, 1.0), ortho);\nmat3 basis = mat3( U, V, axis );\nvec3 diff = ray_target - 0.5 * (base + end_cyl);\nvec3 P = diff * basis;\nfloat dz = dot( axis, ray_direction );\nfloat radius2 = vRadius*vRadius;\nvec3 D = vec3(dot(U, ray_direction),\ndot(V, ray_direction),\ndz);\nfloat a0 = P.x*P.x + P.y*P.y - radius2;\nfloat a1 = P.x*D.x + P.y*D.y;\nfloat a2 = D.x*D.x + D.y*D.y;\nfloat d = a1*a1 - a0*a2;\nif (d < 0.0)\ndiscard;\nfloat dist = (-a1 + sqrt(d)) / a2;\nvec3 new_point = ray_target + dist * ray_direction;\nvec3 tmp_point = new_point - base;\nvec3 _normal = normalize( tmp_point - axis * dot(tmp_point, axis) );\nray_origin = mix( ray_origin, surface_point, ortho );\nfloat front_cap_test = dot( tmp_point, axis );\nfloat end_cap_test = dot((new_point - end_cyl), axis);\n#ifndef CAP\nvec3 new_point2 = ray_target + ( (-a1 - sqrt(d)) / a2 ) * ray_direction;\nvec3 tmp_point2 = new_point2 - base;\n#endif\nif (front_cap_test < 0.0)\n{\nfloat dNV = dot(-axis, ray_direction);\nif (dNV < 0.0)\ndiscard;\nfloat near = dot(-axis, (base)) / dNV;\nvec3 front_point = ray_direction * near + ray_origin;\nif (dot(front_point - base, front_point-base) > radius2)\ndiscard;\n#ifdef CAP\nnew_point = front_point;\n_normal = axis;\n#else\nnew_point = ray_target + ( (-a1 - sqrt(d)) / a2 ) * ray_direction;\ndNV = dot(-axis, ray_direction);\nnear = dot(axis, end_cyl) / dNV;\nnew_point2 = ray_direction * near + ray_origin;\nif (dot(new_point2 - end_cyl, new_point2-base) < radius2)\ndiscard;\ninterior = true;\n#endif\n}\nif( end_cap_test > 0.0 )\n{\nfloat dNV = dot(axis, ray_direction);\nif (dNV < 0.0)\ndiscard;\nfloat near = dot(axis, end_cyl) / dNV;\nvec3 end_point = ray_direction * near + ray_origin;\nif( dot(end_point - end_cyl, end_point-base) > radius2 )\ndiscard;\n#ifdef CAP\nnew_point = end_point;\n_normal = axis;\n#else\nnew_point = ray_target + ( (-a1 - sqrt(d)) / a2 ) * ray_direction;\ndNV = dot(-axis, ray_direction);\nnear = dot(-axis, (base)) / dNV;\nnew_point2 = ray_direction * near + ray_origin;\nif (dot(new_point2 - base, new_point2-base) < radius2)\ndiscard;\ninterior = true;\n#endif\n}\ngl_FragDepthEXT = calcDepth( new_point );\n#ifdef NEAR_CLIP\nif( calcClip( new_point ) > 0.0 ){\ndist = (-a1 - sqrt(d)) / a2;\nnew_point = ray_target + dist * ray_direction;\nif( calcClip( new_point ) > 0.0 )\ndiscard;\ninterior = true;\ngl_FragDepthEXT = calcDepth( new_point );\nif( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = max( 0.0, calcDepth( vec3( - ( nearClip - 0.5 ) ) ) + ( 0.0000001 / vRadius ) );\n}\n}else if( gl_FragDepthEXT <= 0.0 ){\ndist = (-a1 - sqrt(d)) / a2;\nnew_point = ray_target + dist * ray_direction;\ninterior = true;\ngl_FragDepthEXT = calcDepth( new_point );\nif( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = 0.0 + ( 0.0000001 / vRadius );\n}\n}\n#else\nif( gl_FragDepthEXT <= 0.0 ){\ndist = (-a1 - sqrt(d)) / a2;\nnew_point = ray_target + dist * ray_direction;\ninterior = true;\ngl_FragDepthEXT = calcDepth( new_point );\nif( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = 0.0 + ( 0.0000001 / vRadius );\n}\n}\n#endif\nif (gl_FragDepthEXT < 0.0)\ndiscard;\nif (gl_FragDepthEXT > 1.0)\ndiscard;\n#ifdef PICKING\ngl_FragColor = vec4( vPickingColor, objectId );\n#else\nvec3 vViewPosition = -new_point;\nvec3 vNormal = _normal;\nvec3 vColor;\nif( distSq3( new_point, end_cyl ) < distSq3( new_point, base ) ){\nif( b < 0.0 ){\nvColor = vColor1;\n}else{\nvColor = vColor2;\n}\n}else{\nif( b > 0.0 ){\nvColor = vColor1;\n}else{\nvColor = vColor2;\n}\n}\nvec4 diffuseColor = vec4( diffuse, opacity );\nReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\nvec3 totalEmissiveLight = emissive;\n#include color_fragment\n#include roughnessmap_fragment\n#include metalnessmap_fragment\nvec3 normal = normalize( vNormal );\nif( interior ){\nnormal = vec3( 0.0, 0.0, 0.4 );\n}\n#include lights_physical_fragment\n#include lights_template\nvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n#endif\n}");var iy=new Float32Array([-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,-1,-1,1,-1,1]),ry=new Uint16Array([0,1,2,1,4,2,2,4,3,4,5,3]),ny=function(t){function e(e,i){t.call(this,e,i);var r=i||{};this.openEnded=dn(r.openEnded,!1),this.addUniforms({modelViewMatrixInverse:{value:new v},ortho:{value:0}}),this.addAttributes({position1:{type:"v3",value:null},position2:{type:"v3",value:null},color2:{type:"c",value:null},radius:{type:"f",value:null}}),this.setAttributes(e),this.makeMapping()}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={parameters:{},isImpostor:{},vertexShader:{},fragmentShader:{}};return i.parameters.get=function(){return Object.assign.call(this,{openEnded:{updateShader:!0}},t.prototype.parameters)},e.prototype.getDefines=function(e){var i=t.prototype.getDefines.call(this,e);return this.openEnded||(i.CAP=1),i},i.isImpostor.get=function(){return!0},i.vertexShader.get=function(){return"CylinderImpostor.vert"},i.fragmentShader.get=function(){return"CylinderImpostor.frag"},Object.defineProperties(e.prototype,i),e}(function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={mapping:{},mappingIndices:{},mappingIndicesSize:{},mappingType:{},mappingSize:{},mappingItemSize:{}};return i.mapping.get=function(){return iy},i.mappingIndices.get=function(){return ry},i.mappingIndicesSize.get=function(){return 12},i.mappingType.get=function(){return"v3"},i.mappingSize.get=function(){return 6},i.mappingItemSize.get=function(){return 3},Object.defineProperties(e.prototype,i),e}(zv)),oy=function(t,e){return!sf||e&&e.disableImpostor?new ey(t,e):new ny(t,e)},ay=new g,sy=new g,cy=new g,uy=new g(0,1,0),hy=function(t){function e(e,i){var r=i||{},n=dn(r.radialSegments,60),o=dn(r.openEnded,!1),a=(new v).makeRotationX(-Math.PI/2),s=new gi(1,1,n,1,o);s.applyMatrix(a);var c=e.position1.length,u=e.radius.length,h=new Float32Array(c);t.call(this,{position:h,color:e.color,picking:e.picking},r,s),this._position=h,this._from=new Float32Array(c),this._to=new Float32Array(c),this._radius=new Float32Array(u),this.setAttributes(e,!0)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={updateNormals:{}};return e.prototype.applyPositionTransform=function(t,e,i){sy.fromArray(this._from,i),cy.fromArray(this._to,i),t.lookAt(sy,cy,uy);var r=this._radius[e];ay.set(r,r,sy.distanceTo(cy)),t.scale(ay)},e.prototype.setAttributes=function(e,i){var r={};e.position1&&e.position2&&(Mo(e.position1,e.position2,this._position),this._from.set(e.position1),this._to.set(e.position2),r.position=this._position),e.color&&(r.color=e.color),e.radius&&this._radius.set(e.radius),t.prototype.setAttributes.call(this,r,i)},i.updateNormals.get=function(){return!0},Object.defineProperties(e.prototype,i),e}(kv),ly=function(t,e){return new hy(t,e)},py=function(t){this.geometryList=t,this.boundingBox=null};py.prototype.computeBoundingBox=function(){var t=this;this.boundingBox?this.boundingBox.empty():this.boundingBox=new st,this.geometryList.forEach(function(e){e.boundingBox||e.computeBoundingBox(),t.boundingBox.union(e.boundingBox)})};var dy=function(t,e){var i=t||{},r=e||{};this.aspectRatio=dn(r.aspectRatio,1.5),this.wireframe=dn(r.wireframe,!1),this.splitPosition=new Float32Array(i.position1.length),this.cylinderRadius=new Float32Array(i.radius.length);var n=this.makeAttributes(i),o={radialSegments:dn(r.radialSegments,50),openEnded:dn(r.openEnded,!1),disableImpostor:dn(r.disableImpostor,!1)};this.cylinderBuffer=new oy(n.cylinder,o),this.coneBuffer=new ly(n.cone,o),this.geometry=new py([this.cylinderBuffer.geometry,this.coneBuffer.geometry]),this.group=new Re,this.wireframeGroup=new Re,this.pickingGroup=new Re,this.matrix=dn(r.matrix,new v),this.picking=i.picking},fy={matrix:{},pickable:{}};fy.matrix.set=function(t){Lv.prototype.setMatrix.call(this,t)},fy.matrix.get=function(){return this.group.matrix.clone()},fy.pickable.get=function(){return!!this.picking},dy.prototype.makeAttributes=function(t){var e,i,r=this.splitPosition,n=this.cylinderRadius,o=this.aspectRatio,a={},s={};if(t.radius){for(e=0,i=n.length;e<i;++e)n[e]=t.radius[e]/o;a.radius=n,s.radius=t.radius}if(t.position1&&t.position2){var c=new g,u=new g,h=new g,l=new g;for(e=0,i=r.length;e<i;e+=3){c.fromArray(t.position1,e),u.fromArray(t.position2,e),h.subVectors(c,u);var p=h.length(),d=n[e/3]*o*2,f=Math.min(p,d);h.setLength(f),l.copy(u).add(h),l.toArray(r,e)}a.position1=t.position1,a.position2=r,s.position1=r,s.position2=t.position2}return t.color&&(a.color=t.color,a.color2=t.color,s.color=t.color),{cylinder:a,cone:s}},dy.prototype.getMesh=function(t){return(new Re).add(this.cylinderBuffer.getMesh(t),this.coneBuffer.getMesh(t))},dy.prototype.getWireframeMesh=function(){return(new Re).add(this.cylinderBuffer.getWireframeMesh(),this.coneBuffer.getWireframeMesh())},dy.prototype.getPickingMesh=function(){return(new Re).add(this.cylinderBuffer.getPickingMesh(),this.coneBuffer.getPickingMesh())},dy.prototype.setAttributes=function(t){var e=this.makeAttributes(t);this.cylinderBuffer.setAttributes(e.cylinder),this.coneBuffer.setAttributes(e.cone)},dy.prototype.setParameters=function(t){(t=Object.assign({},t))&&void 0!==t.matrix&&(this.matrix=t.matrix),delete t.matrix,t&&void 0!==t.wireframe&&(this.wireframe=t.wireframe,this.setVisibility(this.visible)),this.cylinderBuffer.setParameters(t),this.coneBuffer.setParameters(t)},dy.prototype.setVisibility=function(){Lv.prototype.setVisibility.apply(this,arguments)},dy.prototype.dispose=function(){this.cylinderBuffer.dispose(),this.coneBuffer.dispose()},Object.defineProperties(dy.prototype,fy),mf.add("shader/SDFFont.vert","uniform float nearClip;\nuniform float clipRadius;\nuniform vec3 clipCenter;\nuniform float xOffset;\nuniform float yOffset;\nuniform float zOffset;\nuniform bool ortho;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || ( !defined( PICKING ) && !defined( NOLIGHT ) )\nvarying vec3 vViewPosition;\n#endif\nvarying vec2 texCoord;\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#if defined( PICKING )\n#include unpack_color\nattribute float primitiveId;\nvarying vec3 vPickingColor;\n#else\n#include color_pars_vertex\n#endif\nattribute vec2 mapping;\nattribute vec2 inputTexCoord;\nattribute float inputSize;\n#include matrix_scale\n#include common\nvoid main(void){\n#if defined( PICKING )\nvPickingColor = unpackColor( primitiveId );\n#else\n#include color_vertex\n#endif\ntexCoord = inputTexCoord;\nfloat scale = matrixScale( modelViewMatrix );\nfloat _zOffset = zOffset * scale;\nif( texCoord.x == 10.0 ){\n_zOffset -= 0.001;\n}\nvec3 pos = position;\nif( ortho ){\npos += normalize( cameraPosition ) * _zOffset;\n}\nvec4 cameraPos = modelViewMatrix * vec4( pos, 1.0 );\nvec4 cameraCornerPos = vec4( cameraPos.xyz, 1.0 );\ncameraCornerPos.xy += mapping * inputSize * 0.01 * scale;\ncameraCornerPos.x += xOffset * scale;\ncameraCornerPos.y += yOffset * scale;\nif( !ortho ){\ncameraCornerPos.xyz += normalize( -cameraCornerPos.xyz ) * _zOffset;\n}\ngl_Position = projectionMatrix * cameraCornerPos;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || ( !defined( PICKING ) && !defined( NOLIGHT ) )\nvViewPosition = -cameraCornerPos.xyz;\n#endif\n#if defined( RADIUS_CLIP )\nvClipCenter = -( modelViewMatrix * vec4( clipCenter, 1.0 ) ).xyz;\n#endif\n#include nearclip_vertex\n#include radiusclip_vertex\n}"),mf.add("shader/SDFFont.frag","uniform sampler2D fontTexture;\nuniform float opacity;\nuniform bool showBorder;\nuniform vec3 borderColor;\nuniform float borderWidth;\nuniform vec3 backgroundColor;\nuniform float backgroundOpacity;\nuniform float nearClip;\nuniform float clipRadius;\nvarying vec3 vViewPosition;\nvarying vec2 texCoord;\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#if defined( PICKING )\nuniform float objectId;\nvarying vec3 vPickingColor;\nconst vec3 vColor = vec3( 0.0 );\n#else\n#include common\n#include color_pars_fragment\n#include fog_pars_fragment\n#endif\n#ifdef SDF\nconst float smoothness = 16.0;\n#else\nconst float smoothness = 256.0;\n#endif\nconst float gamma = 2.2;\nvoid main(){\n#include nearclip_fragment\n#include radiusclip_fragment\nif( texCoord.x > 1.0 ){\ngl_FragColor = vec4( backgroundColor, backgroundOpacity );\n}else{\nfloat sdf = texture2D( fontTexture, texCoord ).a;\nif( showBorder ) sdf += borderWidth;\nfloat w = clamp(\nsmoothness * ( abs( dFdx( texCoord.x ) ) + abs( dFdy( texCoord.y ) ) ),\n0.0,\n0.5\n);\nfloat a = smoothstep( 0.5 - w, 0.5 + w, sdf );\na = pow( a, 1.0 / gamma );\nif( a < 0.2 ) discard;\na *= opacity;\nvec3 outgoingLight = vColor;\nif( showBorder && sdf < ( 0.5 + borderWidth ) ){\noutgoingLight = borderColor;\n}\ngl_FragColor = vec4( outgoingLight, a );\n}\n#if defined( PICKING )\ngl_FragColor = vec4( vPickingColor, objectId );\n#else\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n#endif\n}");var my={},gy=function(t){var e=Object.assign({},t);if(this.font=dn(e.font,["sans-serif"]),this.size=dn(e.size,36),this.style=dn(e.style,"normal"),this.variant=dn(e.variant,"normal"),this.weight=dn(e.weight,"normal"),this.outline=dn(e.outline,0),this.width=dn(e.width,2048),this.height=dn(e.height,2048),this.gamma=1,"undefined"!=typeof navigator){var i=navigator.userAgent;i.match(/Chrome/)&&i.match(/OS X/)&&(this.gamma=.5)}this.mapped={},this.scratchW=0,this.scratchH=0,this.currentX=0,this.currentY=0,this.build(),this.populate(),this.texture=new De(this.canvas2),this.texture.flipY=!1,this.texture.needsUpdate=!0};gy.prototype.build=function(){var t=this.size+2*this.outline+Math.round(this.size/4),e=this.width/4,i=document.createElement("canvas");i.width=e,i.height=t;var r=i.getContext("2d");r.font=this.style+" "+this.variant+" "+this.weight+" "+this.size+"px "+this.font,r.fillStyle="#FF0000",r.textAlign="left",r.textBaseline="bottom",r.lineJoin="round";for(var n=[],o=3*this.outline,a=0;a<o;++a){var s=("00"+Math.max(0,8*-a+128-8*!a).toString(16)).slice(-2);n.push("#"+s+s+s)}var c=new Uint8Array(e*t*2);this.canvas=i,this.context=r,this.lineHeight=t,this.maxWidth=e,this.colors=n,this.scratch=c,this.data=new Uint8Array(this.width*this.height*4),this.canvas2=document.createElement("canvas"),this.canvas2.width=this.width,this.canvas2.height=this.height,this.context2=this.canvas2.getContext("2d")},gy.prototype.map=function(t){return void 0===this.mapped[t]&&(this.draw(t),this.currentX+this.scratchW>this.width&&(this.currentX=0,this.currentY+=this.scratchH),this.currentY+this.scratchH>this.height&&console.warn("canvas to small"),this.mapped[t]={x:this.currentX,y:this.currentY,w:this.scratchW,h:this.scratchH},this.context2.drawImage(this.canvas,0,0,this.scratchW,this.scratchH,this.currentX,this.currentY,this.scratchW,this.scratchH),this.currentX+=this.scratchW),this.mapped[t]},gy.prototype.get=function(t){return this.mapped[t]||this.placeholder},gy.prototype.draw=function(t){var e=this.lineHeight,i=this.outline,r=this.context,n=this.scratch,o=this.maxWidth,a=this.colors,s=i,c=e-this.outline,u=r.measureText(t),h=Math.min(o,Math.ceil(u.width+2*s+1));r.clearRect(0,0,h,e);var l,p,d,f,m;if(0===this.outline)for(r.fillText(t,s,c),d=3,l=0,p=(m=(f=r.getImageData(0,0,h,e)).data).length/4;l<p;++l)n[l]=m[d],d+=4;else{for(r.globalCompositeOperation="source-over",l=i+1;l>0;--l)d=l>1?2*l-2:l,r.strokeStyle=a[d-1],r.lineWidth=d,r.strokeText(t,s,c);r.globalCompositeOperation="multiply",r.fillStyle="#FF00FF",r.fillText(t,s,c),m=(f=r.getImageData(0,0,h,e)).data,d=0;var g=this.gamma;for(l=0,p=m.length/4;l<p;++l){var v=m[d],y=v?m[d+1]/v:1;.5===g&&(y=Math.sqrt(y));var b=256-v,x=b+(v-b)*(y=Math.min(1,Math.max(0,y)));n[l]=Math.max(0,Math.min(255,x+2)),m[d+3]=n[l],d+=4}}r.putImageData(f,0,0),this.scratchW=h,this.scratchH=e},gy.prototype.populate=function(){var t=this;this.placeholder=this.map(String.fromCharCode(65533));for(var e=0;e<127;++e)t.map(String.fromCharCode(e));for(var i=128;i<255;++i)t.map(String.fromCharCode(i));for(var r=880;r<1023;++r)t.map(String.fromCharCode(r));for(var n=1024;n<1279;++n)t.map(String.fromCharCode(n));this.map(String.fromCharCode(8491))};var vy=function(t){function e(e,i){var r=e||{},n=i||{};n.forceTransparent=!0;for(var o=r.position.length/3,a=0,s=0;s<o;++s)a+=r.text[s].length;var c=a;n.showBackground&&(c+=o),t.call(this,{position:new Float32Array(3*c),color:new Float32Array(3*c),picking:new Qm},n),this.fontFamily=dn(n.fontFamily,"sans-serif"),this.fontStyle=dn(n.fontStyle,"normal"),this.fontWeight=dn(n.fontWeight,"bold"),this.fontSize=dn(n.fontSize,48),this.sdf=dn(n.sdf,"Chrome"===nf),this.xOffset=dn(n.xOffset,0),this.yOffset=dn(n.yOffset,0),this.zOffset=dn(n.zOffset,.5),this.attachment=dn(n.attachment,"bottom-left"),this.showBorder=dn(n.showBorder,!1),this.borderColor=dn(n.borderColor,"lightgrey"),this.borderWidth=dn(n.borderWidth,.15),this.showBackground=dn(n.showBackground,!1),this.backgroundColor=dn(n.backgroundColor,"lightgrey"),this.backgroundMargin=dn(n.backgroundMargin,.5),this.backgroundOpacity=dn(n.backgroundOpacity,1),this.text=r.text,this.positionCount=o,this.addUniforms({fontTexture:{value:null},xOffset:{value:this.xOffset},yOffset:{value:this.yOffset},zOffset:{value:this.zOffset},ortho:{value:!1},showBorder:{value:this.showBorder},borderColor:{value:new tt(this.borderColor)},borderWidth:{value:this.borderWidth},backgroundColor:{value:new tt(this.backgroundColor)},backgroundOpacity:{value:this.backgroundOpacity}}),this.addAttributes({inputTexCoord:{type:"v2",value:null},inputSize:{type:"f",value:null}}),this.setAttributes(e),this.makeTexture(),this.makeMapping()}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={parameters:{},wireframe:{},isText:{},vertexShader:{},fragmentShader:{}};return i.parameters.get=function(){return Object.assign.call(this,{fontFamily:{uniform:!0},fontStyle:{uniform:!0},fontWeight:{uniform:!0},fontSize:{uniform:!0},sdf:{updateShader:!0,uniform:!0},xOffset:{uniform:!0},yOffset:{uniform:!0},zOffset:{uniform:!0},showBorder:{uniform:!0},borderColor:{uniform:!0},borderWidth:{uniform:!0},backgroundColor:{uniform:!0},backgroundOpacity:{uniform:!0}},t.prototype.parameters,{flatShaded:void 0})},e.prototype.makeMaterial=function(){t.prototype.makeMaterial.call(this);var e=this.texture,i=this.material;i.extensions.derivatives=!0,i.lights=!1,i.uniforms.fontTexture.value=e,i.needsUpdate=!0;var r=this.wireframeMaterial;r.extensions.derivatives=!0,r.lights=!1,r.uniforms.fontTexture.value=e,r.needsUpdate=!0;var n=this.pickingMaterial;n.extensions.derivatives=!0,n.lights=!1,n.uniforms.fontTexture.value=e,n.needsUpdate=!0},e.prototype.setAttributes=function(t){var e,i,r,n,o,a,s=this,c=this.text,u=this.geometry.attributes;t.position&&(e=t.position,n=u.position.array,u.position.needsUpdate=!0),t.size&&(i=t.size,o=u.inputSize.array,u.inputSize.needsUpdate=!0),t.color&&(r=t.color,a=u.color.array,u.color.needsUpdate=!0);for(var h,l,p,d,f=this.positionCount,m=0,g=0;g<f;++g)for(l=3*g,d=c[g].length,s.showBackground&&(d+=1),p=0;p<d;++p,++m)for(var v=0;v<4;v++)h=4*m*3+3*v,e&&(n[h]=e[l],n[h+1]=e[l+1],n[h+2]=e[l+2]),i&&(o[4*m+v]=i[g]),r&&(a[h]=r[l],a[h+1]=r[l+1],a[h+2]=r[l+2])},e.prototype.makeTexture=function(){this.textAtlas=xs({font:[this.fontFamily],style:this.fontStyle,weight:this.fontWeight,size:this.fontSize,outline:this.sdf?5:0}),this.texture=this.textAtlas.texture},e.prototype.makeMapping=function(){for(var t,e,i,r,n,o,a,s,c=this,u=this.textAtlas,h=this.text,l=this.attachment,p=u.lineHeight*this.backgroundMargin*.1-10,d=this.geometry.attributes.inputTexCoord.array,f=this.geometry.attributes.mapping.array,m=this.positionCount,g=0,v=0;v<m;++v){for(r=0,o=(i=h[v]).length,n=0;n<o;++n)r+=(t=u.get(i[n])).w-2*u.outline;for(s=l.startsWith("top")?u.lineHeight/1.25:l.startsWith("middle")?u.lineHeight/2.5:0,a=l.endsWith("right")?r:l.endsWith("center")?r/2:0,a+=u.outline,s+=u.outline,c.showBackground&&(f[(e=2*g*4)+0]=-u.lineHeight/6-a-p,f[e+1]=u.lineHeight-s+p,f[e+2]=-u.lineHeight/6-a-p,f[e+3]=0-s-p,f[e+4]=r+u.lineHeight/6-a+2*u.outline+p,f[e+5]=u.lineHeight-s+p,f[e+6]=r+u.lineHeight/6-a+2*u.outline+p,f[e+7]=0-s-p,d[e+0]=10,d[e+2]=10,d[e+4]=10,d[e+6]=10,g+=1),r=0,n=0;n<o;++n,++g){t=u.get(i[n]),f[(e=2*g*4)+0]=r-a,f[e+1]=t.h-s,f[e+2]=r-a,f[e+3]=0-s,f[e+4]=r+t.w-a,f[e+5]=t.h-s,f[e+6]=r+t.w-a,f[e+7]=0-s;var y=u.width,b=u.height,x=[t.x/y,t.y/b,t.x/y,(t.y+t.h)/b,(t.x+t.w)/y,t.y/b,(t.x+t.w)/y,(t.y+t.h)/b];d.set(x,e),r+=t.w-2*u.outline}}this.geometry.attributes.inputTexCoord.needsUpdate=!0,this.geometry.attributes.mapping.needsUpdate=!0},e.prototype.getDefines=function(e){var i=t.prototype.getDefines.call(this,e);return this.sdf&&(i.SDF=1),i},e.prototype.setUniforms=function(e){!e||void 0===e.fontFamily&&void 0===e.fontStyle&&void 0===e.fontWeight&&void 0===e.fontSize&&void 0===e.sdf||(this.makeTexture(),this.makeMapping(),this.texture.needsUpdate=!0,e.fontTexture=this.texture),t.prototype.setUniforms.call(this,e)},i.wireframe.set=function(t){},i.wireframe.get=function(){return!1},i.isText.get=function(){return!0},i.vertexShader.get=function(){return"SDFFont.vert"},i.fragmentShader.get=function(){return"SDFFont.frag"},Object.defineProperties(e.prototype,i),e}(Gv),yy=new g,by=new st,xy=function(t,e){this.name=dn(t,"shape");var i=e||{};this.aspectRatio=dn(i.aspectRatio,1.5),this.sphereDetail=dn(i.sphereDetail,2),this.radialSegments=dn(i.radialSegments,50),this.disableImpostor=dn(i.disableImpostor,!1),this.openEnded=dn(i.openEnded,!1),this.labelParams=dn(i.labelParams,{}),this.boundingBox=new st,this.bufferList=[],this.meshCount=0,this.spherePosition=[],this.sphereColor=[],this.sphereRadius=[],this.sphereName=[],this.ellipsoidPosition=[],this.ellipsoidColor=[],this.ellipsoidRadius=[],this.ellipsoidMajorAxis=[],this.ellipsoidMinorAxis=[],this.ellipsoidName=[],this.cylinderPosition1=[],this.cylinderPosition2=[],this.cylinderColor=[],this.cylinderRadius=[],this.cylinderName=[],this.conePosition1=[],this.conePosition2=[],this.coneColor=[],this.coneRadius=[],this.coneName=[],this.arrowPosition1=[],this.arrowPosition2=[],this.arrowColor=[],this.arrowRadius=[],this.arrowName=[],this.labelPosition=[],this.labelColor=[],this.labelSize=[],this.labelText=[]},_y={center:{},type:{}};xy.prototype.addBuffer=function(t){this.bufferList.push(t);var e=t.geometry;return e.boundingBox||e.computeBoundingBox(),this.boundingBox.union(e.boundingBox),this},xy.prototype.addMesh=function(t,e,i,r,n){t=kn(t),e=kn(e),Array.isArray(i)&&(i=Cn(i,t.length)),r&&(r=kn(r));var o={position:t,color:e,index:i,normal:r},a=new Jm(this,Object.assign({serial:this.meshCount,name:n},o)),s=new Ov(Object.assign({picking:a},o));return this.bufferList.push(s),by.setFromArray(t),this.boundingBox.union(by),this.meshCount+=1,this},xy.prototype.addSphere=function(t,e,i,r){return _s(t,this.spherePosition),_s(e,this.sphereColor),this.sphereRadius.push(i),this.sphereName.push(r),this.boundingBox.expandByPoint(yy.fromArray(t)),this},xy.prototype.addEllipsoid=function(t,e,i,r,n,o){return _s(t,this.ellipsoidPosition),_s(e,this.ellipsoidColor),this.ellipsoidRadius.push(i),_s(r,this.ellipsoidMajorAxis),_s(n,this.ellipsoidMinorAxis),this.ellipsoidName.push(o),this.boundingBox.expandByPoint(yy.fromArray(t)),this},xy.prototype.addCylinder=function(t,e,i,r,n){return _s(t,this.cylinderPosition1),_s(e,this.cylinderPosition2),_s(i,this.cylinderColor),this.cylinderRadius.push(r),this.cylinderName.push(n),this.boundingBox.expandByPoint(yy.fromArray(t)),this.boundingBox.expandByPoint(yy.fromArray(e)),this},xy.prototype.addCone=function(t,e,i,r,n){return _s(t,this.conePosition1),_s(e,this.conePosition2),_s(i,this.coneColor),this.coneRadius.push(r),this.coneName.push(n),this.boundingBox.expandByPoint(yy.fromArray(t)),this.boundingBox.expandByPoint(yy.fromArray(e)),this},xy.prototype.addArrow=function(t,e,i,r,n){return _s(t,this.arrowPosition1),_s(e,this.arrowPosition2),_s(i,this.arrowColor),this.arrowRadius.push(r),this.arrowName.push(n),this.boundingBox.expandByPoint(yy.fromArray(t)),this.boundingBox.expandByPoint(yy.fromArray(e)),this},xy.prototype.addLabel=function(t,e,i,r){return _s(t,this.labelPosition),_s(e,this.labelColor),this.labelSize.push(i),this.labelText.push(r),this.boundingBox.expandByPoint(yy.fromArray(t)),this},xy.prototype.getBufferList=function(){var t=[];if(this.spherePosition.length){var e=new $v({position:new Float32Array(this.spherePosition),color:new Float32Array(this.sphereColor),radius:new Float32Array(this.sphereRadius),picking:new tg(this)},{sphereDetail:this.sphereDetail,disableImpostor:this.disableImpostor});t.push(e)}if(this.ellipsoidPosition.length){var i=new Zv({position:new Float32Array(this.ellipsoidPosition),color:new Float32Array(this.ellipsoidColor),radius:new Float32Array(this.ellipsoidRadius),majorAxis:new Float32Array(this.ellipsoidMajorAxis),minorAxis:new Float32Array(this.ellipsoidMinorAxis),picking:new Km(this)},{sphereDetail:this.sphereDetail,disableImpostor:this.disableImpostor});t.push(i)}if(this.cylinderPosition1.length){var r=new oy({position1:new Float32Array(this.cylinderPosition1),position2:new Float32Array(this.cylinderPosition2),color:new Float32Array(this.cylinderColor),color2:new Float32Array(this.cylinderColor),radius:new Float32Array(this.cylinderRadius),picking:new Gm(this)},{radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,openEnded:this.openEnded});t.push(r)}if(this.conePosition1.length){var n=new ly({position1:new Float32Array(this.conePosition1),position2:new Float32Array(this.conePosition2),color:new Float32Array(this.coneColor),radius:new Float32Array(this.coneRadius),picking:new qm(this)},{radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,openEnded:this.openEnded});t.push(n)}if(this.arrowPosition1.length){var o=new dy({position1:new Float32Array(this.arrowPosition1),position2:new Float32Array(this.arrowPosition2),color:new Float32Array(this.arrowColor),radius:new Float32Array(this.arrowRadius),picking:new Vm(this)},{aspectRatio:this.aspectRatio,radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,openEnded:this.openEnded});t.push(o)}if(this.labelPosition.length){var a=new vy({position:new Float32Array(this.labelPosition),color:new Float32Array(this.labelColor),size:new Float32Array(this.labelSize),text:this.labelText},this.labelParams);t.push(a)}return this.bufferList.concat(t)},xy.prototype.dispose=function(){this.bufferList.forEach(function(t){t.dispose()}),this.bufferList.length=0,this.spherePosition.length=0,this.sphereColor.length=0,this.sphereRadius.length=0,this.sphereName.length=0,this.ellipsoidPosition.length=0,this.ellipsoidColor.length=0,this.ellipsoidRadius.length=0,this.ellipsoidMajorAxis.length=0,this.ellipsoidMinorAxis.length=0,this.ellipsoidName.length=0,this.cylinderPosition1.length=0,this.cylinderPosition2.length=0,this.cylinderColor.length=0,this.cylinderRadius.length=0,this.cylinderName.length=0,this.conePosition1.length=0,this.conePosition2.length=0,this.coneColor.length=0,this.coneRadius.length=0,this.coneName.length=0,this.arrowPosition1.length=0,this.arrowPosition2.length=0,this.arrowColor.length=0,this.arrowRadius.length=0,this.arrowName.length=0,this.labelPosition.length=0,this.labelColor.length=0,this.labelSize.length=0,this.labelText.length=0},_y.center.get=function(){return this._center||(this._center=this.boundingBox.getCenter()),this._center},_y.type.get=function(){return"Shape"},Object.defineProperties(xy.prototype,_y);var wy=function(t,e,i){this.type="",this.parameters={lazy:{type:"boolean"},clipNear:{type:"range",step:1,max:100,min:0,buffer:!0},clipRadius:{type:"number",precision:1,max:1e3,min:0,buffer:!0},clipCenter:{type:"vector3",precision:1,buffer:!0},flatShaded:{type:"boolean",buffer:!0},opacity:{type:"range",step:.01,max:1,min:0,buffer:!0},depthWrite:{type:"boolean",buffer:!0},side:{type:"select",buffer:!0,options:{front:"front",back:"back",double:"double"}},wireframe:{type:"boolean",buffer:!0},linewidth:{type:"integer",max:50,min:1,buffer:!0},colorScheme:{type:"select",update:"color",options:{}},colorScale:{type:"select",update:"color",options:lf.getScales()},colorReverse:{type:"boolean",update:"color"},colorValue:{type:"color",update:"color"},colorDomain:{type:"hidden",update:"color"},colorMode:{type:"select",update:"color",options:lf.getModes()},roughness:{type:"range",step:.01,max:1,min:0,buffer:!0},metalness:{type:"range",step:.01,max:1,min:0,buffer:!0},diffuse:{type:"color",buffer:!0},matrix:{type:"hidden",buffer:!0}},this.viewer=e,this.tasks=new Cf,this.queue=new ms(this.make.bind(this)),this.bufferList=[],this.parameters.colorScheme&&(this.parameters.colorScheme.options=lf.getSchemes())};wy.prototype.init=function(t){var e=t||{};this.clipNear=dn(e.clipNear,0),this.clipRadius=dn(e.clipRadius,0),this.clipCenter=dn(e.clipCenter,new g),this.flatShaded=dn(e.flatShaded,!1),this.side=dn(e.side,"double"),this.opacity=dn(e.opacity,1),this.depthWrite=dn(e.depthWrite,!0),this.wireframe=dn(e.wireframe,!1),this.linewidth=dn(e.linewidth,2),this.setColor(e.color,e),this.colorScheme=dn(e.colorScheme,"uniform"),this.colorScale=dn(e.colorScale,""),this.colorReverse=dn(e.colorReverse,!1),this.colorValue=dn(e.colorValue,9474192),this.colorDomain=dn(e.colorDomain,void 0),this.colorMode=dn(e.colorMode,"hcl"),this.visible=dn(e.visible,!0),this.quality=dn(e.quality,void 0),this.roughness=dn(e.roughness,.4),this.metalness=dn(e.metalness,0),this.diffuse=dn(e.diffuse,16777215),this.lazy=dn(e.lazy,!1),this.lazyProps={build:!1,bufferParams:{},what:{}},this.matrix=dn(e.matrix,new v);var i=this.parameters;!0===i.sphereDetail&&(i.sphereDetail={type:"integer",max:3,min:0,rebuild:"impostor"}),!0===i.radialSegments&&(i.radialSegments={type:"integer",max:25,min:5,rebuild:"impostor"}),!0===i.openEnded&&(i.openEnded={type:"boolean",rebuild:"impostor",buffer:!0}),!0===i.disableImpostor&&(i.disableImpostor={type:"boolean",rebuild:!0}),"low"===e.quality?(i.sphereDetail&&(this.sphereDetail=0),i.radialSegments&&(this.radialSegments=5)):"medium"===e.quality?(i.sphereDetail&&(this.sphereDetail=1),i.radialSegments&&(this.radialSegments=10)):"high"===e.quality?(i.sphereDetail&&(this.sphereDetail=2),i.radialSegments&&(this.radialSegments=20)):(i.sphereDetail&&(this.sphereDetail=dn(e.sphereDetail,1)),i.radialSegments&&(this.radialSegments=dn(e.radialSegments,10))),i.openEnded&&(this.openEnded=dn(e.openEnded,!0)),i.disableImpostor&&(this.disableImpostor=dn(e.disableImpostor,!1))},wy.prototype.getColorParams=function(t){return Object.assign({scheme:this.colorScheme,scale:this.colorScale,reverse:this.colorReverse,value:this.colorValue,domain:this.colorDomain,mode:this.colorMode},t)},wy.prototype.getBufferParams=function(t){return Object.assign({clipNear:this.clipNear,clipRadius:this.clipRadius,clipCenter:this.clipCenter,flatShaded:this.flatShaded,opacity:this.opacity,depthWrite:this.depthWrite,side:this.side,wireframe:this.wireframe,linewidth:this.linewidth,roughness:this.roughness,metalness:this.metalness,diffuse:this.diffuse,matrix:this.matrix},t)},wy.prototype.setColor=function(t,e){return Object.keys(lf.getSchemes()).includes(t)?e?e.colorScheme=t:this.setParameters({colorScheme:t}):void 0!==t&&(t=new tt(t).getHex(),e?(e.colorScheme="uniform",e.colorValue=t):this.setParameters({colorScheme:"uniform",colorValue:t})),this},wy.prototype.create=function(){},wy.prototype.update=function(){this.build()},wy.prototype.build=function(t){return this.lazy&&!this.visible?void(this.lazyProps.build=!0):this.prepare?(this.queue.length()>0?(this.tasks.change(1-this.queue.length()),this.queue.kill()):this.tasks.increment(),void this.queue.push(t||!1)):(this.tasks.increment(),void this.make())},wy.prototype.make=function(e,i){t.Debug&&cf.time("Representation.make "+this.type);var r=function(){e?(this.update(e),this.viewer.requestRender(),this.tasks.decrement(),i&&i()):(this.clear(),this.create(),this.manualAttach||this.disposed||(t.Debug&&cf.time("Representation.attach "+this.type),this.attach(function(){t.Debug&&cf.timeEnd("Representation.attach "+this.type),this.tasks.decrement(),i&&i()}.bind(this)))),t.Debug&&cf.timeEnd("Representation.make "+this.type)}.bind(this);this.prepare?this.prepare(r):r()},wy.prototype.attach=function(t){this.setVisibility(this.visible),t()},wy.prototype.setVisibility=function(t,e){if(this.visible=t,this.visible){var i=this.lazyProps,r=i.bufferParams,n=i.what;if(i.build)return i.build=!1,void this.build();(Object.keys(r).length||Object.keys(n).length)&&(i.bufferParams={},i.what={},this.updateParameters(r,n))}return this.bufferList.forEach(function(e){e.setVisibility(t)}),e||this.viewer.requestRender(),this},wy.prototype.setParameters=function(t,e,i){var r=this,n=t||{},o=this.parameters;e=e||{},i=i||!1;var a={};for(var s in n)void 0!==n[s]&&void 0!==o[s]&&(o[s].int&&(n[s]=parseInt(n[s])),o[s].float&&(n[s]=parseFloat(n[s])),(n[s]!==r[s]||n[s].equals&&!n[s].equals(r[s]))&&(r[s].set?r[s].set(n[s]):r[s]=n[s],o[s].buffer&&(!0===o[s].buffer?a[s]=n[s]:a[o[s].buffer]=n[s]),o[s].update&&(e[o[s].update]=!0),!o[s].rebuild||"impostor"===o[s].rebuild&&sf&&!r.disableImpostor||(i=!0)));return i?this.build():this.updateParameters(a,e),this},wy.prototype.updateParameters=function(t,e){if(this.lazy&&!this.visible)return Object.assign(this.lazyProps.bufferParams,t),void Object.assign(this.lazyProps.what,e);this.bufferList.forEach(function(e){e.setParameters(t)}),Object.keys(e).length&&this.update(e),this.viewer.requestRender()},wy.prototype.getParameters=function(){var t=this,e={lazy:this.lazy,visible:this.visible,quality:this.quality};return Object.keys(this.parameters).forEach(function(i){null!==t.parameters[i]&&(e[i]=t[i])}),e},wy.prototype.clear=function(){var t=this;this.bufferList.forEach(function(e){t.viewer.remove(e),e.dispose()}),this.bufferList.length=0,this.viewer.requestRender()},wy.prototype.dispose=function(){this.disposed=!0,this.queue.kill(),this.tasks.dispose(),this.clear()};var Sy=function(t){function e(e,i,r){Array.isArray(e)||(e=[e]),t.call(this,e,i,r),this.type="buffer",this.parameters=Object.assign({},this.parameters,{colorScheme:null,colorScale:null,colorValue:null,colorDomain:null,colorMode:null}),this.buffer=e,this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){t.prototype.init.call(this,e),this.build()},e.prototype.create=function(){this.bufferList.push.apply(this.bufferList,this.buffer)},e.prototype.attach=function(t){var e=this;this.bufferList.forEach(function(t){e.viewer.add(t),t.setParameters(e.getBufferParams())}),this.setVisibility(this.visible),t()},e}(wy),Ay=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={isSurface:{}};return i.isSurface.get=function(){return!0},Object.defineProperties(e.prototype,i),e}(Ov),My=function(t){this.size=t.size,this.side=t.side,this.wireframe=t.wireframe,this.visible=t.visible,this.geometry=t.geometry,this.picking=t.picking,this.background=t.background,this.group=new Re,this.wireframeGroup=new Re,this.pickingGroup=new Re,this.matrix=t.matrix,this.frontMeshes=[],this.backMeshes=[];var e=t,i=new t.constructor;e.makeMaterial(),i.makeMaterial(),i.picking=t.picking,i.geometry=t.geometry,i.wireframeGeometry=t.wireframeGeometry,i.setParameters(t.getParameters()),i.updateShader(),e.setParameters({side:"front"}),i.setParameters({side:"back",opacity:i.opacity}),this.buffer=t,this.frontBuffer=e,this.backBuffer=i},Py={matrix:{},pickable:{}};Py.matrix.set=function(t){Lv.prototype.setMatrix.call(this,t)},Py.matrix.get=function(){return this.group.matrix.clone()},Py.pickable.get=function(){return!!this.picking},My.prototype.getMesh=function(t){var e,i;return t?(i=this.backBuffer.getPickingMesh(),e=this.frontBuffer.getPickingMesh()):(i=this.backBuffer.getMesh(),e=this.frontBuffer.getMesh()),this.frontMeshes.push(e),this.backMeshes.push(i),this.setParameters({side:this.side}),(new Re).add(i,e)},My.prototype.getWireframeMesh=function(){return this.buffer.getWireframeMesh()},My.prototype.getPickingMesh=function(){return this.getMesh(!0)},My.prototype.setAttributes=function(t){this.buffer.setAttributes(t)},My.prototype.setParameters=function(t){"front"===(t=Object.assign({},t)).side?(this.frontMeshes.forEach(ws),this.backMeshes.forEach(Ss)):"back"===t.side?(this.frontMeshes.forEach(Ss),this.backMeshes.forEach(ws)):"double"===t.side&&(this.frontMeshes.forEach(ws),this.backMeshes.forEach(ws)),void 0!==t.matrix&&(this.matrix=t.matrix),delete t.matrix,void 0!==t.side&&(this.side=t.side),delete t.side,this.frontBuffer.setParameters(t),void 0!==t.wireframe&&(this.wireframe=t.wireframe,this.setVisibility(this.visible)),delete t.wireframe,this.backBuffer.setParameters(t)},My.prototype.dispose=function(){this.frontBuffer.dispose(),this.backBuffer.dispose()},Object.defineProperties(My.prototype,Py),My.prototype.setVisibility=Lv.prototype.setVisibility,mf.add("shader/Line.vert","uniform float nearClip;\nuniform vec3 clipCenter;\nvarying vec3 vViewPosition;\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#include color_pars_vertex\nvoid main(){\n#include color_vertex\n#include begin_vertex\n#include project_vertex\nvViewPosition = -mvPosition.xyz;\n#if defined( RADIUS_CLIP )\nvClipCenter = -( modelViewMatrix * vec4( clipCenter, 1.0 ) ).xyz;\n#endif\n#include nearclip_vertex\n}"),mf.add("shader/Line.frag","uniform float opacity;\nuniform float nearClip;\nuniform float clipRadius;\nvarying vec3 vViewPosition;\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#include common\n#include color_pars_fragment\n#include fog_pars_fragment\nvoid main(){\n#include nearclip_fragment\n#include radiusclip_fragment\ngl_FragColor = vec4( vColor, opacity );\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n}");var Ty=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={isLine:{},vertexShader:{},fragmentShader:{}};return i.isLine.get=function(){return!0},i.vertexShader.get=function(){return"Line.vert"},i.fragmentShader.get=function(){return"Line.frag"},Object.defineProperties(e.prototype,i),e}(Lv),Ey=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="surface",this.parameters=Object.assign({isolevelType:{type:"select",options:{value:"value",sigma:"sigma"}},isolevel:{type:"number",precision:2,max:1e3,min:-1e3},negateIsolevel:{type:"boolean"},smooth:{type:"integer",precision:1,max:10,min:0},background:{type:"boolean",rebuild:!0},opaqueBack:{type:"boolean",buffer:!0},boxSize:{type:"integer",precision:1,max:100,min:0},colorVolume:{type:"hidden"},contour:{type:"boolean",rebuild:!0},useWorker:{type:"boolean",rebuild:!0},wrap:{type:"boolean",rebuild:!0}},this.parameters),e instanceof Vg?(this.surface=void 0,this.volume=e):(this.surface=e,this.volume=void 0),this.boxCenter=new g,this.__boxCenter=new g,this.box=new st,this.__box=new st,this._position=new g,this.setBox=function(){this._position.copy(i.translationGroup.position).negate(),this._position.equals(this.boxCenter)||this.setParameters({boxCenter:this._position})},this.viewer.signals.ticked.add(this.setBox,this),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"uniform"),i.colorValue=dn(i.colorValue,14540253),this.isolevelType=dn(i.isolevelType,"sigma"),this.isolevel=dn(i.isolevel,2),this.negateIsolevel=dn(i.negateIsolevel,!1),this.smooth=dn(i.smooth,0),this.background=dn(i.background,!1),this.opaqueBack=dn(i.opaqueBack,!0),this.boxSize=dn(i.boxSize,0),this.colorVolume=dn(i.colorVolume,void 0),this.contour=dn(i.contour,!1),this.useWorker=dn(i.useWorker,!0),this.wrap=dn(i.wrap,!1),t.prototype.init.call(this,i),this.build()},e.prototype.attach=function(t){var e=this;this.bufferList.forEach(function(t){e.viewer.add(t)}),this.setVisibility(this.visible),t()},e.prototype.prepare=function(t){var e=this;if(this.volume){var i;if(i="sigma"===this.isolevelType?this.volume.getValueForSigma(this.isolevel):this.isolevel,this.negateIsolevel&&(i*=-1),!this.surface||this.__isolevel!==i||this.__smooth!==this.smooth||this.__contour!==this.contour||this.__wrap!==this.wrap||this.__boxSize!==this.boxSize||this.boxSize>0&&!this.__boxCenter.equals(this.boxCenter)){this.__isolevel=i,this.__smooth=this.smooth,this.__contour=this.contour,this.__wrap=this.wrap,this.__boxSize=this.boxSize,this.__boxCenter.copy(this.boxCenter),this.__box.copy(this.box);var r=function(i){e.surface=i,t()};this.useWorker?this.volume.getSurfaceWorker(i,this.smooth,this.boxCenter,this.boxSize,this.contour,this.wrap,r):r(this.volume.getSurface(i,this.smooth,this.boxCenter,this.boxSize,this.contour,this.wrap))}else t()}else t()},e.prototype.create=function(){var t,e={position:this.surface.getPosition(),color:this.surface.getColor(this.getColorParams()),index:this.surface.getIndex()};if(this.contour)t=new Ty(e,this.getBufferParams({wireframe:!1}));else{e.normal=this.surface.getNormal(),e.picking=this.surface.getPicking();var i=new Ay(e,this.getBufferParams({background:this.background,opaqueBack:this.opaqueBack,dullInterior:!1}));t=new My(i)}this.bufferList.push(t)},e.prototype.update=function(t){if(0!==this.bufferList.length){var e={};(t=t||{}).position&&(e.position=this.surface.getPosition()),t.color&&(e.color=this.surface.getColor(this.getColorParams())),t.index&&(e.index=this.surface.getIndex()),t.normal&&(e.normal=this.surface.getNormal()),this.bufferList.forEach(function(t){t.setAttributes(e)})}},e.prototype.setParameters=function(e,i,r){return e&&void 0!==e.isolevelType&&this.volume&&("value"===this.isolevelType&&"sigma"===e.isolevelType?this.isolevel=this.volume.getSigmaForValue(this.isolevel):"sigma"===this.isolevelType&&"value"===e.isolevelType&&(this.isolevel=this.volume.getValueForSigma(this.isolevel)),this.isolevelType=e.isolevelType),e&&e.boxCenter&&(this.boxCenter.copy(e.boxCenter),delete e.boxCenter),e&&e.wireframe&&(e.contour||void 0===e.contour&&this.contour)&&(e.wireframe=!1),t.prototype.setParameters.call(this,e,i,r),this.volume&&this.volume.getBox(this.boxCenter,this.boxSize,this.box),e&&void 0!==e.colorVolume&&(i.color=!0),this.surface&&(void 0!==e.isolevel||void 0!==e.negateIsolevel||void 0!==e.smooth||void 0!==e.wrap||void 0!==e.boxSize||this.boxSize>0&&!this.__box.equals(this.box))&&this.build({position:!0,color:!0,index:!0,normal:!this.contour}),this},e.prototype.getColorParams=function(){var e=t.prototype.getColorParams.call(this);return e.volume=this.colorVolume,e},e.prototype.dispose=function(){this.viewer.signals.ticked.remove(this.setBox,this),t.prototype.dispose.call(this)},e}(wy);mf.add("shader/Point.vert","uniform float nearClip;\nuniform float clipRadius;\nuniform vec3 clipCenter;\nuniform float size;\nuniform float canvasHeight;\nuniform float pixelRatio;\nvarying vec3 vViewPosition;\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#if defined( PICKING )\n#include unpack_color\nattribute float primitiveId;\nvarying vec3 vPickingColor;\n#else\n#include color_pars_vertex\n#endif\n#include common\nvoid main(){\n#if defined( PICKING )\nvPickingColor = unpackColor( primitiveId );\n#else\n#include color_vertex\n#endif\n#include begin_vertex\n#include project_vertex\n#ifdef USE_SIZEATTENUATION\ngl_PointSize = size * pixelRatio * ( ( canvasHeight / 2.0 ) / -mvPosition.z );\n#else\ngl_PointSize = size * pixelRatio;\n#endif\nvViewPosition = -mvPosition.xyz;\n#if defined( RADIUS_CLIP )\nvClipCenter = -( modelViewMatrix * vec4( clipCenter, 1.0 ) ).xyz;\n#endif\n#include nearclip_vertex\n#include radiusclip_vertex\n}"),mf.add("shader/Point.frag","uniform vec3 diffuse;\nuniform float opacity;\nuniform float nearClip;\nuniform float clipRadius;\nvarying vec3 vViewPosition;\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#ifdef USE_MAP\nuniform sampler2D map;\n#endif\n#if defined( PICKING )\nuniform float objectId;\nvarying vec3 vPickingColor;\n#else\n#include common\n#include color_pars_fragment\n#include fog_pars_fragment\n#endif\nvoid main(){\n#include nearclip_fragment\n#include radiusclip_fragment\n#if defined( PICKING )\n#ifdef USE_MAP\nif( texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) ).a < 0.5 )\ndiscard;\n#endif\ngl_FragColor = vec4( vPickingColor, objectId );\n#else\nvec3 outgoingLight = vec3( 0.0 );\nvec4 diffuseColor = vec4( diffuse, 1.0 );\n#ifdef USE_MAP\ndiffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );\n#endif\n#include color_fragment\n#include alphatest_fragment\noutgoingLight = diffuseColor.rgb;\ngl_FragColor = vec4( outgoingLight, diffuseColor.a * opacity );\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n#endif\n}");var Cy=function(t){function e(e,i){var r=e||{},n=i||{};r.primitiveId||(r.primitiveId=Co(r.position.length/3)),t.call(this,r,n),this.pointSize=dn(n.pointSize,1),this.sizeAttenuation=dn(n.sizeAttenuation,!0),this.sortParticles=dn(n.sortParticles,!1),this.alphaTest=dn(n.alphaTest,.5),this.useTexture=dn(n.useTexture,!1),this.forceTransparent=dn(n.forceTransparent,!1),this.edgeBleach=dn(n.edgeBleach,0),this.addUniforms({size:{value:this.pointSize},canvasHeight:{value:1},pixelRatio:{value:1},map:{value:null}})}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={parameters:{},isPoint:{},vertexShader:{},fragmentShader:{}};return i.parameters.get=function(){return Object.assign.call(this,{pointSize:{uniform:"size"},sizeAttenuation:{updateShader:!0},sortParticles:{},alphaTest:{updateShader:!0},useTexture:{updateShader:!0},forceTransparent:{},edgeBleach:{uniform:!0}},t.prototype.parameters)},e.prototype.makeMaterial=function(){t.prototype.makeMaterial.call(this),this.makeTexture();var e=this.material,i=this.wireframeMaterial,r=this.pickingMaterial;e.uniforms.map.value=this.tex,e.needsUpdate=!0,i.uniforms.map.value=this.tex,i.needsUpdate=!0,r.uniforms.map.value=this.tex,r.needsUpdate=!0},e.prototype.makeTexture=function(){this.tex&&this.tex.dispose(),this.tex=Ms({delta:this.edgeBleach})},e.prototype.getDefines=function(e){var i=t.prototype.getDefines.call(this,e);return this.sizeAttenuation&&(i.USE_SIZEATTENUATION=1),this.useTexture&&(i.USE_MAP=1),this.alphaTest>0&&this.alphaTest<=1&&(i.ALPHATEST=this.alphaTest.toPrecision(2)),i},e.prototype.setUniforms=function(e){e&&void 0!==e.edgeBleach&&(this.makeTexture(),e.map=this.tex),t.prototype.setUniforms.call(this,e)},e.prototype.dispose=function(){t.prototype.dispose.call(this),this.tex&&this.tex.dispose()},i.isPoint.get=function(){return!0},i.vertexShader.get=function(){return"Point.vert"},i.fragmentShader.get=function(){return"Point.frag"},Object.defineProperties(e.prototype,i),e}(Lv),Iy=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="dot",this.parameters=Object.assign({thresholdType:{type:"select",rebuild:!0,options:{value:"value",sigma:"sigma"}},thresholdMin:{type:"number",precision:3,max:1/0,min:-1/0,rebuild:!0},thresholdMax:{type:"number",precision:3,max:1/0,min:-1/0,rebuild:!0},thresholdOut:{type:"boolean",rebuild:!0},dotType:{type:"select",rebuild:!0,options:{"":"",sphere:"sphere",point:"point"}},radiusType:{type:"select",options:{"":"",value:"value","abs-value":"abs-value","value-min":"value-min",deviation:"deviation",size:"size"}},radius:{type:"number",precision:3,max:10,min:.001,property:"size"},scale:{type:"number",precision:3,max:10,min:.001},sphereDetail:!0,disableImpostor:!0,pointSize:{type:"number",precision:1,max:100,min:0,buffer:!0},sizeAttenuation:{type:"boolean",buffer:!0},sortParticles:{type:"boolean",rebuild:!0},useTexture:{type:"boolean",buffer:!0},alphaTest:{type:"range",step:.001,max:1,min:0,buffer:!0},forceTransparent:{type:"boolean",buffer:!0},edgeBleach:{type:"range",step:.001,max:1,min:0,buffer:!0}},this.parameters,{colorScheme:{type:"select",update:"color",options:{"":"",value:"value",uniform:"uniform",random:"random"}}}),e instanceof Vg?(this.surface=void 0,this.volume=new Hg(e)):(this.surface=e,this.volume=void 0),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"uniform"),i.colorValue=dn(i.colorValue,14540253),this.thresholdType=dn(i.thresholdType,"sigma"),this.thresholdMin=dn(i.thresholdMin,2),this.thresholdMax=dn(i.thresholdMax,1/0),this.thresholdOut=dn(i.thresholdOut,!1),this.dotType=dn(i.dotType,"point"),this.radius=dn(i.radius,.1),this.scale=dn(i.scale,1),this.pointSize=dn(i.pointSize,1),this.sizeAttenuation=dn(i.sizeAttenuation,!0),this.sortParticles=dn(i.sortParticles,!1),this.useTexture=dn(i.useTexture,!1),this.alphaTest=dn(i.alphaTest,.5),this.forceTransparent=dn(i.forceTransparent,!1),this.edgeBleach=dn(i.edgeBleach,0),t.prototype.init.call(this,i),this.build()},e.prototype.attach=function(t){var e=this;this.bufferList.forEach(function(t){e.viewer.add(t)}),this.setVisibility(this.visible),t()},e.prototype.create=function(){var t={};if(this.volume){var e,i,r=this.volume;"sigma"===this.thresholdType?(e=r.getValueForSigma(this.thresholdMin),i=r.getValueForSigma(this.thresholdMax)):(e=this.thresholdMin,i=this.thresholdMax),r.setFilter(e,i,this.thresholdOut),t.position=r.getDataPosition(),t.color=r.getDataColor(this.getColorParams()),"sphere"===this.dotType&&(t.radius=r.getDataSize(this.radius,this.scale),t.picking=r.getDataPicking())}else{var n=this.surface;t.position=n.getPosition(),t.color=n.getColor(this.getColorParams()),"sphere"===this.dotType&&(t.radius=n.getSize(this.radius,this.scale),t.picking=n.getPicking())}"sphere"===this.dotType?this.dotBuffer=new $v(t,this.getBufferParams({sphereDetail:this.sphereDetail,disableImpostor:this.disableImpostor,dullInterior:!1})):this.dotBuffer=new Cy(t,this.getBufferParams({pointSize:this.pointSize,sizeAttenuation:this.sizeAttenuation,sortParticles:this.sortParticles,useTexture:this.useTexture,alphaTest:this.alphaTest,forceTransparent:this.forceTransparent,edgeBleach:this.edgeBleach})),this.bufferList.push(this.dotBuffer)},e.prototype.update=function(t){if(0!==this.bufferList.length){var e={};(t=t||{}).color&&(this.volume?e.color=this.volume.getDataColor(this.getColorParams()):e.color=this.surface.getColor(this.getColorParams())),"sphere"===this.dotType&&(t.radius||t.scale)&&(this.volume?e.radius=this.volume.getDataSize(this.radius,this.scale):e.radius=this.surface.getSize(this.radius,this.scale)),this.dotBuffer.setAttributes(e)}},e.prototype.setParameters=function(e,i,r){return i=i||{},e&&void 0!==e.thresholdType&&this.volume instanceof Vg&&("value"===this.thresholdType&&"sigma"===e.thresholdType?(this.thresholdMin=this.volume.getSigmaForValue(this.thresholdMin),this.thresholdMax=this.volume.getSigmaForValue(this.thresholdMax)):"sigma"===this.thresholdType&&"value"===e.thresholdType&&(this.thresholdMin=this.volume.getValueForSigma(this.thresholdMin),this.thresholdMax=this.volume.getValueForSigma(this.thresholdMax)),this.thresholdType=e.thresholdType),e&&void 0!==e.radiusType&&("radius"===e.radiusType?this.radius=.1:this.radius=e.radiusType,i.radius=!0,"sphere"!==this.dotType||sf&&!this.disableImpostor||(r=!0)),e&&void 0!==e.radius&&(i.radius=!0,"sphere"!==this.dotType||sf&&!this.disableImpostor||(r=!0)),e&&void 0!==e.scale&&(i.scale=!0,"sphere"!==this.dotType||sf&&!this.disableImpostor||(r=!0)),t.prototype.setParameters.call(this,e,i,r),this},e}(wy);mf.add("shader/Image.vert","uniform float clipRadius;\nuniform vec3 clipCenter;\nvarying vec2 vUv;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || !defined( PICKING )\nvarying vec3 vViewPosition;\n#endif\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\nvoid main() {\n#include begin_vertex\n#include project_vertex\nvUv = uv;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || !defined( PICKING )\nvViewPosition = -mvPosition.xyz;\n#endif\n#if defined( RADIUS_CLIP )\nvClipCenter = -( modelViewMatrix * vec4( clipCenter, 1.0 ) ).xyz;\n#endif\n}"),mf.add("shader/Image.frag","uniform sampler2D map;\nuniform float opacity;\nuniform vec2 mapSize;\nuniform float nearClip;\nuniform float clipRadius;\nvarying vec2 vUv;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || !defined( PICKING )\nvarying vec3 vViewPosition;\n#endif\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\n#if defined( PICKING )\nuniform sampler2D pickingMap;\nuniform float objectId;\n#else\n#include fog_pars_fragment\n#endif\n#if defined( CUBIC_INTERPOLATION )\n#if defined( CATMULROM_FILTER ) || defined( MITCHELL_FILTER )\n#if defined( CATMULROM_FILTER )\nconst float B = 0.0;\nconst float C = 0.5;\n#elif defined( MITCHELL_FILTER )\nconst float B = 0.333;\nconst float C = 0.333;\n#endif\nfloat filter( float x ){\nfloat f = x;\nif( f < 0.0 ){\nf = -f;\n}\nif( f < 1.0 ){\nreturn ( ( 12.0 - 9.0 * B - 6.0 * C ) * ( f * f * f ) +\n( -18.0 + 12.0 * B + 6.0 *C ) * ( f * f ) +\n( 6.0 - 2.0 * B ) ) / 6.0;\n}else if( f >= 1.0 && f < 2.0 ){\nreturn ( ( -B - 6.0 * C ) * ( f * f * f )\n+ ( 6.0 * B + 30.0 * C ) * ( f *f ) +\n( - ( 12.0 * B ) - 48.0 * C ) * f +\n8.0 * B + 24.0 * C ) / 6.0;\n}else{\nreturn 0.0;\n}\n}\n#elif defined( BSPLINE_FILTER )\nfloat filter( float x ){\nfloat f = x;\nif( f < 0.0 ){\nf = -f;\n}\nif( f >= 0.0 && f <= 1.0 ){\nreturn ( 2.0 / 3.0 ) + ( 0.5 ) * ( f * f * f ) - ( f * f );\n}else if( f > 1.0 && f <= 2.0 ){\nreturn 1.0 / 6.0 * pow( ( 2.0 - f ), 3.0 );\n}\nreturn 1.0;\n}\n#else\nfloat filter( float x ){\nreturn 1.0;\n}\n#endif\nvec4 biCubic( sampler2D tex, vec2 texCoord ){\nvec2 texelSize = 1.0 / mapSize;\ntexCoord -= texelSize / 2.0;\nvec4 nSum = vec4( 0.0 );\nfloat nDenom = 0.0;\nvec2 cell = fract( texCoord * mapSize );\nfor( float m = -1.0; m <= 2.0; ++m ){\nfor( float n = -1.0; n <= 2.0; ++n ){\nvec4 vecData = texture2D(\ntex, texCoord + texelSize * vec2( m, n )\n);\nfloat c = filter( m - cell.x ) * filter( -n + cell.y );\nnSum += vecData * c;\nnDenom += c;\n}\n}\nreturn nSum / nDenom;\n}\n#endif\nvoid main(){\n#include nearclip_fragment\n#include radiusclip_fragment\n#if defined( CUBIC_INTERPOLATION )\ngl_FragColor = biCubic( map, vUv );\n#else\ngl_FragColor = texture2D( map, vUv );\n#endif\n#if defined( PICKING )\nif( gl_FragColor.a < 0.7 )\ndiscard;\ngl_FragColor = vec4( texture2D( pickingMap, vUv ).xyz, objectId );\n#else\nif( gl_FragColor.a < 0.01 )\ndiscard;\ngl_FragColor.a *= opacity;\n#include fog_fragment\n#endif\n}");var Ly=new Uint16Array([0,1,2,1,3,2]),Ry=new Float32Array([0,1,0,0,1,1,1,0]),Oy=function(t){function e(e,i){var r=e||{},n=i||{};t.call(this,{position:r.position,index:Ly,picking:r.picking},n),this.forceTransparent=!0,this.filter=dn(n.filter,"nearest");var o=new y(r.imageData,r.width,r.height);o.flipY=!0,this.tex=o;for(var a=r.imageData.length,s=new Uint8Array(a),c=0;c<a;c+=4){var u=c/4;s[c]=u>>16&255,s[c+1]=u>>8&255,s[c+2]=255&u}var h=new y(s,r.width,r.height);h.flipY=!0,h.minFilter=Ph,h.magFilter=Ph,this.pickingTex=h,this.addUniforms({map:{value:o},pickingMap:{value:h},mapSize:{value:new l(r.width,r.height)}}),this.geometry.addAttribute("uv",new _t(Ry,2))}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={parameters:{},vertexShader:{},fragmentShader:{}};return i.parameters.get=function(){return Object.assign.call(this,{filter:{updateShader:!0,uniform:!0}},t.prototype.parameters)},e.prototype.getDefines=function(e){var i=t.prototype.getDefines.call(this,e);return this.filter.startsWith("cubic")&&(i.CUBIC_INTERPOLATION=1,this.filter.endsWith("bspline")?i.BSPLINE_FILTER=1:this.filter.endsWith("catmulrom")?i.CATMULROM_FILTER=1:this.filter.endsWith("mitchell")&&(i.MITCHELL_FILTER=1)),i},e.prototype.updateTexture=function(){var t=this.tex;this.filter.startsWith("cubic")?(t.minFilter=Ph,t.magFilter=Ph):"linear"===this.filter?(t.minFilter=Ch,t.magFilter=Ch):(t.minFilter=Ph,t.magFilter=Ph),t.needsUpdate=!0,this.pickingTex.needsUpdate=!0},e.prototype.makeMaterial=function(){t.prototype.makeMaterial.call(this),this.updateTexture();var e=this.material;e.uniforms.map.value=this.tex,e.blending=Ou,e.needsUpdate=!0;var i=this.wireframeMaterial;i.uniforms.map.value=this.tex,i.blending=Ou,i.needsUpdate=!0;var r=this.pickingMaterial;r.uniforms.map.value=this.tex,r.uniforms.pickingMap.value=this.pickingTex,r.blending=Ou,r.needsUpdate=!0},e.prototype.setUniforms=function(e){e&&void 0!==e.filter&&(this.updateTexture(),e.map=this.tex),t.prototype.setUniforms.call(this,e)},i.vertexShader.get=function(){return"Image.vert"},i.fragmentShader.get=function(){return"Image.frag"},Object.defineProperties(e.prototype,i),e}(Lv),Dy=function(t,e){var i=e||{};this.dimension=dn(i.dimension,"x"),this.positionType=dn(i.positionType,"percent"),this.position=dn(i.position,30),this.thresholdType=dn(i.thresholdType,"sigma"),this.thresholdMin=dn(i.thresholdMin,-1/0),this.thresholdMax=dn(i.thresholdMax,1/0),this.normalize=dn(i.normalize,!1),this.volume=t};Dy.prototype.getPositionFromCoordinate=function(t){var e,i=this.dimension,r=this.volume,n=r.matrix,o=(new g).setFromMatrixPosition(n)[i],a=(new g).setFromMatrixScale(n)[i];return e="x"===i?r.nx:"y"===i?r.ny:r.nz,Math.round(((t-o)/(e/100)+1)/a)},Dy.prototype.getData=function(t){function e(t){return Math.round(t/100*(o-1))}function i(t,e,i,r){return 3*(i*a.ny*a.nx+e*a.nx+t)+r}function r(t,e,i,r){m.set(t,e,i).applyMatrix4(c).toArray(f,r)}var n=this;t=t||{};var o,a=this.volume,s=a.data,c=a.matrix;o="coordinate"===this.positionType?this.getPositionFromCoordinate(this.position):this.position;var u,h,l,p,d,f=new Float32Array(12),m=new g,v=0,y=0,b=0,x=a.nx,_=a.ny,w=a.nz;"x"===this.dimension?(l=e(a.nx),p=a.ny-1,d=a.nz-1,u=a.nz,h=a.ny,x=(v=l)+1,r(l,0,0,0),r(l,p,0,3),r(l,0,d,6),r(l,p,d,9)):"y"===this.dimension?(l=a.nx-1,p=e(a.ny),d=a.nz-1,u=a.nz,h=a.nx,_=(y=p)+1,r(0,p,0,0),r(l,p,0,3),r(0,p,d,6),r(l,p,d,9)):"z"===this.dimension&&(l=a.nx-1,p=a.ny-1,d=e(a.nz),u=a.nx,h=a.ny,w=(b=d)+1,r(0,0,d,0),r(0,p,d,3),r(l,0,d,6),r(l,p,d,9));var S,A,M=0,P=0,T=new Uint8Array(u*h*4),E=new Float32Array(u*h);"sigma"===this.thresholdType?(S=a.getValueForSigma(this.thresholdMin),A=a.getValueForSigma(this.thresholdMax)):(S=this.thresholdMin,A=this.thresholdMax);var C=Object.assign({},t.colorParams,{volume:a});this.normalize&&(C.domain=[0,1]);var I,L,R,O=lf.getScheme(C),D=new Float32Array(3),N=O.getScale();if(this.normalize){I=1/0,L=-1/0;for(var k=y;k<_;++k)for(var B=v;B<x;++B)for(var F=b;F<w;++F){var z=s[i(B,k,F,0)/3];z<I&&(I=z),z>L&&(L=z)}R=L-I}for(var U=y;U<_;++U)for(var j=v;j<x;++j)for(var G=b;G<w;++G){var V=i(j,U,G,0)/3,$=s[V];n.normalize&&($=($-I)/R),O.colorToArray(N($),D),T[M]=Math.round(255*D[0]),T[M+1]=Math.round(255*D[1]),T[M+2]=Math.round(255*D[2]),T[M+3]=$>S&&$<A?255:0,E[P]=V,++P,M+=4}var H=new ng(E,a);return{position:f,imageData:T,width:u,height:h,picking:H}};var Ny=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="slice",this.parameters=Object.assign({filter:{type:"select",buffer:!0,options:{nearest:"nearest",linear:"linear","cubic-bspline":"cubic-bspline","cubic-catmulrom":"cubic-catmulrom","cubic-mitchell":"cubic-mitchell"}},positionType:{type:"select",rebuild:!0,options:{percent:"percent",coordinate:"coordinate"}},position:{type:"range",step:.1,max:100,min:1,rebuild:!0},dimension:{type:"select",rebuild:!0,options:{x:"x",y:"y",z:"z"}},thresholdType:{type:"select",rebuild:!0,options:{value:"value",sigma:"sigma"}},thresholdMin:{type:"number",precision:3,max:1/0,min:-1/0,rebuild:!0},thresholdMax:{type:"number",precision:3,max:1/0,min:-1/0,rebuild:!0},normalize:{type:"boolean",rebuild:!0}},this.parameters,{flatShaded:null,side:null,wireframe:null,linewidth:null,colorScheme:null,roughness:null,metalness:null,diffuse:null}),this.volume=e,this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=this.volume,r=e||{};r.colorDomain=dn(r.colorDomain,[i.min,i.max]),r.colorScheme=dn(r.colorScheme,"value"),r.colorScale=dn(r.colorScale,"Spectral"),this.colorScheme="value",this.dimension=dn(r.dimension,"x"),this.filter=dn(r.filter,"cubic-bspline"),this.positionType=dn(r.positionType,"percent"),this.position=dn(r.position,30),this.thresholdType=dn(r.thresholdType,"sigma"),this.thresholdMin=dn(r.thresholdMin,-1/0),this.thresholdMax=dn(r.thresholdMax,1/0),this.normalize=dn(r.normalize,!1),t.prototype.init.call(this,r),this.build()},e.prototype.attach=function(t){var e=this;this.bufferList.forEach(function(t){e.viewer.add(t)}),this.setVisibility(this.visible),t()},e.prototype.create=function(){var t=new Dy(this.volume,{positionType:this.positionType,position:this.position,dimension:this.dimension,thresholdType:this.thresholdType,thresholdMin:this.thresholdMin,thresholdMax:this.thresholdMax,normalize:this.normalize}),e=new Oy(t.getData({colorParams:this.getColorParams()}),this.getBufferParams({filter:this.filter}));this.bufferList.push(e)},e}(wy),ky=function(t){function e(e,i,r){var n=r||{};if(t.call(this,e,i,n),this.type="structure",this.parameters=Object.assign({radiusType:{type:"select",options:ga.types},radius:{type:"number",precision:3,max:10,min:.001},scale:{type:"number",precision:3,max:10,min:.001},assembly:null,defaultAssembly:{type:"hidden"}},this.parameters),this.selection=new Kd(n.sele),this.dataList=[],this.structure=e,this.structureView=this.structure.getView(this.selection),e.biomolDict){var o={default:"default","":e.unitcell?"AU":"FULL"};Object.keys(e.biomolDict).forEach(function(t){o[t]=t}),this.parameters.assembly={type:"select",options:o,rebuild:!0}}else this.parameters.assembly=null}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={defaultScale:{}};return i.defaultScale.get=function(){return{vdw:1,covalent:1,bfactor:.01,sstruc:1}},e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"element"),this.radius=dn(i.radius,"vdw"),this.scale=dn(i.scale,1),this.assembly=dn(i.assembly,"default"),this.defaultAssembly=dn(i.defaultAssembly,""),"auto"===i.quality&&(i.quality=this.getQuality()),t.prototype.init.call(this,i),this.selection.signals.stringChanged.add(function(){this.build()},this),this.build()},e.prototype.getAssembly=function(){var t="default"===this.assembly?this.defaultAssembly:this.assembly;return this.structure.biomolDict[t]},e.prototype.getQuality=function(){var t,e=this.structureView,i=this.getAssembly();return t=i?i.getAtomCount(e):e.atomCount,of&&(t*=4),e.atomStore.count/e.residueStore.count<2&&(t*=10),t<15e3?"high":t<8e4?"medium":"low"},e.prototype.create=function(){if(0!==this.structureView.atomCount){var t=this.getAssembly();if(t)t.partList.forEach(function(t,e){var i=t.getView(this.structureView);if(0!==i.atomCount){var r=this.createData(i,e);r&&(r.sview=i,r.instanceList=t.getInstanceList(),this.dataList.push(r))}},this);else{var e=this.createData(this.structureView,0);e&&(e.sview=this.structureView,this.dataList.push(e))}}},e.prototype.createData=function(){console.error("createData not implemented")},e.prototype.update=function(t){if(this.lazy&&!this.visible)return void Object.assign(this.lazyProps.what,t);this.dataList.forEach(function(e){e.bufferList.length>0&&this.updateData(t,e)},this)},e.prototype.updateData=function(){this.build()},e.prototype.getColorParams=function(){var e=t.prototype.getColorParams.call(this);return e.structure=this.structure,e},e.prototype.getAtomParams=function(t,e){return Object.assign({what:t,colorParams:this.getColorParams(),radiusParams:{radius:this.radius,scale:this.scale}},e)},e.prototype.getBondParams=function(t,e){return Object.assign({what:t,colorParams:this.getColorParams(),radiusParams:{radius:this.radius,scale:this.scale}},e)},e.prototype.setSelection=function(t,e){return this.selection.setString(t,e),this},e.prototype.setParameters=function(e,i,r){return i=i||{},e&&void 0!==e.radiusType&&("size"===e.radiusType?this.radius=1:this.radius=e.radiusType,delete e.radiusType,i.radius=!0,sf&&!this.disableImpostor||(r=!0)),e&&void 0!==e.radius&&(i.radius=!0,sf&&!this.disableImpostor||(r=!0)),e&&void 0!==e.scale&&(i.radius=!0,sf&&!this.disableImpostor||(r=!0)),e&&void 0!==e.defaultAssembly&&(r=!0),t.prototype.setParameters.call(this,e,i,r),this},e.prototype.getParameters=function(){return Object.assign(t.prototype.getParameters.call(this),{sele:this.selection?this.selection.string:void 0,defaultAssembly:this.defaultAssembly})},e.prototype.attach=function(t){var e=this.viewer,i=this.bufferList;this.dataList.forEach(function(t){t.bufferList.forEach(function(r){i.push(r),e.add(r,t.instanceList)})}),this.setVisibility(this.visible),t()},e.prototype.clear=function(){this.dataList.length=0,t.prototype.clear.call(this)},e.prototype.dispose=function(){this.structureView.dispose(),delete this.structure,delete this.structureView,t.prototype.dispose.call(this)},Object.defineProperties(e.prototype,i),e}(wy),By=function(t){function e(e,i){var r=4*(e.position1.length/3);t.call(this,{position:new Float32Array(3*r),color:new Float32Array(3*r)},i),this.setAttributes(e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={isLine:{},vertexShader:{},fragmentShader:{}};return e.prototype.setAttributes=function(t){var e,i,r,n,o,a,s=this.geometry.attributes;t.position1&&t.position2&&(e=t.position1,i=t.position2,o=s.position.array,s.position.needsUpdate=!0),t.color&&t.color2&&(r=t.color,n=t.color2,a=s.color.array,s.color.needsUpdate=!0);for(var c,u,h,l,p,d,f,m,g,v,y,b=this.size,x=0;x<b;x++)u=3*x,c=4*x*3,e&&i&&(d=e[u],f=e[u+1],m=e[u+2],h=(d+(g=i[u]))/2,l=(f+(v=i[u+1]))/2,p=(m+(y=i[u+2]))/2,o[c]=d,o[c+1]=f,o[c+2]=m,o[c+3]=h,o[c+4]=l,o[c+5]=p,o[c+6]=h,o[c+7]=l,o[c+8]=p,o[c+9]=g,o[c+10]=v,o[c+11]=y),r&&n&&(a[c]=a[c+3]=r[u],a[c+1]=a[c+4]=r[u+1],a[c+2]=a[c+5]=r[u+2],a[c+6]=a[c+9]=n[u],a[c+7]=a[c+10]=n[u+1],a[c+8]=a[c+11]=n[u+2])},i.isLine.get=function(){return!0},i.vertexShader.get=function(){return"Line.vert"},i.fragmentShader.get=function(){return"Line.frag"},Object.defineProperties(e.prototype,i),e}(Lv),Fy=function(t){function e(e,i,r){t.call(this,e.structure,i,r),this.type="trajectory",this.parameters=Object.assign({drawLine:{type:"boolean",rebuild:!0},drawCylinder:{type:"boolean",rebuild:!0},drawPoint:{type:"boolean",rebuild:!0},drawSphere:{type:"boolean",rebuild:!0},linewidth:{type:"integer",max:20,min:1,rebuild:!0},pointSize:{type:"integer",max:20,min:1,rebuild:!0},sizeAttenuation:{type:"boolean",rebuild:!0},sort:{type:"boolean",rebuild:!0}},this.parameters),this.manualAttach=!0,this.trajectory=e,this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"uniform"),i.colorValue=dn(i.colorValue,14540253),this.drawLine=dn(i.drawLine,!0),this.drawCylinder=dn(i.drawCylinder,!1),this.drawPoint=dn(i.drawPoint,!1),this.drawSphere=dn(i.drawSphere,!1),this.pointSize=dn(i.pointSize,1),this.sizeAttenuation=dn(i.sizeAttenuation,!1),this.sort=dn(i.sort,!0),t.prototype.init.call(this,i)},e.prototype.attach=function(t){var e=this;this.bufferList.forEach(function(t){e.viewer.add(t)}),this.setVisibility(this.visible),t()},e.prototype.prepare=function(t){t()},e.prototype.create=function(){if(0!==this.atomSet.atomCount){var t=this,e=this.atomSet.atoms[0].index;this.trajectory.getPath(e,function(e){var i=e.length/3,r=new tt(t.colorValue);if(t.drawSphere){var n=new $v({position:e,color:To(i,r.r,r.g,r.b),radius:Po(i,.2)},t.getBufferParams({sphereDetail:t.sphereDetail,dullInterior:!0,disableImpostor:t.disableImpostor}));t.bufferList.push(n)}if(t.drawCylinder){var o=new oy({position1:e.subarray(0,-3),position2:e.subarray(3),color:To(i-1,r.r,r.g,r.b),color2:To(i-1,r.r,r.g,r.b),radius:Po(i,.05)},t.getBufferParams({openEnded:!1,radialSegments:t.radialSegments,disableImpostor:t.disableImpostor,dullInterior:!0}));t.bufferList.push(o)}if(t.drawPoint){var a=new Cy({position:e,color:To(i,r.r,r.g,r.b)},t.getBufferParams({pointSize:t.pointSize,sizeAttenuation:t.sizeAttenuation,sort:t.sort}));t.bufferList.push(a)}if(t.drawLine){var s=new By({position1:e.subarray(0,-3),position2:e.subarray(3),color:To(i-1,r.r,r.g,r.b),color2:To(i-1,r.r,r.g,r.b)},t.getBufferParams());t.bufferList.push(s)}t.attach()})}},e}(ky),zy=0,Uy=new v,jy=new g,Gy=function(t,e){Object.defineProperty(this,"id",{value:zy++});var i=e||{};this.name=i.name,this.uuid=$n(),this.visible=void 0===i.visible||i.visible,this.signals={representationAdded:new io,representationRemoved:new io,visibilityChanged:new io,matrixChanged:new io,statusChanged:new io,nameChanged:new io,disposed:new io},this.stage=t,this.viewer=t.viewer,this.reprList=[],this.annotationList=[],this.matrix=new v,this.position=new g,this.quaternion=new m,this.scale=new g(1,1,1),this.transform=new v,this.controls=new Fm(this)},Vy={type:{}};Vy.type.get=function(){return"component"},Gy.prototype.setPosition=function(t){return Array.isArray(t)?this.position.fromArray(t):this.position.copy(t),this.updateMatrix(),this},Gy.prototype.setRotation=function(t){if(Array.isArray(t))if(3===t.length){var e=(new ft).fromArray(t);this.quaternion.setFromEuler(e)}else this.quaternion.fromArray(t);else t instanceof ft?this.quaternion.setFromEuler(t):this.quaternion.copy(t);return this.updateMatrix(),this},Gy.prototype.setScale=function(t){return this.scale.set(t,t,t),this.updateMatrix(),this},Gy.prototype.setTransform=function(t){return this.transform.copy(t),this.updateMatrix(),this},Gy.prototype.updateMatrix=function(){var t=this,e=this.getCenterUntransformed(jy);this.matrix.makeTranslation(-e.x,-e.y,-e.z),Uy.makeRotationFromQuaternion(this.quaternion),this.matrix.premultiply(Uy),Uy.makeScale(this.scale.x,this.scale.y,this.scale.z),this.matrix.premultiply(Uy);var i=this.position;Uy.makeTranslation(i.x+e.x,i.y+e.y,i.z+e.z),this.matrix.premultiply(Uy),this.matrix.premultiply(this.transform),this.reprList.forEach(function(e){e.setParameters({matrix:t.matrix})}),this.stage.viewer.updateBoundingBox(),this.signals.matrixChanged.dispatch(this.matrix)},Gy.prototype.addAnnotation=function(t,e,i){var r=new Dm(this,t,e,i);return this.annotationList.push(r),r},Gy.prototype.removeAnnotation=function(t){var e=this.annotationList.indexOf(t);-1!==e&&(this.annotationList.splice(e,1),t.dispose())},Gy.prototype.removeAllAnnotations=function(){this.annotationList.forEach(function(t){t.dispose()}),this.annotationList.length=0},Gy.prototype.addRepresentation=function(t,e,i){var r=i||{},n=this.stage.getParameters();r.matrix=this.matrix.clone(),r.quality=r.quality||n.quality,r.disableImpostor=dn(r.disableImpostor,!n.impostor),r.useWorker=dn(r.useWorker,n.workerDefault),r.visible=dn(r.visible,!0);var o=Object.assign({},r,{visible:this.visible&&r.visible}),a=Ts(t,e,this.viewer,o),s=this.__getRepresentationComponent(a,r);return this.reprList.push(s),this.signals.representationAdded.dispatch(s),s},Gy.prototype.addBufferRepresentation=function(t,e){return Gy.prototype.addRepresentation.call(this,"buffer",t,e)},Gy.prototype.hasRepresentation=function(t){return-1!==this.reprList.indexOf(t)},Gy.prototype.removeRepresentation=function(t){var e=this.reprList.indexOf(t);-1!==e&&(this.reprList.splice(e,1),t.dispose(),this.signals.representationRemoved.dispatch(t))},Gy.prototype.updateRepresentations=function(t){this.reprList.forEach(function(e){e.update(t)}),this.stage.viewer.requestRender()},Gy.prototype.removeAllRepresentations=function(){var t=this;this.reprList.forEach(function(e){e.dispose(),t.signals.representationRemoved.dispatch(e)}),this.reprList.length=0},Gy.prototype.dispose=function(){this.removeAllAnnotations(),this.removeAllRepresentations(),delete this.annotationList,delete this.reprList,this.signals.disposed.dispatch()},Gy.prototype.setVisibility=function(t){return this.visible=t,this.eachRepresentation(function(t){t.updateVisibility()}),this.annotationList.forEach(function(t){t.updateVisibility()}),this.signals.visibilityChanged.dispatch(t),this},Gy.prototype.setStatus=function(t){return this.status=t,this.signals.statusChanged.dispatch(t),this},Gy.prototype.setName=function(t){return this.name=t,this.signals.nameChanged.dispatch(t),this},Gy.prototype.getBox=function(){return(t=this).getBoxUntransformed.apply(t,arguments).clone().applyMatrix4(this.matrix);var t},Gy.prototype.getCenter=function(){return(t=this).getCenterUntransformed.apply(t,arguments).clone().applyMatrix4(this.matrix);var t},Gy.prototype.getZoom=function(){return this.stage.getZoomForBox((t=this).getBox.apply(t,arguments));var t},Gy.prototype.getBoxUntransformed=function(){},Gy.prototype.getCenterUntransformed=function(){return this.getBoxUntransformed().getCenter()},Gy.prototype.autoView=function(t){this.stage.animationControls.zoomMove(this.getCenter(),this.getZoom(),dn(t,0))},Gy.prototype.eachRepresentation=function(t){this.reprList.forEach(t)},Object.defineProperties(Gy.prototype,Vy),Gy.prototype.__getRepresentationComponent=function(t,e){return new $y(this.stage,t,e,this)};var $y=function(t){function e(e,i,r,n){var o=r||{};o.name=dn(o.name,i.type),t.call(this,e,o),this.signals=Object.assign(this.signals,{parametersChanged:new io}),this.parent=n,this.setRepresentation(i)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"representation"},e.prototype.getType=function(){return this.repr.type},e.prototype.setRepresentation=function(t){this.disposeRepresentation(),this.repr=t,this.stage.tasks.listen(this.repr.tasks),this.updateVisibility()},e.prototype.addRepresentation=function(){},e.prototype.removeRepresentation=function(){},e.prototype.hasRepresentation=function(){},e.prototype.disposeRepresentation=function(){this.repr&&(this.stage.tasks.unlisten(this.repr.tasks),this.repr.dispose())},e.prototype.dispose=function(){this.parent&&this.parent.hasRepresentation(this)?this.parent.removeRepresentation(this):(this.disposeRepresentation(),this.signals.disposed.dispatch())},e.prototype.setVisibility=function(t){return this.visible=t,this.updateVisibility(),this.signals.visibilityChanged.dispatch(this.visible),this},e.prototype.getVisibility=function(){return this.parent?this.parent.visible&&this.visible:this.visible},e.prototype.toggleVisibility=function(){return this.setVisibility(!this.visible)},e.prototype.updateVisibility=function(){this.repr.setVisibility(this.getVisibility())},e.prototype.update=function(t){return this.repr.update(t),this},e.prototype.build=function(t){return this.repr.build(t),this},e.prototype.setSelection=function(t){return this.repr.setSelection(t),this},e.prototype.setParameters=function(t){return this.repr.setParameters(t),this.signals.parametersChanged.dispatch(this.repr.getParameters()),this},e.prototype.getParameters=function(){return this.repr.getParameters()},e.prototype.setColor=function(t){return this.repr.setColor(t),this},e.prototype.getCenter=function(){},e.prototype.getZoom=function(){},e.prototype.getBox=function(){},Object.defineProperties(e.prototype,i),e}(Gy),Hy=function(t){var e=this;this.list=t||[];for(var i=this.list.length,r=0;r<i;++r)e.list[r].signals.disposed.add(e._remove,e)};Hy.prototype._remove=function(t){var e=this.list.indexOf(t);-1!==e&&this.list.splice(e,1)},Hy.prototype._invoke=function(t,e){for(var i=this,r=this.list.length,n=0;n<r;++n){var o=i.list[n],a=o[t];"function"==typeof a&&a.apply(o,e)}return this},Hy.prototype.setVisibility=function(t){return this._invoke("setVisibility",[t])},Hy.prototype.setSelection=function(t){return this._invoke("setSelection",[t])},Hy.prototype.dispose=function(){return this._invoke("dispose")};var Wy=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.addRepresentation=function(t,e){return this._invoke("addRepresentation",[t,e])},e.prototype.autoView=function(t){return this._invoke("autoView",[t])},e}(Hy),Xy=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setParameters=function(t){return this._invoke("setParameters",[t])},e.prototype.setColor=function(t){return this._invoke("setColor",[t])},e}(Hy),qy=new g,Yy=function(t,e){if(this.signals={parametersChanged:new io,fullscreenChanged:new io,componentAdded:new io,componentRemoved:new io,clicked:new io,hovered:new io},this.tasks=new Cf,this.compList=[],this.defaultFileParams={},this.viewer=new Ho(t),this.viewer.renderer){this.tooltip=document.createElement("div"),Object.assign(this.tooltip.style,{display:"none",position:"fixed",zIndex:2+(parseInt(this.viewer.container.style.zIndex)||0),pointerEvents:"none",backgroundColor:"rgba( 0, 0, 0, 0.6 )",color:"lightgrey",padding:"8px",fontFamily:"sans-serif"}),document.body.appendChild(this.tooltip),this.mouseObserver=new Xf(this.viewer.renderer.domElement),this.viewerControls=new mm(this),this.trackballControls=new im(this),this.pickingControls=new am(this),this.animationControls=new Tm(this),this.mouseControls=new Im(this),this.pickingBehavior=new Lm(this),this.mouseBehavior=new Rm(this),this.animationBehavior=new Om(this),this.spinAnimation=this.animationControls.spin(null),this.rockAnimation=this.animationControls.rock(null);var i=Object.assign({impostor:!0,quality:"medium",workerDefault:!0,sampleLevel:0,backgroundColor:"black",rotateSpeed:2,zoomSpeed:1.2,panSpeed:1,clipNear:0,clipFar:100,clipDist:10,fogNear:50,fogFar:100,cameraFov:40,cameraType:"perspective",lightColor:14540253,lightIntensity:1,ambientColor:14540253,ambientIntensity:.2,hoverTimeout:0,tooltip:!0,mousePreset:"default"},e);this.parameters={backgroundColor:{type:"color"},quality:{type:"select",options:{auto:"auto",low:"low",medium:"medium",high:"high"}},sampleLevel:{type:"range",step:1,max:5,min:-1},impostor:{type:"boolean"},workerDefault:{type:"boolean"},rotateSpeed:{type:"number",precision:1,max:10,min:0},zoomSpeed:{type:"number",precision:1,max:10,min:0},panSpeed:{type:"number",precision:1,max:10,min:0},clipNear:{type:"range",step:1,max:100,min:0},clipFar:{type:"range",step:1,max:100,min:0},clipDist:{type:"integer",max:200,min:0},fogNear:{type:"range",step:1,max:100,min:0},fogFar:{type:"range",step:1,max:100,min:0},cameraType:{type:"select",options:{perspective:"perspective",orthographic:"orthographic"}},cameraFov:{type:"range",step:1,max:120,min:15},lightColor:{type:"color"},lightIntensity:{type:"number",precision:2,max:10,min:0},ambientColor:{type:"color"},ambientIntensity:{type:"number",precision:2,max:10,min:0},hoverTimeout:{type:"integer",max:1e4,min:-1},tooltip:{type:"boolean"},mousePreset:{type:"select",options:{default:"default",pymol:"pymol",coot:"coot"}}},this.setParameters(i),this.viewer.animate()}};Yy.prototype.setParameters=function(t){var e=Object.assign({},t),i=this.parameters,r=this.viewer,n=this.trackballControls;for(var o in e)void 0!==e[o]&&i[o]&&(i[o].int&&(e[o]=parseInt(e[o])),i[o].float&&(e[o]=parseFloat(e[o])),i[o].value=e[o]);return void 0!==e.quality&&this.setQuality(e.quality),void 0!==e.impostor&&this.setImpostor(e.impostor),void 0!==e.rotateSpeed&&(n.rotateSpeed=e.rotateSpeed),void 0!==e.zoomSpeed&&(n.zoomSpeed=e.zoomSpeed),void 0!==e.panSpeed&&(n.panSpeed=e.panSpeed),void 0!==e.mousePreset&&this.mouseControls.preset(e.mousePreset),this.mouseObserver.setParameters({hoverTimeout:e.hoverTimeout}),r.setClip(e.clipNear,e.clipFar,e.clipDist),r.setFog(void 0,e.fogNear,e.fogFar),r.setCamera(e.cameraType,e.cameraFov),r.setSampling(e.sampleLevel),r.setBackground(e.backgroundColor),r.setLight(e.lightColor,e.lightIntensity,e.ambientColor,e.ambientIntensity),this.signals.parametersChanged.dispatch(this.getParameters()),this},Yy.prototype.getParameters=function(){var t=this,e={};for(var i in t.parameters)e[i]=t.parameters[i].value;return e},Yy.prototype.defaultFileRepresentation=function(e){if("structure"===e.type){e.setSelection("/0");var i,r,n,o=e.structure;if(o.biomolDict.BU1){var a=o.biomolDict.BU1;i=a.getAtomCount(o),r=a.getResidueCount(o),n=a.getInstanceCount(),e.setDefaultAssembly("BU1")}else i=o.getModelProxy(0).atomCount,r=o.getModelProxy(0).residueCount,n=1;of&&(i*=4);var s=o.atomStore.count/o.residueStore.count<2;s&&(i*=10);var c="chainname",u="RdYlBu",h=!1;if(1===o.getChainnameCount("polymer and /0")&&(c="residueindex",u="spectral",h=!0),t.Debug&&console.log(i,n,s),r/n<4)e.addRepresentation("ball+stick",{colorScheme:"element",scale:2,aspectRatio:1.5,bondScale:.3,bondSpacing:.75,quality:"auto"});else if(n>5&&i>15e3||i>7e5){var l=Math.min(1.5,Math.max(.1,2e3/(i/n)));s&&(l=Math.min(l,.15)),e.addRepresentation("surface",{sele:"polymer",surfaceType:"sas",probeRadius:1.4,scaleFactor:l,colorScheme:c,colorScale:u,colorReverse:h,useWorker:!1})}else i>25e4?e.addRepresentation("backbone",{lineOnly:!0,colorScheme:c,colorScale:u,colorReverse:h}):i>1e5?e.addRepresentation("backbone",{quality:"low",disableImpostor:!0,colorScheme:c,colorScale:u,colorReverse:h,scale:2}):i>8e4?e.addRepresentation("backbone",{colorScheme:c,colorScale:u,colorReverse:h,scale:2}):(e.addRepresentation("cartoon",{colorScheme:c,colorScale:u,colorReverse:h,scale:.7,aspectRatio:5,quality:"auto"}),i<5e4&&e.addRepresentation("base",{colorScheme:c,colorScale:u,colorReverse:h,quality:"auto"}),e.addRepresentation("ball+stick",{sele:"ligand",colorScheme:"element",scale:2,aspectRatio:1.5,bondScale:.3,bondSpacing:.75,quality:"auto"}));e.structure.frames.length&&e.addTrajectory()}else"surface"!==e.type&&"volume"!==e.type||e.addRepresentation("surface");this.tasks.onZeroOnce(this.autoView,this)},Yy.prototype.loadFile=function(t,e){var i=Object.assign({},this.defaultFileParams,e),r=new Gy(this,i);r.name=yn(t).name,this.addComponent(r);var n=this.tasks;n.increment();var o=function(t){return this.removeComponent(r),r=this.addComponentFromObject(t,i),"script"===r.type?r.run():i.defaultRepresentation&&this.defaultFileRepresentation(r),n.decrement(),r}.bind(this),a=function(t){throw r.setStatus(t),n.decrement(),t};return("dcd"===dn(i.ext,yn(t).ext)?Promise.reject("loadFile: ext 'dcd' must be loaded into a structure component"):mo(t,i)).then(o,a)},Yy.prototype.addComponent=function(t){if(!t)return void cf.warn("Stage.addComponent: no component given");this.compList.push(t),this.signals.componentAdded.dispatch(t)},Yy.prototype.addComponentFromObject=function(t,e){var i=vf.get(t.type);if(i){var r=new i(this,t,e);return this.addComponent(r),r}cf.warn("no component for object type",t.type)},Yy.prototype.removeComponent=function(t){var e=this.compList.indexOf(t);-1!==e&&(this.compList.splice(e,1),t.dispose(),this.signals.componentRemoved.dispatch(t))},Yy.prototype.removeAllComponents=function(t){this.compList.slice().forEach(function(e){t&&e.type!==t||this.removeComponent(e)},this)},Yy.prototype.handleResize=function(){this.viewer.handleResize()},Yy.prototype.setSize=function(t,e){var i=this.viewer.container;i!==document.body&&(void 0!==t&&(i.style.width=t),void 0!==e&&(i.style.height=e),this.handleResize())},Yy.prototype.toggleFullscreen=function(t){function e(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement}function i(){if(!e()&&r.lastFullscreenElement){var t=r.lastFullscreenElement;t.style.width=t.dataset.normalWidth,t.style.height=t.dataset.normalHeight,document.removeEventListener("fullscreenchange",i),document.removeEventListener("mozfullscreenchange",i),document.removeEventListener("webkitfullscreenchange",i),document.removeEventListener("MSFullscreenChange",i),r.handleResize(),r.signals.fullscreenChanged.dispatch(!1)}}if(!(document.fullscreenEnabled||document.mozFullScreenEnabled||document.webkitFullscreenEnabled||document.msFullscreenEnabled))return void cf.log("fullscreen mode (currently) not possible");var r=this;t=t||this.viewer.container,this.lastFullscreenElement=t,e()?document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen():(t.dataset.normalWidth=t.style.width,t.dataset.normalHeight=t.style.height,t.style.width=screen.width+"px",t.style.height=screen.height+"px",t.requestFullscreen?t.requestFullscreen():t.msRequestFullscreen?t.msRequestFullscreen():t.mozRequestFullScreen?t.mozRequestFullScreen():t.webkitRequestFullscreen&&t.webkitRequestFullscreen(),document.addEventListener("fullscreenchange",i),document.addEventListener("mozfullscreenchange",i),document.addEventListener("webkitfullscreenchange",i),document.addEventListener("MSFullscreenChange",i),this.handleResize(),this.signals.fullscreenChanged.dispatch(!0),setTimeout(function(){r.handleResize()},100))},Yy.prototype.setFocus=function(t){var e=Xn(t/2,0,49.9),i=100-e,r=(i-e)/2;this.setParameters({clipNear:e,clipFar:i,fogNear:qn(i-r),fogFar:qn(i+r)})},Yy.prototype.setSpin=function(t,e){this.rockAnimation.axis&&this.setRock(null),Array.isArray(t)&&(t=(new g).fromArray(t)),void 0!==t&&(this.spinAnimation.axis=t),void 0!==e&&(this.spinAnimation.angle=e)},Yy.prototype.setRock=function(t,e,i){this.spinAnimation.axis&&this.setSpin(null),Array.isArray(t)&&(t=(new g).fromArray(t)),void 0!==t&&(this.rockAnimation.axis=t),void 0!==e&&(this.rockAnimation.angleStep=e),void 0!==i&&(this.rockAnimation.angleEnd=i),this.rockAnimation.angleSum=0,this.rockAnimation.direction=1},Yy.prototype.getZoomForBox=function(t){var e=t.getSize(qy),i=Math.max(e.x,e.y,e.z),r=Math.min(e.x,e.y,e.z),n=i+Math.sqrt(r),o=Gn(this.viewer.perspectiveCamera.fov),a=this.viewer.width,s=this.viewer.height,c=a/s,u=s<a?1:c;return n=Math.abs(.5*n/u/Math.sin(o/2)),-(n+=this.parameters.clipDist.value)},Yy.prototype.getBox=function(){return this.viewer.boundingBox},Yy.prototype.getZoom=function(){return this.getZoomForBox(this.getBox())},Yy.prototype.getCenter=function(t){return this.getBox().getCenter(t)},Yy.prototype.autoView=function(t){this.animationControls.zoomMove(this.getCenter(),this.getZoom(),dn(t,0))},Yy.prototype.makeImage=function(t){var e=this.viewer,i=this.tasks;return new Promise(function(r,n){function o(){i.increment(),e.makeImage(t).then(function(t){i.decrement(),r(t)}).catch(function(t){i.decrement(),n(t)})}i.onZeroOnce(o)})},Yy.prototype.setImpostor=function(t){this.parameters.impostor.value=t;var e=["spacefill","ball+stick","licorice","hyperball","backbone","rocket","helixorient","contact","distance","dot"];this.eachRepresentation(function(i){if("script"!==i.type&&e.includes(i.getType())){var r=i.getParameters();r.disableImpostor=!t,i.build(r)}})},Yy.prototype.setQuality=function(t){this.parameters.quality.value=t;var e=["tube","cartoon","ribbon","trace","rope"],i=["spacefill","ball+stick","licorice","hyperball","backbone","rocket","helixorient","contact","distance","dot"];this.eachRepresentation(function(r){if("script"!==r.type){var n=r.getParameters();if(!e.includes(r.getType())){if(!i.includes(r.getType()))return;if(!n.disableImpostor)return void(r.repr.quality=t)}n.quality=t,r.build(n)}})},Yy.prototype.eachComponent=function(t,e){this.compList.slice().forEach(function(i,r){e&&i.type!==e||t(i,r)})},Yy.prototype.eachRepresentation=function(t,e){this.eachComponent(function(e){e.reprList.slice().forEach(function(i){t(i,e)})},e)},Yy.prototype.getComponentsByName=function(t,e){var i=[];return this.eachComponent(function(e){(void 0===t||Es(t,e))&&i.push(e)},e),new Wy(i)},Yy.prototype.getComponentsByObject=function(t){var e=[];return this.eachComponent(function(i){i[i.type]===t&&e.push(i)}),new Wy(e)},Yy.prototype.getRepresentationsByName=function(t,e){var i,r;"object"!=typeof t||t instanceof RegExp?(i=void 0,r=t):(i=t.comp,r=t.repr);var n=[];return this.eachRepresentation(function(t,e){(void 0===i||Es(i,e))&&(void 0===r||Es(r,t))&&n.push(t)},e),new Xy(n)},Yy.prototype.getAnythingByName=function(t){var e=this.getComponentsByName(t).list,i=this.getRepresentationsByName(t).list;return new Hy(e.concat(i))},Yy.prototype.dispose=function(){this.tasks.dispose()};var Zy=[[4,0,-2,-1,-2,0,-2,-1,-1,-1,-1,-2,-1,-1,-1,1,0,0,-3,-2],[0,9,-3,-4,-2,-3,-3,-1,-3,-1,-1,-3,-3,-3,-3,-1,-1,-1,-2,-2],[-2,-3,6,2,-3,-1,-1,-3,-1,-4,-3,1,-1,0,-2,0,-1,-3,-4,-3],[-1,-4,2,5,-3,-2,0,-3,1,-3,-2,0,-1,2,0,0,-1,-2,-3,-2],[-2,-2,-3,-3,6,-3,-1,0,-3,0,0,-3,-4,-3,-3,-2,-2,-1,1,3],[0,-3,-1,-2,-3,6,-2,-4,-2,-4,-3,0,-2,-2,-2,0,-2,-3,-2,-3],[-2,-3,-1,0,-1,-2,8,-3,-1,-3,-2,1,-2,0,0,-1,-2,-3,-2,2],[-1,-1,-3,-3,0,-4,-3,4,-3,2,1,-3,-3,-3,-3,-2,-1,3,-3,-1],[-1,-3,-1,1,-3,-2,-1,-3,5,-2,-1,0,-1,1,2,0,-1,-2,-3,-2],[-1,-1,-4,-3,0,-4,-3,2,-2,4,2,-3,-3,-2,-2,-2,-1,1,-2,-1],[-1,-1,-3,-2,0,-3,-2,1,-1,2,5,-2,-2,0,-1,-1,-1,1,-1,-1],[-2,-3,1,0,-3,0,1,-3,0,-3,-2,6,-2,0,0,1,0,-3,-4,-2],[-1,-3,-1,-1,-4,-2,-2,-3,-1,-3,-2,-2,7,-1,-2,-1,-1,-2,-4,-3],[-1,-3,0,2,-3,-2,0,-3,1,-2,0,0,-1,5,1,0,-1,-2,-2,-1],[-1,-3,-2,0,-3,-2,0,-3,2,-2,-1,0,-2,1,5,-1,-1,-3,-3,-2],[1,-1,0,0,-2,0,-1,-2,0,-2,-1,1,-1,0,-1,4,1,-2,-3,-2],[0,-1,-1,-1,-2,-2,-2,-1,-1,-1,-1,0,-1,-1,-1,1,5,0,-2,-2],[0,-1,-3,-2,-1,-3,-3,3,-2,1,1,-3,-2,-2,-3,-2,0,4,-3,-1],[-3,-2,-4,-3,1,-2,-2,-3,-3,-2,-1,-4,-4,-2,-3,-3,-2,-3,11,2],[-2,-2,-3,-2,3,-3,2,-1,-2,-1,-1,-2,-3,-1,-2,-2,-2,-1,2,7]],Ky=[[4,-1,-2,-2,0,-1,-1,0,-2,-1,-1,-1,-1,-2,-1,1,0,-3,-2,0,-2,-1,0],[-1,5,0,-2,-3,1,0,-2,0,-3,-2,2,-1,-3,-2,-1,-1,-3,-2,-3,-1,0,-1],[-2,0,6,1,-3,0,0,0,1,-3,-3,0,-2,-3,-2,1,0,-4,-2,-3,3,0,-1],[-2,-2,1,6,-3,0,2,-1,-1,-3,-4,-1,-3,-3,-1,0,-1,-4,-3,-3,4,1,-1],[0,-3,-3,-3,9,-3,-4,-3,-3,-1,-1,-3,-1,-2,-3,-1,-1,-2,-2,-1,-3,-3,-2],[-1,1,0,0,-3,5,2,-2,0,-3,-2,1,0,-3,-1,0,-1,-2,-1,-2,0,3,-1],[-1,0,0,2,-4,2,5,-2,0,-3,-3,1,-2,-3,-1,0,-1,-3,-2,-2,1,4,-1],[0,-2,0,-1,-3,-2,-2,6,-2,-4,-4,-2,-3,-3,-2,0,-2,-2,-3,-3,-1,-2,-1],[-2,0,1,-1,-3,0,0,-2,8,-3,-3,-1,-2,-1,-2,-1,-2,-2,2,-3,0,0,-1],[-1,-3,-3,-3,-1,-3,-3,-4,-3,4,2,-3,1,0,-3,-2,-1,-3,-1,3,-3,-3,-1],[-1,-2,-3,-4,-1,-2,-3,-4,-3,2,4,-2,2,0,-3,-2,-1,-2,-1,1,-4,-3,-1],[-1,2,0,-1,-3,1,1,-2,-1,-3,-2,5,-1,-3,-1,0,-1,-3,-2,-2,0,1,-1],[-1,-1,-2,-3,-1,0,-2,-3,-2,1,2,-1,5,0,-2,-1,-1,-1,-1,1,-3,-1,-1],[-2,-3,-3,-3,-2,-3,-3,-3,-1,0,0,-3,0,6,-4,-2,-2,1,3,-1,-3,-3,-1],[-1,-2,-2,-1,-3,-1,-1,-2,-2,-3,-3,-1,-2,-4,7,-1,-1,-4,-3,-2,-2,-1,-2],[1,-1,1,0,-1,0,0,0,-1,-2,-2,0,-1,-2,-1,4,1,-3,-2,-2,0,0,0],[0,-1,0,-1,-1,-1,-1,-2,-2,-1,-1,-1,-1,-2,-1,1,5,-2,-2,0,-1,-1,0],[-3,-3,-4,-4,-2,-2,-3,-2,-2,-3,-2,-3,-1,1,-4,-3,-2,11,2,-3,-4,-3,-2],[-2,-2,-2,-3,-2,-1,-2,-3,2,-1,-1,-2,-1,3,-3,-2,-2,2,7,-1,-3,-2,-1],[0,-3,-3,-3,-1,-2,-2,-3,-3,3,1,-2,1,-1,-2,-2,0,-3,-1,4,-3,-2,-1],[-2,-1,3,4,-3,0,1,-1,0,-3,-4,0,-3,-3,-2,0,-1,-4,-3,-3,4,1,-1],[-1,0,0,1,-3,3,4,-2,0,-3,-3,1,-1,-3,-1,0,-1,-3,-2,-2,1,4,-1],[0,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,0,0,-2,-1,-1,-1,-1,-1]],Qy=function(){return{blosum62:Cs("ARNDCQEGHILKMFPSTWYVBZ?",Ky),blosum62x:Cs("ACDEFGHIKLMNPQRSTVWY",Zy)}}(),Jy=function(t,e,i,r,n){this.seq1=t,this.seq2=e,this.gapPenalty=i||-10,this.gapExtensionPenalty=r||-1,this.substMatrix=n||"blosum62",this.substMatrix&&(this.substMatrix=Qy[this.substMatrix])};Jy.prototype.initMatrices=function(){var t=this;this.n=this.seq1.length,this.m=this.seq2.length,this.score=void 0,this.ali="",this.S=[],this.V=[],this.H=[];var e,i;for(e=0;e<=this.n;++e)for(t.S[e]=[],t.V[e]=[],t.H[e]=[],i=0;i<=this.m;++i)t.S[e][i]=0,t.V[e][i]=0,t.H[e][i]=0;for(e=0;e<=this.n;++e)t.S[e][0]=t.gap(0),t.H[e][0]=-1/0;for(i=0;i<=this.m;++i)t.S[0][i]=t.gap(0),t.V[0][i]=-1/0;this.S[0][0]=0},Jy.prototype.gap=function(t){return this.gapPenalty+t*this.gapExtensionPenalty},Jy.prototype.makeScoreFn=function(){var t,e,i=this.seq1,r=this.seq2,n=this.substMatrix;return n?function(o,a){t=i[o],e=r[a];try{return n[t][e]}catch(t){return-4}}:(cf.warn("Alignment: no subst matrix"),function(n,o){return t=i[n],e=r[o],t===e?5:-3})},Jy.prototype.calc=function(){t.Debug&&cf.time("Alignment.calc"),this.initMatrices();var e,i,r,n,o,a,s,c=this.gap(0),u=this.makeScoreFn(),h=this.gapExtensionPenalty,l=this.V,p=this.H,d=this.S,f=this.n,m=this.m;for(a=1;a<=f;++a)for(i=d[a-1],e=l[a-1],r=l[a],n=p[a],o=d[a],s=1;s<=m;++s)r[s]=Math.max(i[s]+c,e[s]+h),n[s]=Math.max(o[s-1]+c,n[s-1]+h),o[s]=Math.max(i[s-1]+u(a-1,s-1),r[s],n[s]);t.Debug&&cf.timeEnd("Alignment.calc"),t.Debug&&cf.log(this.S,this.V,this.H)},Jy.prototype.trace=function(){var e=this;t.Debug&&cf.time("Alignment.trace"),this.ali1="",this.ali2="";var i,r=this.makeScoreFn(),n=this.n,o=this.m;for(this.S[n][o]>=this.V[n][o]?(i="S",this.score=this.S[n][o]):this.V[n][o]>=this.H[n][o]?(i="V",this.score=this.V[n][o]):(i="H",this.score=this.H[n][o]),t.Debug&&cf.log("Alignment: SCORE",this.score),t.Debug&&cf.log("Alignment: S, V, H",this.S[n][o],this.V[n][o],this.H[n][o]);n>0&&o>0;)"S"===i?e.S[n][o]===e.S[n-1][o-1]+r(n-1,o-1)?(e.ali1=e.seq1[n-1]+e.ali1,e.ali2=e.seq2[o-1]+e.ali2,--n,--o,i="S"):e.S[n][o]===e.V[n][o]?i="V":e.S[n][o]===e.H[n][o]?i="H":(--n,--o):"V"===i?e.V[n][o]===e.V[n-1][o]+e.gapExtensionPenalty?(e.ali1=e.seq1[n-1]+e.ali1,e.ali2="-"+e.ali2,--n,i="V"):e.V[n][o]===e.S[n-1][o]+e.gap(0)?(e.ali1=e.seq1[n-1]+e.ali1,e.ali2="-"+e.ali2,--n,i="S"):--n:"H"===i?e.H[n][o]===e.H[n][o-1]+e.gapExtensionPenalty?(e.ali1="-"+e.ali1,e.ali2=e.seq2[o-1]+e.ali2,--o,i="H"):e.H[n][o]===e.S[n][o-1]+e.gap(0)?(e.ali1="-"+e.ali1,e.ali2=e.seq2[o-1]+e.ali2,--o,i="S"):--o:cf.error("Alignment: no matrix");for(;n>0;)e.ali1=e.seq1[n-1]+e.ali1,e.ali2="-"+e.ali2,--n;for(;o>0;)e.ali1="-"+e.ali1,e.ali2=e.seq2[o-1]+e.ali2,--o;t.Debug&&cf.timeEnd("Alignment.trace"),t.Debug&&cf.log([this.ali1,this.ali2])};var tb=function(t){function e(e){var i=this;t.call(this,e),e.scale||(this.scale="rainbow",this.reverse=dn(e.reverse,!0)),this.scalePerModel={},this.structure.eachModel(function(t){i.domain=[t.atomOffset,t.atomEnd],i.scalePerModel[t.index]=i.getScale()})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){return this.scalePerModel[t.modelIndex](t.index)},e}(Dd);lf.add("atomindex",tb);var eb=function(t){function e(e){if(t.call(this,e),e.scale||(this.scale="OrRd"),!e.domain){var i,r=1/0,n=-1/0;e.sele&&(i=new Selection(e.sele)),this.structure.eachAtom(function(t){var e=t.bfactor;r=Math.min(r,e),n=Math.max(n,e)},i),this.domain=[r,n]}this.bfactorScale=this.getScale()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){return this.bfactorScale(t.bfactor)},e}(Dd);lf.add("bfactor",eb);var ib=function(t){function e(e){t.call(this,e),e.scale||(this.scale="Spectral");var i={},r={};this.structure.eachModel(function(t){var e=0,n={};t.eachChain(function(t){void 0===n[t.chainid]&&(n[t.chainid]=e,e+=1)}),this.domain=[0,e-1],i[t.index]=n,r[t.index]=this.getScale()}.bind(this)),this.atomColor=function(t){var e=i[t.modelIndex];return r[t.modelIndex](e[t.chainid])}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("chainid",ib);var rb=function(t){function e(e){if(t.call(this,e),e.scale||(this.scale="Spectral"),e.domain){var i=this.getScale();this.atomColor=function(t){return i(t.chainIndex)}}else{var r={};this.structure.eachModel(function(t){this.domain=[t.chainOffset,t.chainEnd],r[t.index]=this.getScale()}.bind(this)),this.atomColor=function(t){return r[t.modelIndex](t.chainIndex)}}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("chainindex",rb);var nb=function(t){function e(e){t.call(this,e),e.scale||(this.scale="Spectral");var i={},r={};this.structure.eachModel(function(t){var e=0,n={};t.eachChain(function(t){void 0===n[t.chainname]&&(n[t.chainname]=e,e+=1)}),this.domain=[0,e-1],i[t.index]=n,r[t.index]=this.getScale()}.bind(this)),this.atomColor=function(t){var e=i[t.modelIndex];return r[t.modelIndex](e[t.chainname])}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("chainname",nb);var ob=function(t){function e(e){t.call(this,e),e.scale||(this.scale="RdYlBu"),this.rsrzScale=this.getScale({domain:[2,0]}),this.rsccScale=this.getScale({domain:[.678,1]});var i=e.structure.validation||{};this.rsrzDict=i.rsrzDict||{},this.rsccDict=i.rsccDict||{}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){var e=t.resno;t.inscode&&(e+="^"+t.inscode),t.chainname&&(e+=":"+t.chainname),e+="/"+t.modelIndex;var i=this.rsrzDict[e];if(void 0!==i)return this.rsrzScale(i);var r=this.rsccDict[e];return void 0!==r?this.rsccScale(r):9474192},e}(Dd);lf.add("densityfit",ob);var ab={ARG:{CD:.1,CZ:.5,NE:-.1},ASN:{CG:.55,OD1:-.55},ASP:{CB:-.16,CG:.36,OD1:-.6,OD2:-.6},CYS:{CB:.19,SG:-.19},GLN:{CD:.55,OE1:-.55},GLU:{CD:.36,CG:-.16,OE1:-.6,OE2:-.6},HIS:{CB:.1,CD2:.2,CE1:.45,CG:.15,ND1:.05,NE2:.05},LYS:{CE:.25,NZ:.75},MET:{CE:.06,CG:.06,SD:-.12},PTR:{C:.55,CA:.1,CZ:.25,N:-.35,O:-.55,O1P:-.85,O2P:-.85,O3P:-.85,OG1:-1.1,P:1.4},SEP:{C:.55,CA:.1,CB:.25,N:-.35,O:-.55,O1P:-.85,O2P:-.85,O3P:-.85,OG1:-1.1,P:1.4},SER:{CB:.25,OG:-.25},THR:{CB:.25,OG1:-.25},TPO:{C:.55,CA:.1,CB:.25,N:-.35,O:-.55,OG1:-1.1,O1P:-.85,O2P:-.85,O3P:-.85,P:1.4},TRP:{CD1:.06,CD2:.1,CE2:-.04,CE3:-.03,CG:-.03,NE1:-.06},TYR:{CZ:.25,OH:-.25},backbone:{C:.55,O:-.55,N:-.35,CA:.1}},sb=12,cb=1.04,ub=.25,hb=function(t){function e(e){function i(t){return t.isProtein()?ab[t.resname]&&ab[t.resname][t.atomname]||ab.backbone[t.atomname]||0:0}t.call(this,e),e.scale||(this.scale="rwb"),e.domain||(this.domain=[-.5,0,.5]);var r=this.getScale(),n=this.structure,o=new Float32Array(n.atomCount),a=[],s=[];n.eachAtom(function(t){if(o[t.index]=i(t)*t.occupancy,"N"===t.atomname){var e=Ls(t);void 0!==e&&(a.push(e),s.push(ub*t.occupancy))}});var c=this.structure.getBoundingBox();c.expandByScalar(cb);var u=Rs(a),h=new Fa(u,c),l=new Fa(this.structure.atomStore,c),p=this.atomProxy,d=new g,f=sb*sb;this.positionColor=function(t){for(var e=0,i=l.within(t.x,t.y,t.z,sb),n=0;n<i.length;n++){var a=i[n],c=o[a];if(0!==c){p.index=a,d.x=t.x-p.x,d.y=t.y-p.y,d.z=t.z-p.z;var m=d.lengthSq();m<f&&(e+=c/m)}}for(var g=h.within(t.x,t.y,t.z,sb),v=0;v<g.length;v++){var y=g[v];d.x=t.x-u.x[y],d.y=t.y-u.y[y],d.z=t.z-u.z[y];var b=d.lengthSq();b<f&&(e+=s[y]/b)}return r(e)}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("electrostatic",hb);var lb={H:16777215,HE:14286847,LI:13402367,BE:12779264,B:16758197,C:9474192,N:3166456,O:16715021,F:9494608,NE:11789301,NA:11230450,MG:9109248,AL:12560038,SI:1578e4,P:16744448,S:16777008,CL:2093087,AR:8442339,K:9388244,CA:4062976,SC:15132390,TI:12567239,V:10921643,CR:9083335,MN:10255047,FE:14706227,CO:15765664,NI:5296208,CU:13140019,ZN:8224944,GA:12750735,GE:6721423,AS:12419299,SE:16752896,BR:10889513,KR:6076625,RB:7351984,SR:65280,Y:9764863,ZR:9756896,NB:7586505,MO:5551541,TC:3907230,RU:2396047,RH:687500,PD:27013,AG:12632256,CD:16767375,IN:10909043,SN:6717568,SB:10380213,TE:13924864,I:9699476,XE:9699476,CS:5707663,BA:51456,LA:7394559,CE:16777159,PR:14286791,ND:13107143,PM:10747847,SM:9437127,EU:6422471,GD:4587463,TB:3211207,DY:2097095,HO:65436,ER:58997,TM:54354,YB:48952,LU:43812,HF:5096191,TA:5089023,W:2200790,RE:2522539,OS:2516630,IR:1528967,PT:13684960,AU:16765219,HG:12105936,TL:10900557,PB:5724513,BI:10375093,PO:11230208,AT:7688005,RN:4358806,FR:4325478,RA:32e3,AC:7384058,TH:47871,PA:41471,U:36863,NP:33023,PU:27647,AM:5528818,CM:7888099,BK:9064419,CF:10565332,ES:11739092,FM:11739066,MD:11734438,NO:12389767,LR:13041766,RF:13369433,DB:13697103,SG:14221381,BH:14680120,HS:15073326,MT:15400998,DS:16777215,RG:16777215,CN:16777215,UUT:16777215,FL:16777215,UUP:16777215,LV:16777215,UUH:16777215,D:16777152,T:16777120},pb=function(t){function e(e){var i=e||{};i.value=dn(i.value,lb.C),t.call(this,i)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){var e=t.element;return"C"===e?this.value:lb[e]||16777215},e}(Dd);lf.add("element",pb);var db=function(t){function e(e){t.call(this,e),e.scale||(this.scale="Spectral"),e.domain||(this.domain=[0,this.structure.entityList.length-1]);var i=this.getScale();this.atomColor=function(t){return i(t.entityIndex)}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("entityindex",db);var fb=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){var e=t.entity;switch(e?e.entityType:void 0){case sg:return 8374655;case cg:return 16629894;case ug:return 12496596;case hg:return 3697840;default:return 16777113}},e}(Dd);lf.add("entitytype",fb);var mb=function(t){function e(e){t.call(this,e);var i=e.structure.validation||{};this.geoAtomDict=i.geoAtomDict||{},this.geoDict=i.geoDict||{}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){var e=t.resno;t.inscode&&(e+="^"+t.inscode),t.chainname&&(e+=":"+t.chainname),e+="/"+t.modelIndex;var i,r=this.geoAtomDict[e];return i=void 0!==r?Hn(r[t.atomname]||0):this.geoDict[e]||0,0===i?2188972:1===i?16703627:2===i?16018755:i>=3?10813478:9474192},e}(Dd);lf.add("geoquality",mb);var gb=function(t){function e(e){t.call(this,e),e.scale||(this.scale="RdYlGn");var i,r={};for(i in Sg)r[i]=Sg[i][0];if(!e.domain){var n,o=1/0,a=-1/0;for(i in r)n=r[i],o=Math.min(o,n),a=Math.max(a,n);this.domain=[o,0,a]}var s=this.getScale();this.atomColor=function(t){return s(r[t.resname]||Ag)}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("hydrophobicity",gb);var vb=function(t){function e(e){t.call(this,e),e.scale||(this.scale="rainbow"),e.domain||(this.domain=[0,this.structure.modelStore.count]);var i=this.getScale();this.atomColor=function(t){return i(t.modelIndex)}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("modelindex",vb);var yb=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){switch(t.residueType.moleculeType){case 1:return 3697840;case 2:return 15729279;case 3:return 12496596;case 4:return 16629894;case 5:return 12540695;case 6:return 8374655;default:return 16777113}},e}(Dd);lf.add("moleculetype",yb);var bb=function(t){function e(e){t.call(this,e),e.scale||(this.scale="PuBu"),e.domain||(this.domain=[0,1]);var i=this.getScale();this.atomColor=function(t){return i(t.occupancy)}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("occupancy",bb);var xb=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(){return Os()},e.prototype.volumeColor=function(){return Os()},e.prototype.positionColor=function(){return Os()},e}(Dd);lf.add("random",xb);var _b=function(t){function e(e){var i=this;if(t.call(this,e),e.scale||(this.scale="rainbow",this.reverse=dn(e.reverse,!0)),e.domain){var r=this.getScale();this.atomColor=function(t){return r(t.residueIndex)}}else{var n={};this.structure.eachChain(function(t){i.domain=[t.residueOffset,t.residueEnd],n[t.index]=i.getScale()}),this.atomColor=function(t){return n[t.chainIndex](t.residueIndex)}}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(Dd);lf.add("residueindex",_b);var wb={ALA:9240460,ARG:124,ASN:16743536,ASP:10485826,CYS:16777072,GLN:16731212,GLU:6684672,GLY:16777215,HIS:7368959,ILE:19456,LEU:4546117,LYS:4671416,MET:12099650,PHE:5459026,PRO:5395026,SER:16740418,THR:12078080,TRP:5195264,TYR:9203788,VAL:16747775,ASX:16711935,GLX:16711935,ASH:16711935,GLH:16711935,A:10526975,G:16740464,I:8454143,C:16747595,T:10551200,U:16744576,DA:10526975,DG:16740464,DI:8454143,DC:16747595,DT:10551200,DU:16744576},Sb=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){return wb[t.resname]||16711935},e}(Dd);lf.add("resname",Sb);var Ab={alphaHelix:16711808,threeTenHelix:10485888,piHelix:6291584,betaStrand:16762880,betaTurn:6324479,coil:16777215,dna:11403518,rna:16580962,carbohydrate:10921722},Mb=function(t){function e(e){t.call(this,e),this.rp=this.structure.getResidueProxy()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(t){var e=t.sstruc,i=this.rp;return"h"===e?Ab.alphaHelix:"g"===e?Ab.threeTenHelix:"i"===e?Ab.piHelix:"e"===e||"b"===e?Ab.betaStrand:"t"===e?Ab.betaTurn:(i.index=t.residueIndex,i.isDna()?Ab.dna:i.isRna()?Ab.rna:i.isSaccharide()?Ab.carbohydrate:i.isProtein()||"s"===e||"l"===e?Ab.coil:8421504)},e}(Dd);lf.add("sstruc",Mb);var Pb=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.atomColor=function(){return this.value},e.prototype.bondColor=function(){return this.value},e.prototype.valueColor=function(){return this.value},e.prototype.volumeColor=function(){return this.value},e}(Dd);lf.add("uniform",Pb);var Tb=function(t){function e(e){t.call(this,e),this.valueScale=this.getScale()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.volumeColor=function(t){return this.valueScale(this.volume.data[t])},e}(Dd);lf.add("value",Tb);var Eb=function(t){function e(e){t.call(this,e);var i=this.volume;if(i&&i.inverseMatrix){var r=this.getScale(),n=i.inverseMatrix,o=i.data,a=i.nx,s=i.ny,c=a*s,u=new g;this.positionColor=function(t){u.copy(t),u.applyMatrix4(n);var e=Math.floor(u.x),i=Math.floor(u.y),h=Math.floor(u.z),l=(h*s+i)*a+e,p=l+1,d=l+a,f=l+c,m=d+1,g=f+1,v=d+c,y=v+1,b=o[l],x=o[p],_=o[d],w=o[f],S=o[m],A=o[g],M=o[v],P=o[y],T=u.x-e,E=u.y-i,C=u.z-h,I=Zn(b,x,T),L=Zn(w,A,T),R=Zn(_,S,T),O=Zn(M,P,T),D=Zn(Zn(I,R,E),Zn(L,O,E),C);return r(D)}}else{var h=this.value;this.positionColor=function(){return h}}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.positionColor=function(){},e}(Dd);lf.add("volume",Eb);var Cb=function(t){function e(e,i,r){var n=this,o=r||{};o.name=dn(o.name,i.name),t.call(this,e,o),this.script=i,this.status="loaded",this.script.signals.nameChanged.add(function(t){n.setName(t)})}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"script"},e.prototype.addRepresentation=function(){},e.prototype.removeRepresentation=function(){},e.prototype.run=function(){var t=this;this.setStatus("running"),this.script.call(this.stage).then(function(){t.setStatus("finished")}),this.setStatus("called")},e.prototype.dispose=function(){this.signals.disposed.dispatch()},e.prototype.setVisibility=function(){},e.prototype.getCenter=function(){},e.prototype.getZoom=function(){},e.prototype.getBox=function(){},Object.defineProperties(e.prototype,i),e}(Gy);vf.add("script",Cb);var Ib=function(t){function e(e,i,r){var n=r||{};n.name=dn(n.name,i.name),t.call(this,e,n),this.shape=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"shape"},e.prototype.addRepresentation=function(e,i){return t.prototype.addRepresentation.call(this,e,this.shape,i)},e.prototype.getBoxUntransformed=function(){return this.shape.boundingBox},e.prototype.getCenterUntransformed=function(){return this.shape.center},e.prototype.dispose=function(){this.shape.dispose(),t.prototype.dispose.call(this)},Object.defineProperties(e.prototype,i),e}(Gy);vf.add("shape",Ib);var Lb=function(t){function e(e,i,r,n){var o=this,a=r||{};a.name=dn(a.name,i.name),t.call(this,e,a),this.signals=Object.assign(this.signals,{frameChanged:new io,playerChanged:new io,gotNumframes:new io,parametersChanged:new io}),this.trajectory=i,this.parent=n,this.status="loaded",this.defaultStep=dn(a.defaultStep,void 0),this.defaultTimeout=dn(a.defaultTimeout,50),this.defaultInterpolateType=dn(a.defaultInterpolateType,""),this.defaultInterpolateStep=dn(a.defaultInterpolateStep,5),this.defaultMode=dn(a.defaultMode,"loop"),this.defaultDirection=dn(a.defaultDirection,"forward"),i.signals.frameChanged.add(function(t){o.signals.frameChanged.dispatch(t)}),i.signals.playerChanged.add(function(t){o.signals.playerChanged.dispatch(t)}),i.signals.gotNumframes.add(function(t){o.signals.gotNumframes.dispatch(t)}),void 0!==a.initialFrame&&this.setFrame(a.initialFrame)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"trajectory"},e.prototype.addRepresentation=function(e,i){return t.prototype.addRepresentation.call(this,e,this.trajectory,i)},e.prototype.setFrame=function(t){this.trajectory.setFrame(t)},e.prototype.setParameters=function(t){this.trajectory.setParameters(t),this.signals.parametersChanged.dispatch(t)},e.prototype.dispose=function(){this.trajectory.dispose(),t.prototype.dispose.call(this)},e.prototype.getCenter=function(){},Object.defineProperties(e.prototype,i),e}(Gy),Rb=function(t){function e(e,i,r){t.call(this,"",i,r),this.name=e.name,this.path=e.path,this.frames=e.coordinates,this.boxes=e.boxes}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"frames"},e.prototype.makeAtomIndices=function(){"StructureView"===this.structure.type?this.atomIndices=this.structure.getAtomIndices():this.atomIndices=null},e.prototype._loadFrame=function(t,e){var i,r=this.frames[t];if(this.atomIndices){var n=this.atomIndices,o=n.length;i=new Float32Array(3*o);for(var a=0;a<o;++a){var s=3*a,c=3*n[a];i[s+0]=r[c+0],i[s+1]=r[c+1],i[s+2]=r[c+2]}}else i=new Float32Array(r);var u=this.boxes[t],h=this.frames.length;this.process(t,u,i,h),"function"==typeof e&&e()},e.prototype.getNumframes=function(){this.frames&&this.setNumframes(this.frames.length)},e.prototype.getPath=function(t,e){var i,r,n,o=this,a=this.numframes,s=3*t,c=new Float32Array(3*a);for(i=0;i<a;++i)r=3*i,n=o.frames[i],c[r+0]=n[s+0],c[r+1]=n[s+1],c[r+2]=n[s+2];e(c)},Object.defineProperties(e.prototype,i),e}(Cv),Ob=function(t){function e(e,i,r){t.call(this,"",i,r)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"structure"},e.prototype.makeAtomIndices=function(){this.structure.atomSet.getSize()<this.structure.atomStore.count?this.atomIndices=this.structure.getAtomIndices():this.atomIndices=null},e.prototype._loadFrame=function(t,e){var i,r=this.structure,n=r.frames[t];if(this.atomIndices){var o=this.atomIndices,a=o.length;i=new Float32Array(3*a);for(var s=0;s<a;++s){var c=3*s,u=3*o[s];i[c+0]=n[u+0],i[c+1]=n[u+1],i[c+2]=n[u+2]}}else i=new Float32Array(n);var h=r.boxes[t],l=r.frames.length;this.process(t,h,i,l),"function"==typeof e&&e()},e.prototype.getNumframes=function(){this.setNumframes(this.structure.frames.length)},e.prototype.getPath=function(t,e){var i,r,n,o=this,a=this.numframes,s=3*t,c=new Float32Array(3*a);for(i=0;i<a;++i)r=3*i,n=o.structure.frames[i],c[r+0]=n[s+0],c[r+1]=n[s+1],c[r+2]=n[s+2];e(c)},Object.defineProperties(e.prototype,i),e}(Cv),Db=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"remote"},e.prototype.makeAtomIndices=function(){var t=[];if("StructureView"===this.structure.type){var e,i,r=this.structure.getAtomIndices(),n=r[0],o=r[0],a=r.length;for(e=1;e<a;++e)o+1<(i=r[e])&&(t.push([n,o+1]),n=i),o=i;t.push([n,o+1])}else t.push([0,this.atomCount]);this.atomIndices=t},e.prototype._loadFrame=function(t,e){var i=new XMLHttpRequest,r=pf.trajectory,n=r.getFrameUrl(this.trajPath,t),o=r.getFrameParams(this.trajPath,this.atomIndices);i.open("POST",n,!0),i.responseType="arraybuffer",i.setRequestHeader("Content-type","application/x-www-form-urlencoded"),i.addEventListener("load",function(){var r=i.response;if(!r)return void cf.error("empty arrayBuffer for '"+n+"'");var o=new Int32Array(r,0,1)[0],a=new Float32Array(r,8,9),s=new Float32Array(r,44);this.process(t,a,s,o),"function"==typeof e&&e()}.bind(this),!1),i.send(o)},e.prototype.getNumframes=function(){var t=new XMLHttpRequest,e=pf.trajectory.getNumframesUrl(this.trajPath);t.open("GET",e,!0),t.addEventListener("load",function(){this.setNumframes(parseInt(t.response))}.bind(this),!1),t.send(null)},e.prototype.getPath=function(t,e){if(this.pathCache[t])return void e(this.pathCache[t]);cf.time("loadPath");var i=new XMLHttpRequest,r=pf.trajectory.getPathUrl(this.trajPath,t);i.open("POST",r,!0),i.responseType="arraybuffer",i.setRequestHeader("Content-type","application/x-www-form-urlencoded"),i.addEventListener("load",function(){cf.timeEnd("loadPath");var n=i.response;if(!n)return void cf.error("empty arrayBuffer for '"+r+"'");var o=new Float32Array(n);this.pathCache[t]=o,e(o)}.bind(this),!1),i.send("")},Object.defineProperties(e.prototype,i),e}(Cv);Mv.prototype.getView=function(t){return new Nb(this,t)};var Nb=function(e){function i(t,i){e.call(this),this.structure=t,this.selection=i,this.center=new g,this.boundingBox=new st,this._bp=this.getBondProxy(),this._ap=this.getAtomProxy(),this._rp=this.getResidueProxy(),this._cp=this.getChainProxy(),this.selection&&this.selection.signals.stringChanged.add(this.refresh,this),this.structure.signals.refreshed.add(this.refresh,this),this.refresh()}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{},name:{},path:{},title:{},id:{},atomSetDict:{},biomolDict:{},entityList:{},unitcell:{},frames:{},boxes:{},validation:{},bondStore:{},backboneBondStore:{},rungBondStore:{},atomStore:{},residueStore:{},chainStore:{},modelStore:{},atomMap:{},residueMap:{},bondHash:{},spatialHash:{}};return i.prototype.init=function(){},r.type.get=function(){return"StructureView"},r.name.get=function(){return this.structure.name},r.path.get=function(){return this.structure.path},r.title.get=function(){return this.structure.title},r.id.get=function(){return this.structure.id},r.atomSetDict.get=function(){return this.structure.atomSetDict},r.biomolDict.get=function(){return this.structure.biomolDict},r.entityList.get=function(){return this.structure.entityList},r.unitcell.get=function(){return this.structure.unitcell},r.frames.get=function(){return this.structure.frames},r.boxes.get=function(){return this.structure.boxes},r.validation.get=function(){return this.structure.validation},r.bondStore.get=function(){return this.structure.bondStore},r.backboneBondStore.get=function(){return this.structure.backboneBondStore},r.rungBondStore.get=function(){return this.structure.rungBondStore},r.atomStore.get=function(){return this.structure.atomStore},r.residueStore.get=function(){return this.structure.residueStore},r.chainStore.get=function(){return this.structure.chainStore},r.modelStore.get=function(){return this.structure.modelStore},r.atomMap.get=function(){return this.structure.atomMap},r.residueMap.get=function(){return this.structure.residueMap},r.bondHash.get=function(){return this.structure.bondHash},r.spatialHash.get=function(){return this.structure.spatialHash},i.prototype.refresh=function(){var e=this;t.Debug&&cf.time("StructureView.refresh"),this.atomSetCache={},this.atomSet=this.getAtomSet(this.selection,!0),this.structure.atomSet&&(this.atomSet=this.atomSet.intersection(this.structure.atomSet)),this.bondSet=this.getBondSet();for(var i in e.atomSetDict){var r=e.atomSetDict[i];e.atomSetCache["__"+i]=r.makeIntersection(e.atomSet)}this.atomCount=this.atomSet.getSize(),this.bondCount=this.bondSet.getSize(),this.boundingBox=this.getBoundingBox(),this.center=this.boundingBox.getCenter(),t.Debug&&cf.timeEnd("StructureView.refresh"),this.signals.refreshed.dispatch()},i.prototype.setSelection=function(t){this.selection=t,this.refresh()},i.prototype.getSelection=function(t){var e=[];t&&t.string&&e.push(t.string);var i=this.structure.getSelection();i&&i.string&&e.push(i.string),this.selection&&this.selection.string&&e.push(this.selection.string);var r="";return e.length>0&&(r="( "+e.join(" ) AND ( ")+" )"),new Kd(r)},i.prototype.getStructure=function(){return this.structure.getStructure()},i.prototype.eachBond=function(t,e){this.structure.eachBond(t,this.getSelection(e))},i.prototype.eachAtom=function(t,e){var i=this.getAtomProxy(),r=this.getAtomSet(e),n=this.atomStore.count;if(r.getSize()<n)r.forEach(function(e){i.index=e,t(i)});else for(var o=0;o<n;++o)i.index=o,t(i)},i.prototype.eachResidue=function(t,e){this.structure.eachResidue(t,this.getSelection(e))},i.prototype.eachResidueN=function(){console.error("StructureView.eachResidueN() not implemented")},i.prototype.eachChain=function(t,e){this.structure.eachChain(t,this.getSelection(e))},i.prototype.eachModel=function(t,e){this.structure.eachModel(t,this.getSelection(e))},i.prototype.getAtomSet=function(t,e){var i=this.structure.getAtomSet(t);return!e&&this.atomSet&&(i=i.makeIntersection(this.atomSet)),i},i.prototype.getAtomIndices=function(t){return this.structure.getAtomIndices(this.getSelection(t))},i.prototype.refreshPosition=function(){return this.structure.refreshPosition()},i.prototype.dispose=function(){this.selection&&this.selection.signals.stringChanged.remove(this.refresh,this),this.structure.signals.refreshed.remove(this.refresh,this),delete this.structure,delete this.atomSet,delete this.bondSet,delete this.atomCount,delete this.bondCount},Object.defineProperties(i.prototype,r),i}(Mv),kb=function(t){function e(e,i,r){var n=r||{};n.name=dn(n.name,i.name),t.call(this,e,n),this.signals=Object.assign(this.signals,{trajectoryAdded:new io,trajectoryRemoved:new io,defaultAssemblyChanged:new io}),this.structure=i,this.trajList=[],this.initSelection(n.sele),this.setDefaultAssembly(n.assembly||"")}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"structure"},e.prototype.initSelection=function(t){var e=this;this.selection=new Kd(t),this.structureView=new Nb(this.structure,this.selection),this.selection.signals.stringChanged.add(function(){e.structureView.setSelection(e.selection),e.rebuildRepresentations(),e.rebuildTrajectories()})},e.prototype.setSelection=function(t){return this.selection.setString(t),this},e.prototype.setDefaultAssembly=function(t){var e=this;this.defaultAssembly=t,this.reprList.forEach(function(t){t.setParameters({defaultAssembly:e.defaultAssembly})}),this.signals.defaultAssemblyChanged.dispatch(t)},e.prototype.rebuildRepresentations=function(){this.reprList.forEach(function(t){t.build()})},e.prototype.rebuildTrajectories=function(){var t=this;this.trajList.slice().forEach(function(e){e.trajectory.setStructure(t.structureView)})},e.prototype.addRepresentation=function(e,i){var r=i||{};return r.defaultAssembly=this.defaultAssembly,t.prototype.addRepresentation.call(this,e,this.structureView,r)},e.prototype.addTrajectory=function(t,e){var i=this,r=Ds(t,this.structureView,e);r.signals.frameChanged.add(function(){i.updateRepresentations({position:!0})});var n=new Lb(this.stage,r,e,this);return this.trajList.push(n),this.signals.trajectoryAdded.dispatch(n),n},e.prototype.removeTrajectory=function(t){var e=this.trajList.indexOf(t);-1!==e&&this.trajList.splice(e,1),t.dispose(),this.signals.trajectoryRemoved.dispatch(t)},e.prototype.dispose=function(){this.trajList.slice().forEach(function(t){t.dispose()}),this.trajList.length=0,this.structure.dispose(),t.prototype.dispose.call(this)},e.prototype.autoView=function(t,e){Number.isInteger(t)&&(e=t,t=void 0),this.stage.animationControls.zoomMove(this.getCenter(t),this.getZoom(t),dn(e,0))},e.prototype.getBoxUntransformed=function(t){return t?this.structureView.getBoundingBox(new Kd(t)):this.structureView.boundingBox},e.prototype.getCenterUntransformed=function(t){return t&&"string"==typeof t?this.structure.atomCenter(new Kd(t)):this.structure.center},e.prototype.superpose=function(t,e,i,r){return Is(this.structureView,t.structureView,e,i,r),this.updateRepresentations({position:!0}),this},e.prototype.setVisibility=function(e){return t.prototype.setVisibility.call(this,e),this.trajList.forEach(function(t){t.setVisibility(e)}),this},Object.defineProperties(e.prototype,i),e}(Gy);vf.add("structure",kb);var Bb=function(t){function e(e,i,r){var n=r||{};n.name=dn(n.name,i.name),t.call(this,e,n),this.surface=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"surface"},e.prototype.addRepresentation=function(e,i){return t.prototype.addRepresentation.call(this,e,this.surface,i)},e.prototype.getBoxUntransformed=function(){return this.surface.boundingBox},e.prototype.getCenterUntransformed=function(){return this.surface.center},e.prototype.dispose=function(){this.surface.dispose(),t.prototype.dispose.call(this)},Object.defineProperties(e.prototype,i),e}(Gy);vf.add("surface",Bb);var Fb=function(t){function e(e,i,r){var n=r||{};n.name=dn(n.name,i.name),t.call(this,e,n),this.volume=i}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"volume"},e.prototype.addRepresentation=function(e,i){return t.prototype.addRepresentation.call(this,e,this.volume,i)},e.prototype.getBoxUntransformed=function(){return this.volume.boundingBox},e.prototype.getCenterUntransformed=function(){return this.volume.center},e.prototype.dispose=function(){this.volume.dispose(),t.prototype.dispose.call(this)},Object.defineProperties(e.prototype,i),e}(Gy);vf.add("volume",Fb);var zb=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="axes",this.parameters=Object.assign({radius:{type:"number",precision:3,max:10,min:.001},sphereDetail:!0,radialSegments:!0,disableImpostor:!0,showAxes:{type:"boolean",rebuild:!0},showBox:{type:"boolean",rebuild:!0}},this.parameters,{assembly:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.radius=dn(i.radius,.5),i.colorValue=dn(i.colorValue,"lightgreen"),this.showAxes=dn(i.showAxes,!0),this.showBox=dn(i.showBox,!1),t.prototype.init.call(this,i)},e.prototype.getPrincipalAxes=function(){var t,e=this.getAssembly();return e&&(t=e.partList[0].getSelection()),this.structureView.getPrincipalAxes(t)},e.prototype.getAxesData=function(t){var e=this.getPrincipalAxes(t),i=new tt(this.colorValue),r=0,n=0;this.showAxes&&(r+=6,n+=3),this.showBox&&(r+=8,n+=12);var o=new Float32Array(3*r),a=To(r,i.r,i.g,i.b),s=Po(r,this.radius),c=new Float32Array(3*n),u=new Float32Array(3*n),h=To(n,i.r,i.g,i.b),l=Po(n,this.radius),p=0;if(this.showAxes){var d=function(t,e){t.toArray(o,2*p),e.toArray(o,2*p+3),t.toArray(c,p),e.toArray(u,p),p+=3};d(e.begA,e.endA),d(e.begB,e.endB),d(e.begC,e.endC)}if(this.showBox){var f=new g,m=e.getProjectedScaleForAtoms(t),v=m.d1a,y=m.d2a,b=m.d3a,x=m.d1b,_=m.d2b,w=m.d3b;console.log(v,y,b,x,_,w);var S=2*p,A=function(t,i,r){f.copy(e.center).addScaledVector(e.normVecA,t).addScaledVector(e.normVecB,i).addScaledVector(e.normVecC,r),f.toArray(o,S),S+=3};A(v,y,b),A(v,y,w),A(v,_,w),A(v,_,b),A(x,_,w),A(x,_,b),A(x,y,b),A(x,y,w);var M=p,P=function(t,e){f.fromArray(o,2*p+3*t).toArray(c,M),f.fromArray(o,2*p+3*e).toArray(u,M),M+=3};P(0,1),P(0,3),P(0,6),P(1,2),P(1,7),P(2,3),P(2,4),P(3,5),P(4,5),P(4,7),P(5,6),P(6,7)}var T=new Hm(e);return{vertex:{position:o,color:a,radius:s,picking:T},edge:{position1:c,position2:u,color:h,color2:h,radius:l,picking:T}}},e.prototype.create=function(){var t=this.getAxesData(this.structureView);this.sphereBuffer=new $v(t.vertex,this.getBufferParams({sphereDetail:this.sphereDetail,disableImpostor:this.disableImpostor,dullInterior:!0})),this.cylinderBuffer=new oy(t.edge,this.getBufferParams({openEnded:!0,radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,dullInterior:!0})),this.dataList.push({sview:this.structureView,bufferList:[this.sphereBuffer,this.cylinderBuffer]})},e.prototype.updateData=function(t,e){var i=this.getAxesData(e.sview),r={},n={};t&&!t.position||(r.position=i.vertex.position,n.position1=i.edge.position1,n.position2=i.edge.position2),t&&!t.color||(r.color=i.vertex.color,n.color=i.edge.color,n.color2=i.edge.color),t&&!t.radius||(r.radius=i.vertex.radius,n.radius=i.edge.radius),this.sphereBuffer.setAttributes(r),this.cylinderBuffer.setAttributes(n)},e}(ky);df.add("axes",zb);var Ub=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="ball+stick",this.parameters=Object.assign({sphereDetail:!0,radialSegments:!0,openEnded:!0,disableImpostor:!0,aspectRatio:{type:"number",precision:1,max:10,min:1},lineOnly:{type:"boolean",rebuild:!0},cylinderOnly:{type:"boolean",rebuild:!0},multipleBond:{type:"select",rebuild:!0,options:{off:"off",symmetric:"symmetric",offset:"offset"}},bondScale:{type:"number",precision:2,max:1,min:.01},bondSpacing:{type:"number",precision:2,max:2,min:.5}},this.parameters),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.radius=dn(i.radius,.15),this.aspectRatio=dn(i.aspectRatio,2),this.lineOnly=dn(i.lineOnly,!1),this.cylinderOnly=dn(i.cylinderOnly,!1),this.multipleBond=dn(i.multipleBond,"off"),this.bondSpacing=dn(i.bondSpacing,1),this.bondScale=dn(i.bondScale,.4),t.prototype.init.call(this,i)},e.prototype.getAtomParams=function(e,i){return i=Object.assign({radiusParams:{radius:this.radius,scale:this.scale*this.aspectRatio}},i),t.prototype.getAtomParams.call(this,e,i)},e.prototype.getAtomData=function(t,e,i){return t.getAtomData(this.getAtomParams(e,i))},e.prototype.getBondParams=function(e,i){return i=Object.assign({multipleBond:this.multipleBond,bondSpacing:this.bondSpacing,bondScale:this.bondScale},i),t.prototype.getBondParams.call(this,e,i)},e.prototype.getBondData=function(t,e,i){return t.getBondData(this.getBondParams(e,i))},e.prototype.createData=function(t){var e=this.getBondData(t),i=[];if(this.lineOnly)this.lineBuffer=new By(e,this.getBufferParams()),i.push(this.lineBuffer);else{var r=new oy(e,this.getBufferParams({openEnded:this.openEnded,radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,dullInterior:!0}));if(i.push(r),!this.cylinderOnly){var n=new $v(this.getAtomData(t),this.getBufferParams({sphereDetail:this.sphereDetail,disableImpostor:this.disableImpostor,dullInterior:!0}));i.push(n)}}return{bufferList:i}},e.prototype.updateData=function(t,e){"off"!==this.multipleBond&&t&&t.radius&&(t.position=!0);var i=this.getBondData(e.sview,t);if(this.lineOnly){var r={};t&&!t.position||(r.position1=i.position1,r.position2=i.position2),t&&!t.color||(r.color=i.color,r.color2=i.color2),e.bufferList[0].setAttributes(r)}else{var n={};if(t&&!t.position||(n.position1=i.position1,n.position2=i.position2),t&&!t.color||(n.color=i.color,n.color2=i.color2),t&&!t.radius||(n.radius=i.radius),e.bufferList[0].setAttributes(n),!this.cylinderOnly){var o=this.getAtomData(e.sview,t),a={};t&&!t.position||(a.position=o.position),t&&!t.color||(a.color=o.color),t&&!t.radius||(a.radius=o.radius),e.bufferList[1].setAttributes(a)}}},e.prototype.setParameters=function(e){var i=!1,r={};return e&&(e.aspectRatio||e.bondSpacing||e.bondScale)&&(r.radius=!0,sf&&!this.disableImpostor||(i=!0)),t.prototype.setParameters.call(this,e,r,i),this},e}(ky);df.add("ball+stick",Ub);var jb=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="backbone",this.parameters=Object.assign({},this.parameters,{multipleBond:null,bondSpacing:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.aspectRatio=dn(i.aspectRatio,1),i.radius=dn(i.radius,.25),t.prototype.init.call(this,i)},e.prototype.getAtomData=function(t,e,i){return t.getBackboneAtomData(this.getAtomParams(e,i))},e.prototype.getBondData=function(t,e,i){return t.getBackboneBondData(this.getBondParams(e,i))},e}(Ub);df.add("backbone",jb);var Gb=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="base",this.parameters=Object.assign({},this.parameters,{multipleBond:null,bondSpacing:null})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.aspectRatio=dn(i.aspectRatio,1),i.radius=dn(i.radius,.3),t.prototype.init.call(this,i)},e.prototype.getAtomData=function(t,e,i){return t.getRungAtomData(this.getAtomParams(e,i))},e.prototype.getBondData=function(t,e,i){var r=this.getBondParams(e,i);return r.colorParams.rung=!0,t.getRungBondData(r)},e}(Ub);df.add("base",Gb),ks.prototype={constructor:ks,getAtomIterator:function(t,e){function i(){var t=this.get(u);return u+=1,t}function r(i){var r=h[c%4];if(r.index=o.getAtomIndexByType(i,t),e&&i>0&&i<s&&"e"===r.sstruc){var n=l[c%4];return p.index=o.getAtomIndexByType(i+1,t),d.index=o.getAtomIndexByType(i-1,t),n.addVectors(p,d).add(r).add(r).multiplyScalar(.25),c+=1,n}return c+=1,r}function n(){c=0,u=-1}var o=this.polymer,a=o.structure,s=o.residueCount,c=0,u=-1,h=[a.getAtomProxy(),a.getAtomProxy(),a.getAtomProxy(),a.getAtomProxy()],l=[new g,new g,new g,new g],p=a.getAtomProxy(),d=a.getAtomProxy();return{size:s,next:i,get:r,reset:n}},getSubdividedColor:function(t){function e(t,e,i){c.atomColorToArray(t,e,i)}var i=this.subdiv,r=this.polymer,n=(r.residueCount-1)*i*3+3;r.isCyclic&&(n+=3*i);var o=new Float32Array(n),a=this.getAtomIterator("trace"),s=t||{};s.structure=r.structure;var c=lf.getScheme(s);return this.interpolator.getColor(a,e,o,0,r.isCyclic),{color:o}},getSubdividedPicking:function(){function t(t){return t.index}var e=this.subdiv,i=this.polymer,r=(i.residueCount-1)*e+1;i.isCyclic&&(r+=e);var n=i.structure,o=this.getAtomIterator("trace"),a=new Float32Array(r);return this.interpolator.getPicking(o,t,a,0,i.isCyclic),{picking:new $m(a,n)}},getSubdividedPosition:function(){return{position:this.getPosition()}},getSubdividedOrientation:function(){var t=this.getTangent(),e=this.getNormals(t);return{tangent:t,normal:e.normal,binormal:e.binormal}},getSubdividedSize:function(t,e){function i(t){return c.atomRadius(t)}var r=this.subdiv,n=this.polymer,o=(n.residueCount-1)*r+1;n.isCyclic&&(o+=r);var a=new Float32Array(o),s=this.getAtomIterator("trace"),c=new ga(t,e);return this.interpolator.getSize(s,i,a,0,n.isCyclic),{size:a}},getPosition:function(){var t=this.subdiv,e=this.polymer,i=(e.residueCount-1)*t*3+3;e.isCyclic&&(i+=3*t);var r=new Float32Array(i),n=this.positionIterator||this.getAtomIterator("trace",this.smoothSheet);return this.interpolator.getPosition(n,r,0,e.isCyclic),r},getTangent:function(){var t=this.subdiv,e=this.polymer,i=(this.size-1)*t*3+3;e.isCyclic&&(i+=3*t);var r=new Float32Array(i),n=this.positionIterator||this.getAtomIterator("trace",this.smoothSheet);return this.interpolator.getTangent(n,r,0,e.isCyclic),r},getNormals:function(t){var e=this.subdiv,i=this.polymer,r=i.isProtein(),n=this.size,o=(n-1)*e*3+3;i.isCyclic&&(o+=3*e);var a=new Float32Array(o),s=new Float32Array(o);if(this.directional&&!this.polymer.isCg()){var c=this.getAtomIterator("direction1"),u=this.getAtomIterator("direction2");this.interpolator.getNormalDir(c,u,t,a,s,0,i.isCyclic,r)}else this.interpolator.getNormal(n,t,a,s,0,i.isCyclic,r);return{normal:a,binormal:s}}};var Vb=new g,$b=new g,Hb=function(t){function e(e,i){var r=e||{},n=i||{},o=dn(n.radialSegments,4),a=dn(n.capped,!1),s=a?o:0,c=a?o-2:0,u=r.position.length/3,h=u*o*3+2*s*3,l=2*(u-1)*o*3+2*c*3,p=new Float32Array(h),d=new Float32Array(h),f=new Float32Array(h),m=Cn(l,h/3);t.call(this,{position:p,color:d,index:m,normal:f,picking:r.picking},n),this.aspectRatio=dn(n.aspectRatio,1),this.radialSegments=o,this.capped=a,this.capVertices=s,this.capTriangles=c,this.size2=u,r.primitiveId=Co(u),this.setAttributes(r),this.meshIndex=m,this.makeIndex()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setAttributes=function(t){var e,i,r,n,o,a,s,c,u,h,l,p=this.aspectRatio,d=this.size2,f=d-1,m=this.radialSegments,g=this.geometry.attributes;t.position&&(e=t.position,i=t.normal,r=t.binormal,n=t.tangent,a=t.size,c=g.position.array,h=g.normal.array,g.position.needsUpdate=!0,g.normal.needsUpdate=!0),t.color&&(o=t.color,u=g.color.array,g.color.needsUpdate=!0),t.primitiveId&&(s=t.primitiveId,l=g.primitiveId.array,g.primitiveId.needsUpdate=!0);var v,y,b,x,_,w,S,A,M,P,T,E,C,I,L,R,O,D,N,k,B,F,z,U=[],j=[],G=[],V=[],$=[],H=[];if(e)for(y=0;y<m;++y)S=y/m*2*Math.PI,U[y]=p*Math.cos(S),j[y]=Math.sin(S),G[y]=p*Math.cos(S-.01),V[y]=Math.sin(S-.01),$[y]=p*Math.cos(S+.01),H[y]=Math.sin(S+.01);for(v=0;v<d;++v)for(x=(b=3*v)*m,e&&(Vb.set(n[b],n[b+1],n[b+2]),L=i[b],R=i[b+1],O=i[b+2],D=r[b],N=r[b+1],k=r[b+2],B=e[b],F=e[b+1],z=e[b+2],I=a[v]),y=0;y<m;++y)_=x+3*y,e&&(A=-I*U[y],M=I*j[y],P=-I*G[y],T=I*V[y],E=-I*$[y],C=I*H[y],c[_]=B+A*L+M*D,c[_+1]=F+A*R+M*N,c[_+2]=z+A*O+M*k,$b.set(E*L+C*D-(P*L+T*D),E*R+C*N-(P*R+T*N),E*O+C*k-(P*O+T*k)).cross(Vb),h[_]=$b.x,h[_+1]=$b.y,h[_+2]=$b.z),o&&(u[_]=o[b],u[_+1]=o[b+1],u[_+2]=o[b+2]),s&&(l[v*m+y]=s[v]);for(b=0,x=3*d*m,y=0;y<m;++y)_=b+3*y,w=x+3*y,e&&(c[w]=c[_],c[w+1]=c[_+1],c[w+2]=c[_+2],h[w]=n[b],h[w+1]=n[b+1],h[w+2]=n[b+2]),o&&(u[w]=u[_],u[w+1]=u[_+1],u[w+2]=u[_+2]),s&&(l[d*m+y]=l[0+y]);for(b=3*(d-1)*m,x=3*(d+1)*m,y=0;y<m;++y)_=b+3*y,w=x+3*y,e&&(c[w]=c[_],c[w+1]=c[_+1],c[w+2]=c[_+2],h[w]=n[3*f],h[w+1]=n[3*f+1],h[w+2]=n[3*f+2]),o&&(u[w]=u[_],u[w+1]=u[_+1],u[w+2]=u[_+2]),s&&(l[(d+1)*m+y]=l[(d-1)*m+y])},e.prototype.makeIndex=function(){var t,e,i,r,n,o,a=this.meshIndex,s=this.size2,c=s-1,u=this.capTriangles,h=this.radialSegments,l=this.radialSegments+1;for(t=0;t<c;++t)for(e=t*h*3*2,i=t*h,r=(t+1)*h,o=0;o<h;++o)a[n=e+3*o*2]=i+o,a[n+1]=i+(o+1)%h,a[n+2]=r+o,a[n+3]=r+o,a[n+4]=i+(o+1)%h,a[n+5]=r+(o+1)%h;var p=[0];for(o=1;o<l/2;++o)p.push(o),h-o!==o&&p.push(h-o);for(n=c*h*3*2,e=s*h,o=0;o<p.length-2;++o)o%2==0?(a[n+3*o+0]=e+p[o+0],a[n+3*o+1]=e+p[o+1],a[n+3*o+2]=e+p[o+2]):(a[n+3*o+0]=e+p[o+2],a[n+3*o+1]=e+p[o+1],a[n+3*o+2]=e+p[o+0]);for(n=c*h*3*2+3*u,e=s*h+h,o=0;o<p.length-2;++o)o%2==0?(a[n+3*o+0]=e+p[o+0],a[n+3*o+1]=e+p[o+1],a[n+3*o+2]=e+p[o+2]):(a[n+3*o+0]=e+p[o+2],a[n+3*o+1]=e+p[o+1],a[n+3*o+2]=e+p[o+0])},e}(Ov),Wb=function(e){function i(t,i,r){e.call(this,t,i,r),this.type="cartoon",this.parameters=Object.assign({aspectRatio:{type:"number",precision:1,max:10,min:1},subdiv:{type:"integer",max:50,min:1,rebuild:!0},radialSegments:{type:"integer",max:50,min:1,rebuild:!0},tension:{type:"number",precision:1,max:1,min:.1},capped:{type:"boolean",rebuild:!0},smoothSheet:{type:"boolean",rebuild:!0}},this.parameters),this.init(r)}return e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i,i.prototype.init=function(t){var i=t||{};i.colorScheme=dn(i.colorScheme,"chainname"),i.colorScale=dn(i.colorScale,"RdYlBu"),i.radius=dn(i.radius,"sstruc"),i.scale=dn(i.scale,.7),this.aspectRatio=dn(i.aspectRatio,5),this.tension=dn(i.tension,NaN),this.capped=dn(i.capped,!0),this.smoothSheet=dn(i.smoothSheet,!1),"low"===i.quality?(this.subdiv=3,this.radialSegments=6):"medium"===i.quality?this.subdiv=6:"high"===i.quality?this.subdiv=12:this.subdiv=dn(i.subdiv,6),e.prototype.init.call(this,i)},i.prototype.getSplineParams=function(t){return Object.assign({subdiv:this.subdiv,tension:this.tension,directional:1!==this.aspectRatio,smoothSheet:this.smoothSheet},t)},i.prototype.getSpline=function(t){return new ks(t,this.getSplineParams())},i.prototype.getScale=function(t){return t.isCg()?this.scale*this.aspectRatio:this.scale},i.prototype.getAspectRatio=function(t){return t.isCg()?1:this.aspectRatio},i.prototype.createData=function(t){var e=this,i=[],r=[];return this.structure.eachPolymer(function(t){if(!(t.residueCount<4)){r.push(t);var n=e.getSpline(t),o=n.getSubdividedPosition(),a=n.getSubdividedOrientation(),s=n.getSubdividedColor(e.getColorParams()),c=n.getSubdividedPicking(),u=n.getSubdividedSize(e.radius,e.getScale(t));i.push(new Hb(Object.assign({},o,a,s,c,u),e.getBufferParams({radialSegments:e.radialSegments,aspectRatio:e.getAspectRatio(t),capped:e.capped,dullInterior:!0})))}},t.getSelection()),{bufferList:i,polymerList:r}},i.prototype.updateData=function(e,i){var r=this;t.Debug&&cf.time(this.type+" repr update"),e=e||{};for(var n=0,o=i.polymerList.length;n<o;++n){var a={},s=i.polymerList[n],c=r.getSpline(s);if(i.bufferList[n].aspectRatio=r.getAspectRatio(s),e.position||e.radius){var u=c.getSubdividedPosition(),h=c.getSubdividedOrientation(),l=c.getSubdividedSize(r.radius,r.getScale(s));a.position=u.position,a.normal=h.normal,a.binormal=h.binormal,a.tangent=h.tangent,a.size=l.size}if(e.color){var p=c.getSubdividedColor(r.getColorParams());a.color=p.color}if(e.picking){var d=c.getSubdividedPicking();a.picking=d.picking}i.bufferList[n].setAttributes(a)}t.Debug&&cf.timeEnd(this.type+" repr update")},i.prototype.setParameters=function(t){var i={};return t&&t.aspectRatio&&(i.radius=!0),t&&t.tension&&(i.position=!0),e.prototype.setParameters.call(this,t,i,!1),this},i}(ky);df.add("cartoon",Wb);var Xb=function(t,e){this.sview1=t,this.sview2=e,this.kdtree2=new ts(e)};Xb.prototype.within=function(t,e){cf.time("Contact within");var i=this.kdtree2,r=this.sview1.getAtomProxy(),n=this.sview1.getAtomSet(!1),o=new Yg;this.sview1.eachAtom(function(a){for(var s=!1,c=i.nearest(a,1/0,t),u=0,h=c.length;u<h;++u){var l=c[u];r.index=l.index,a.residueIndex!==r.residueIndex&&(!e||l.distance>e)&&(s=!0,n.set(r.index),o.addBond(a,r,1))}s&&n.set(a.index)});var a=new og(o.count,!0);return cf.timeEnd("Contact within"),{atomSet:n,bondSet:a,bondStore:o}};var qb=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="contact",this.parameters=Object.assign({contactType:{type:"select",rebuild:!0,options:{polar:"polar",polarBackbone:"polar backbone"}},maxDistance:{type:"number",precision:1,max:10,min:.1,rebuild:!0},maxAngle:{type:"integer",max:180,min:0,rebuild:!0},radialSegments:!0,disableImpostor:!0},this.parameters),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.radius=dn(i.radius,.25),this.contactType=dn(i.contactType,"polarBackbone"),this.maxDistance=dn(i.maxDistance,3.5),this.maxAngle=dn(i.maxAngle,40),t.prototype.init.call(this,i)},e.prototype.getContactData=function(t){return{polar:Bs,polarBackbone:Fs}[this.contactType](t,this.maxDistance,this.maxAngle)},e.prototype.getBondData=function(t,e,i){var r=t.getBondData(this.getBondParams(e,i));return r.picking&&(r.picking=new Xm(r.picking.array,r.picking.structure,i.bondStore)),r},e.prototype.createData=function(t){var e=this.getContactData(t);return{bufferList:[new oy(this.getBondData(t,void 0,{bondSet:e.bondSet,bondStore:e.bondStore}),this.getBufferParams({openEnded:!1,radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,dullInterior:!0}))],bondSet:e.bondSet,bondStore:e.bondStore}},e.prototype.updateData=function(t,e){if(!t||t.position){var i=this.getContactData(e.sview);e.bondSet=i.bondSet,e.bondStore=i.bondStore}var r={bondSet:e.bondSet,bondStore:e.bondStore},n=this.getBondData(e.sview,t,r),o={};t&&!t.position||(o.position=Mo(n.position1,n.position2),o.position1=n.position1,o.position2=n.position2),t&&!t.color||(o.color=n.color1,o.color2=n.color2),t&&!t.radius||(o.radius=n.radius),e.bufferList[0].setAttributes(o)},e}(ky);df.add("contact",qb);var Yb=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="distance",this.parameters=Object.assign({labelSize:{type:"number",precision:3,max:10,min:.001},labelColor:{type:"color"},labelVisible:{type:"boolean"},labelZOffset:{type:"number",precision:1,max:20,min:-20,buffer:"zOffset"},labelUnit:{type:"select",rebuild:!0,options:{"":"",angstrom:"angstrom",nm:"nm"}},atomPair:{type:"hidden",rebuild:!0},radialSegments:!0,disableImpostor:!0},this.parameters,{flatShaded:null,assembly:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.radius=dn(i.radius,.15),this.fontFamily=dn(i.fontFamily,"sans-serif"),this.fontStyle=dn(i.fontStyle,"normal"),this.fontWeight=dn(i.fontWeight,"bold"),this.sdf=dn(i.sdf,"Firefox"!==nf),this.labelSize=dn(i.labelSize,2),this.labelColor=dn(i.labelColor,16777215),this.labelVisible=dn(i.labelVisible,!0),this.labelZOffset=dn(i.labelZOffset,.5),this.labelUnit=dn(i.labelUnit,""),this.atomPair=dn(i.atomPair,[]),t.prototype.init.call(this,i)},e.prototype.getDistanceData=function(t,e){var i=e.length,r=new Array(i),n=new Float32Array(3*i),o=new Kd,a=new Kd,s=new Yg,c=t.getAtomProxy(),u=t.getAtomProxy(),h=0;e.forEach(function(e,i){var l=e[0],p=e[1];if(Number.isInteger(l)&&Number.isInteger(p))c.index=l,u.index=p;else{o.setString(l),a.setString(p);var d=t.getAtomIndices(o),f=t.getAtomIndices(a);if(!d.length||!f.length)return void(h+=1);c.index=d[0],u.index=f[0]}s.addBond(c,u,1),i-=h;var m=c.distanceTo(u);switch(this.labelUnit){case"angstrom":r[i]=m.toFixed(2)+" "+String.fromCharCode(8491);break;case"nm":r[i]=(m/10).toFixed(2)+" nm";break;default:r[i]=m.toFixed(2)}var g=3*i;n[g+0]=(c.x+u.x)/2,n[g+1]=(c.y+u.y)/2,n[g+2]=(c.z+u.z)/2},this),h>0&&(i-=h,n=n.subarray(0,3*i));var l=new og(s.count,!0);return{text:r,position:n,bondSet:l,bondStore:s}},e.prototype.getBondData=function(t,e,i){var r=t.getBondData(this.getBondParams(e,i));return r.picking&&(r.picking=new Zm(r.picking.array,r.picking.structure,i.bondStore)),r},e.prototype.create=function(){if(0!==this.structureView.atomCount){var t=this.atomPair.length;if(0!==t){var e=this.getDistanceData(this.structureView,this.atomPair),i=new tt(this.labelColor);this.textBuffer=new vy({position:e.position,size:Po(t,this.labelSize),color:To(t,i.r,i.g,i.b),text:e.text},this.getBufferParams({fontFamily:this.fontFamily,fontStyle:this.fontStyle,fontWeight:this.fontWeight,sdf:this.sdf,zOffset:this.labelZOffset,opacity:1,visible:this.labelVisible}));var r={bondSet:e.bondSet,bondStore:e.bondStore},n=this.getBondData(this.structureView,void 0,r);this.cylinderBuffer=new oy(n,this.getBufferParams({openEnded:!1,radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,dullInterior:!0})),this.dataList.push({sview:this.structureView,bondSet:e.bondSet,bondStore:e.bondStore,position:e.position,bufferList:[this.textBuffer,this.cylinderBuffer]})}}},e.prototype.update=function(e){e.position?this.build():t.prototype.update.call(this,e)},e.prototype.updateData=function(t,e){var i={bondSet:e.bondSet,bondStore:e.bondStore},r=this.getBondData(e.sview,t,i),n={},o={},a=this.atomPair.length;if(t.labelSize&&(o.size=Po(a,this.labelSize)),t.labelColor){var s=new tt(this.labelColor);o.color=To(a,s.r,s.g,s.b)}t.color&&(n.color=r.color,n.color2=r.color2),(t.radius||t.scale)&&(n.radius=r.radius),this.textBuffer.setAttributes(o),this.cylinderBuffer.setAttributes(n)},e.prototype.setVisibility=function(e,i){return t.prototype.setVisibility.call(this,e,!0),this.textBuffer&&this.textBuffer.setVisibility(this.labelVisible&&this.visible),i||this.viewer.requestRender(),this},e.prototype.setParameters=function(e){var i={};return e&&e.labelSize&&(i.labelSize=!0),e&&(e.labelColor||0===e.labelColor)&&(i.labelColor=!0),t.prototype.setParameters.call(this,e,i,!1),e&&void 0!==e.labelVisible&&this.setVisibility(this.visible),this},e}(ky);df.add("distance",Yb);var Zb=function(t){function e(e,i){var r=i||{},n=2*(e.position.length/3),o=new tt(dn(r.color,"grey")),a=new Float32Array(3*n),s=To(n,o.r,o.g,o.b);t.call(this,{position:a,color:s},r),this.scale=dn(r.scale,1),this.setAttributes(e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={isLine:{},vertexShader:{},fragmentShader:{}};return e.prototype.setAttributes=function(t){var e,i,r,n=this.geometry.attributes;t.position&&t.vector&&(e=t.position,i=t.vector,r=n.position.array,n.position.needsUpdate=!0);var o,a,s=this.size/2,c=this.scale;if(t.position&&t.vector)for(var u=0;u<s;u++)a=3*u,r[(o=2*u*3)+0]=e[a+0],r[o+1]=e[a+1],r[o+2]=e[a+2],r[o+3]=e[a+0]+i[a+0]*c,r[o+4]=e[a+1]+i[a+1]*c,r[o+5]=e[a+2]+i[a+2]*c},i.isLine.get=function(){return!0},i.vertexShader.get=function(){return"Line.vert"},i.fragmentShader.get=function(){return"Line.frag"},Object.defineProperties(e.prototype,i),e}(Lv),Kb=function(e){function i(t,i,r){e.call(this,t,i,r),this.type="helixorient",this.parameters=Object.assign({sphereDetail:!0,disableImpostor:!0},this.parameters),this.init(r)}return e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i,i.prototype.init=function(t){var i=t||{};i.colorScheme=dn(i.colorScheme,"sstruc"),i.radius=dn(i.radius,.15),i.scale=dn(i.scale,1),e.prototype.init.call(this,i)},i.prototype.createData=function(t){var e=this,i=[],r=[];return this.structure.eachPolymer(function(t){if(!(t.residueCount<4)){r.push(t);var n=new Za(t),o=n.getPosition(),a=n.getColor(e.getColorParams()),s=n.getSize(e.radius,e.scale),c=n.getPicking();i.push(new $v({position:o.center,color:a.color,radius:s.size,picking:c.picking},e.getBufferParams({sphereDetail:e.sphereDetail,disableImpostor:e.disableImpostor,dullInterior:!0})),new Zb({position:o.center,vector:o.axis},e.getBufferParams({color:"skyblue",scale:1})),new Zb({position:o.center,vector:o.resdir},e.getBufferParams({color:"lightgreen",scale:1})))}},t.getSelection()),{bufferList:i,polymerList:r}},i.prototype.updateData=function(e,i){t.Debug&&cf.time(this.type+" repr update"),e=e||{};for(var r=0,n=i.polymerList.length;r<n;++r){var o=3*r,a={},s=new Za(i.polymerList[r]);if(e.position){var c=s.getPosition();a.position=c.center,i.bufferList[o+1].setAttributes({position:c.center,vector:c.axis}),i.bufferList[o+2].setAttributes({position:c.center,vector:c.resdir})}i.bufferList[o].setAttributes(a)}t.Debug&&cf.timeEnd(this.type+" repr update")},i}(ky);df.add("helixorient",Kb);var Qb=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="licorice",this.parameters=Object.assign({},this.parameters,{aspectRatio:null})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.aspectRatio=1,t.prototype.init.call(this,i)},e}(Ub);df.add("licorice",Qb),mf.add("shader/HyperballStickImpostor.vert","\nattribute vec3 mapping;\nattribute float radius;\nattribute float radius2;\nattribute vec3 position1;\nattribute vec3 position2;\nvarying mat4 matrix_near;\nvarying vec4 prime1;\nvarying vec4 prime2;\nvarying float vRadius;\nvarying float vRadius2;\n#ifdef PICKING\n#include unpack_color\nattribute float primitiveId;\nvarying vec3 vPickingColor;\n#else\nattribute vec3 color2;\nvarying vec3 vColor1;\nvarying vec3 vColor2;\n#endif\nuniform float shrink;\nuniform mat4 modelViewProjectionMatrix;\nuniform mat4 modelViewProjectionMatrixInverse;\nvoid main(){\nvRadius = radius;\nvRadius2 = radius2;\nvec4 spaceposition;\nvec3 position_atom1;\nvec3 position_atom2;\nvec4 vertex_position;\n#ifdef PICKING\nvPickingColor = unpackColor( primitiveId );\n#else\nvColor1 = color;\nvColor2 = color2;\n#endif\nfloat radius1 = radius;\nposition_atom1 = position1;\nposition_atom2 = position2;\nfloat distance = distance( position_atom1, position_atom2 );\nspaceposition.z = mapping.z * distance;\nif (radius1 > radius2) {\nspaceposition.y = mapping.y * 1.5 * radius1;\nspaceposition.x = mapping.x * 1.5 * radius1;\n} else {\nspaceposition.y = mapping.y * 1.5 * radius2;\nspaceposition.x = mapping.x * 1.5 * radius2;\n}\nspaceposition.w = 1.0;\nvec4 e3 = vec4( 1.0 );\nvec3 e1, e1_temp, e2, e2_temp;\ne3.xyz = normalize(position_atom1-position_atom2);\nif (e3.z == 0.0) { e3.z = 0.0000000000001;}\nif ( (position_atom1.x - position_atom2.x) == 0.0) { position_atom1.x += 0.001;}\nif ( (position_atom1.y - position_atom2.y) == 0.0) { position_atom1.y += 0.001;}\nif ( (position_atom1.z - position_atom2.z) == 0.0) { position_atom1.z += 0.001;}\nvec4 focus = vec4( 1.0 );\nfocus.x = ( position_atom1.x*position_atom1.x - position_atom2.x*position_atom2.x +\n( radius2*radius2 - radius1*radius1 )*e3.x*e3.x/shrink )/(2.0*(position_atom1.x - position_atom2.x));\nfocus.y = ( position_atom1.y*position_atom1.y - position_atom2.y*position_atom2.y +\n( radius2*radius2 - radius1*radius1 )*e3.y*e3.y/shrink )/(2.0*(position_atom1.y - position_atom2.y));\nfocus.z = ( position_atom1.z*position_atom1.z - position_atom2.z*position_atom2.z +\n( radius2*radius2 - radius1*radius1 )*e3.z*e3.z/shrink )/(2.0*(position_atom1.z - position_atom2.z));\ne1.x = 1.0;\ne1.y = 1.0;\ne1.z = ( (e3.x*focus.x + e3.y*focus.y + e3.z*focus.z) - e1.x*e3.x - e1.y*e3.y)/e3.z;\ne1_temp = e1 - focus.xyz;\ne1 = normalize(e1_temp);\ne2_temp = e1.yzx * e3.zxy - e1.zxy * e3.yzx;\ne2 = normalize(e2_temp);\nmat3 R= mat3( e1.xyz, e2.xyz, e3.xyz );\nvertex_position.xyz = R * spaceposition.xyz;\nvertex_position.w = 1.0;\nvertex_position.x += (position_atom1.x+position_atom2.x) / 2.0;\nvertex_position.y += (position_atom1.y+position_atom2.y) / 2.0;\nvertex_position.z += (position_atom1.z+position_atom2.z) / 2.0;\ngl_Position = modelViewProjectionMatrix * vertex_position;\nvec4 i_near, i_far;\nvec4 near = gl_Position;\nnear.z = 0.0 ;\nnear = modelViewProjectionMatrixInverse * near;\ni_near = near;\nvec4 far = gl_Position;\nfar.z = far.w ;\ni_far = modelViewProjectionMatrixInverse * far;\nprime1 = vec4( position_atom1 - (position_atom1 - focus.xyz)*shrink, 1.0 );\nprime2 = vec4( position_atom2 - (position_atom2 - focus.xyz)*shrink, 1.0 );\nfloat Rsquare = (radius1*radius1/shrink) - (\n(position_atom1.x - focus.x)*(position_atom1.x - focus.x) +\n(position_atom1.y - focus.y)*(position_atom1.y - focus.y) +\n(position_atom1.z - focus.z)*(position_atom1.z - focus.z)\n);\nfocus.w = Rsquare;\nmatrix_near = mat4( i_near, i_far, focus, e3 );\ngl_Position.z = 1.0;\n}"),mf.add("shader/HyperballStickImpostor.frag","#define STANDARD\n#define IMPOSTOR\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\nuniform float nearClip;\nuniform float shrink;\nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewProjectionMatrix;\nuniform mat4 modelViewMatrixInverseTranspose;\nuniform mat4 projectionMatrix;\nvarying mat4 matrix_near;\nvarying vec4 prime1;\nvarying vec4 prime2;\nvarying float vRadius;\nvarying float vRadius2;\n#ifdef PICKING\nuniform float objectId;\nvarying vec3 vPickingColor;\n#else\nvarying vec3 vColor1;\nvarying vec3 vColor2;\n#include common\n#include fog_pars_fragment\n#include bsdfs\n#include lights_pars\n#include lights_physical_pars_fragment\n#endif\nbool interior = false;\nfloat calcClip( vec4 cameraPos ){\nreturn dot( cameraPos, vec4( 0.0, 0.0, 1.0, nearClip - 0.5 ) );\n}\nfloat calcClip( vec3 cameraPos ){\nreturn calcClip( vec4( cameraPos, 1.0 ) );\n}\nfloat calcDepth( in vec3 cameraPos ){\nvec2 clipZW = cameraPos.z * projectionMatrix[2].zw + projectionMatrix[3].zw;\nreturn 0.5 + 0.5 * clipZW.x / clipZW.y;\n}\nstruct Ray {\nvec3 origin ;\nvec3 direction ;\n};\nbool cutoff_plane (vec3 M, vec3 cutoff, vec3 x3){\nfloat a = x3.x;\nfloat b = x3.y;\nfloat c = x3.z;\nfloat d = -x3.x*cutoff.x-x3.y*cutoff.y-x3.z*cutoff.z;\nfloat l = a*M.x+b*M.y+c*M.z+d;\nif (l<0.0) {return true;}\nelse{return false;}\n}\nvec3 isect_surf(Ray r, mat4 matrix_coef){\nvec4 direction = vec4(r.direction, 0.0);\nvec4 origin = vec4(r.origin, 1.0);\nfloat a = dot(direction,(matrix_coef*direction));\nfloat b = dot(origin,(matrix_coef*direction));\nfloat c = dot(origin,(matrix_coef*origin));\nfloat delta =b*b-a*c;\ngl_FragColor.a = 1.0;\nif (delta<0.0){\ndiscard;\n}\nfloat t1 =(-b-sqrt(delta))/a;\nreturn r.origin+t1*r.direction;\n}\nvec3 isect_surf2(Ray r, mat4 matrix_coef){\nvec4 direction = vec4(r.direction, 0.0);\nvec4 origin = vec4(r.origin, 1.0);\nfloat a = dot(direction,(matrix_coef*direction));\nfloat b = dot(origin,(matrix_coef*direction));\nfloat c = dot(origin,(matrix_coef*origin));\nfloat delta =b*b-a*c;\ngl_FragColor.a = 1.0;\nif (delta<0.0){\ndiscard;\n}\nfloat t2 =(-b+sqrt(delta))/a;\nreturn r.origin+t2*r.direction;\n}\nRay primary_ray(vec4 near1, vec4 far1){\nvec3 near=near1.xyz/near1.w;\nvec3 far=far1.xyz/far1.w;\nreturn Ray(near,far-near);\n}\nfloat update_z_buffer(vec3 M, mat4 ModelViewP){\nfloat depth1;\nvec4 Ms=(ModelViewP*vec4(M,1.0));\nreturn depth1=(1.0+Ms.z/Ms.w)/2.0;\n}\nvoid main(){\nfloat radius = max( vRadius, vRadius2 );\nvec4 i_near, i_far, focus;\nvec3 e3, e1, e1_temp, e2;\ni_near = vec4(matrix_near[0][0],matrix_near[0][1],matrix_near[0][2],matrix_near[0][3]);\ni_far = vec4(matrix_near[1][0],matrix_near[1][1],matrix_near[1][2],matrix_near[1][3]);\nfocus = vec4(matrix_near[2][0],matrix_near[2][1],matrix_near[2][2],matrix_near[2][3]);\ne3 = vec3(matrix_near[3][0],matrix_near[3][1],matrix_near[3][2]);\ne1.x = 1.0;\ne1.y = 1.0;\ne1.z = ( (e3.x*focus.x + e3.y*focus.y + e3.z*focus.z) - e1.x*e3.x - e1.y*e3.y)/e3.z;\ne1_temp = e1 - focus.xyz;\ne1 = normalize(e1_temp);\ne2 = normalize(cross(e1,e3));\nvec4 equation = focus;\nfloat shrinkfactor = shrink;\nfloat t1 = -1.0/(1.0-shrinkfactor);\nfloat t2 = 1.0/(shrinkfactor);\nvec4 colonne1, colonne2, colonne3, colonne4;\nmat4 mat;\nvec3 equation1 = vec3(t2,t2,t1);\nfloat A1 = - e1.x*equation.x - e1.y*equation.y - e1.z*equation.z;\nfloat A2 = - e2.x*equation.x - e2.y*equation.y - e2.z*equation.z;\nfloat A3 = - e3.x*equation.x - e3.y*equation.y - e3.z*equation.z;\nfloat A11 = equation1.x*e1.x*e1.x + equation1.y*e2.x*e2.x + equation1.z*e3.x*e3.x;\nfloat A21 = equation1.x*e1.x*e1.y + equation1.y*e2.x*e2.y + equation1.z*e3.x*e3.y;\nfloat A31 = equation1.x*e1.x*e1.z + equation1.y*e2.x*e2.z + equation1.z*e3.x*e3.z;\nfloat A41 = equation1.x*e1.x*A1 + equation1.y*e2.x*A2 + equation1.z*e3.x*A3;\nfloat A22 = equation1.x*e1.y*e1.y + equation1.y*e2.y*e2.y + equation1.z*e3.y*e3.y;\nfloat A32 = equation1.x*e1.y*e1.z + equation1.y*e2.y*e2.z + equation1.z*e3.y*e3.z;\nfloat A42 = equation1.x*e1.y*A1 + equation1.y*e2.y*A2 + equation1.z*e3.y*A3;\nfloat A33 = equation1.x*e1.z*e1.z + equation1.y*e2.z*e2.z + equation1.z*e3.z*e3.z;\nfloat A43 = equation1.x*e1.z*A1 + equation1.y*e2.z*A2 + equation1.z*e3.z*A3;\nfloat A44 = equation1.x*A1*A1 + equation1.y*A2*A2 + equation1.z*A3*A3 - equation.w;\ncolonne1 = vec4(A11,A21,A31,A41);\ncolonne2 = vec4(A21,A22,A32,A42);\ncolonne3 = vec4(A31,A32,A33,A43);\ncolonne4 = vec4(A41,A42,A43,A44);\nmat = mat4(colonne1,colonne2,colonne3,colonne4);\nRay ray = primary_ray(i_near,i_far) ;\nvec3 M;\nM = isect_surf(ray, mat);\nif (cutoff_plane(M, prime1.xyz, -e3) || cutoff_plane(M, prime2.xyz, e3)){ discard; }\nvec4 M1 = vec4(M,1.0);\nvec4 M2 = mat*M1;\nvec3 _normal = ( modelViewMatrixInverseTranspose * M2 ).xyz;\ngl_FragDepthEXT = update_z_buffer(M, modelViewProjectionMatrix) ;\n#ifdef NEAR_CLIP\nif( calcClip( modelViewMatrix * vec4( M, 1.0 ) ) > 0.0 ){\nM = isect_surf2(ray, mat);\nif( calcClip( modelViewMatrix * vec4( M, 1.0 ) ) > 0.0 )\ndiscard;\ninterior = true;\ngl_FragDepthEXT = update_z_buffer(M, modelViewProjectionMatrix) ;\nif( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = max( 0.0, calcDepth( vec3( - ( nearClip - 0.5 ) ) ) + ( 0.0000001 / radius ) );\n}\n}else if( gl_FragDepthEXT <= 0.0 ){\nM = isect_surf2(ray, mat);\ninterior = true;\ngl_FragDepthEXT = update_z_buffer(M, modelViewProjectionMatrix);\nif( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = 0.0 + ( 0.0000001 / radius );\n}\n}\n#else\nif( gl_FragDepthEXT <= 0.0 ){\nM = isect_surf2(ray, mat);\ninterior = true;\ngl_FragDepthEXT = update_z_buffer(M, modelViewProjectionMatrix) ;\nif( gl_FragDepthEXT >= 0.0 ){\ngl_FragDepthEXT = 0.0 + ( 0.0000001 / radius );\n}\n}\n#endif\nif (cutoff_plane(M, prime1.xyz, -e3) || cutoff_plane(M, prime2.xyz, e3)){ discard; }\nif (gl_FragDepthEXT < 0.0)\ndiscard;\nif (gl_FragDepthEXT > 1.0)\ndiscard;\nfloat distance_ratio = ((M.x-prime2.x)*e3.x + (M.y-prime2.y)*e3.y +(M.z-prime2.z)*e3.z) /\ndistance(prime2.xyz,prime1.xyz);\n#ifdef PICKING\ngl_FragColor = vec4( vPickingColor, objectId );\n#else\nvec3 vViewPosition = -( modelViewMatrix * vec4( M, 1.0 ) ).xyz;\nvec3 vNormal = _normal;\nvec3 vColor;\nif( distance_ratio>0.5 ){\nvColor = vColor1;\n}else{\nvColor = vColor2;\n}\nvec4 diffuseColor = vec4( diffuse, opacity );\nReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\nvec3 totalEmissiveLight = emissive;\n#include color_fragment\n#include roughnessmap_fragment\n#include metalnessmap_fragment\nvec3 normal = normalize( vNormal );\nif( interior ){\nnormal = vec3( 0.0, 0.0, 0.4 );\n}\n#include lights_physical_fragment\n#include lights_template\nvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );\n#include premultiplied_alpha_fragment\n#include tonemapping_fragment\n#include encodings_fragment\n#include fog_fragment\n#endif\n}");var Jb=new Float32Array([-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,1,1,-1,1,1,1,-1,1,1]),tx=new Uint16Array([0,1,2,0,2,3,1,5,6,1,6,2,4,6,5,4,7,6,0,7,4,0,3,7,0,5,1,0,4,5,3,2,6,3,6,7]),ex=function(t){function e(e,i){t.call(this,e,i);var r=e||{},n=dn((i||{}).shrink,.14);this.addUniforms({modelViewProjectionMatrix:{value:new v},modelViewProjectionMatrixInverse:{value:new v},modelViewMatrixInverseTranspose:{value:new v},shrink:{value:n}}),this.addAttributes({position1:{type:"v3",value:null},position2:{type:"v3",value:null},color2:{type:"c",value:null},radius:{type:"f",value:null},radius2:{type:"f",value:null}}),this.setAttributes(r),this.makeMapping()}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={parameters:{},isImpostor:{},vertexShader:{},fragmentShader:{}};return i.parameters.get=function(){return Object.assign.call(this,{shrink:{uniform:!0}},t.prototype.parameters)},i.isImpostor.get=function(){return!0},i.vertexShader.get=function(){return"HyperballStickImpostor.vert"},i.fragmentShader.get=function(){return"HyperballStickImpostor.frag"},Object.defineProperties(e.prototype,i),e}(function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={mapping:{},mappingIndices:{},mappingIndicesSize:{},mappingType:{},mappingSize:{},mappingItemSize:{}};return i.mapping.get=function(){return Jb},i.mappingIndices.get=function(){return tx},i.mappingIndicesSize.get=function(){return 36},i.mappingType.get=function(){return"v3"},i.mappingSize.get=function(){return 8},i.mappingItemSize.get=function(){return 3},Object.defineProperties(e.prototype,i),e}(zv)),ix=function(t,e){return!sf||e&&e.disableImpostor?(t.radius=Lo(t.radius1,t.radius2),new ey(t,e)):new ex(t,e)},rx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="hyperball",this.parameters=Object.assign({shrink:{type:"number",precision:3,max:1,min:.001,buffer:!0}},this.parameters,{multipleBond:null,bondSpacing:null})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.scale=dn(i.scale,.2),i.radius=dn(i.radius,"vdw"),this.shrink=dn(i.shrink,.12),t.prototype.init.call(this,i)},e.prototype.getBondParams=function(e,i){return e&&!e.radius||(i=Object.assign({radius2:!0},i)),t.prototype.getBondParams.call(this,e,i)},e.prototype.createData=function(t){var e=new $v(t.getAtomData(this.getAtomParams()),this.getBufferParams({sphereDetail:this.sphereDetail,disableImpostor:this.disableImpostor,dullInterior:!0}));return this.__center=new Float32Array(3*t.bondCount),{bufferList:[e,new ix(t.getBondData(this.getBondParams()),this.getBufferParams({shrink:this.shrink,radialSegments:this.radialSegments,dullInterior:!0}))]}},e.prototype.updateData=function(t,e){var i=e.sview.getAtomData(this.getAtomParams()),r=e.sview.getBondData(this.getBondParams()),n={},o={};if(!t||t.position){n.position=i.position;var a=r.position1,s=r.position2;o.position=Mo(a,s,this.__center),o.position1=a,o.position2=s}t&&!t.color||(n.color=i.color,o.color=r.color1,o.color2=r.color2),t&&!t.radius||(n.radius=i.radius,o.radius=r.radius1,o.radius2=r.radius2),e.bufferList[0].setAttributes(n),e.bufferList[1].setAttributes(o)},e}(Qb);df.add("hyperball",rx),zs.prototype={constructor:zs,atomLabel:function(t){var e;switch(this.type){case"atomname":e=t.atomname;break;case"atomindex":e=""+t.index;break;case"occupancy":e=t.occupancy.toFixed(2);break;case"bfactor":e=t.bfactor.toFixed(2);break;case"serial":e=""+t.serial;break;case"element":e=t.element;break;case"atom":e=t.atomname+"|"+t.index;break;case"resname":e=t.resname;break;case"resno":e=""+t.resno;break;case"res":var i=t.resname.toUpperCase();e=(Mg[i]||i)+t.resno;break;case"text":e=this.text[t.index];break;default:e=t.qualifiedName()}return void 0===e?"":e}},zs.types={"":"",atomname:"atom name",atomindex:"atom index",occupancy:"occupancy",bfactor:"b-factor",serial:"serial",element:"element",atom:"atom name + index",resname:"residue name",resno:"residue no",res:"residue name + no",text:"text",qualified:"qualified name"};var nx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="label",this.parameters=Object.assign({labelType:{type:"select",options:zs.types,rebuild:!0},labelText:{type:"hidden",rebuild:!0},fontFamily:{type:"select",options:{"sans-serif":"sans-serif",monospace:"monospace",serif:"serif"},buffer:!0},fontStyle:{type:"select",options:{normal:"normal",italic:"italic"},buffer:!0},fontWeight:{type:"select",options:{normal:"normal",bold:"bold"},buffer:!0},sdf:{type:"boolean",buffer:!0},xOffset:{type:"number",precision:1,max:20,min:-20,buffer:!0},yOffset:{type:"number",precision:1,max:20,min:-20,buffer:!0},zOffset:{type:"number",precision:1,max:20,min:-20,buffer:!0},attachment:{type:"select",options:{"bottom-left":"bottom-left","bottom-center":"bottom-center","bottom-right":"bottom-right","middle-left":"middle-left","middle-center":"middle-center","middle-right":"middle-right","top-left":"top-left","top-center":"top-center","top-right":"top-right"},rebuild:!0},showBorder:{type:"boolean",buffer:!0},borderColor:{type:"color",buffer:!0},borderWidth:{type:"number",precision:2,max:.3,min:0,buffer:!0},showBackground:{type:"boolean",rebuild:!0},backgroundColor:{type:"color",buffer:!0},backgroundMargin:{type:"number",precision:2,max:2,min:0,rebuild:!0},backgroundOpacity:{type:"range",step:.01,max:1,min:0,buffer:!0}},this.parameters,{side:null,flatShaded:null,wireframe:null,linewidth:null,roughness:null,metalness:null,diffuse:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};this.labelType=dn(i.labelType,"res"),this.labelText=dn(i.labelText,{}),this.fontFamily=dn(i.fontFamily,"sans-serif"),this.fontStyle=dn(i.fontStyle,"normal"),this.fontWeight=dn(i.fontWeight,"bold"),this.sdf=dn(i.sdf,"Chrome"===nf),this.xOffset=dn(i.xOffset,0),this.yOffset=dn(i.yOffset,0),this.zOffset=dn(i.zOffset,.5),this.attachment=dn(i.attachment,"bottom-left"),this.showBorder=dn(i.showBorder,!1),this.borderColor=dn(i.borderColor,"lightgrey"),this.borderWidth=dn(i.borderWidth,.15),this.showBackground=dn(i.showBackground,!1),this.backgroundColor=dn(i.backgroundColor,"lightgrey"),this.backgroundMargin=dn(i.backgroundMargin,.5),this.backgroundOpacity=dn(i.backgroundOpacity,1),t.prototype.init.call(this,i)},e.prototype.createData=function(t){var e={position:!0,color:!0,radius:!0},i=t.getAtomData(this.getAtomParams(e)),r=[],n=new zs(this.labelType,this.labelText);return t.eachAtom(function(t){r.push(n.atomLabel(t))}),{bufferList:[new vy({position:i.position,size:i.radius,color:i.color,text:r},this.getBufferParams({fontFamily:this.fontFamily,fontStyle:this.fontStyle,fontWeight:this.fontWeight,sdf:this.sdf,xOffset:this.xOffset,yOffset:this.yOffset,zOffset:this.zOffset,attachment:this.attachment,showBorder:this.showBorder,borderColor:this.borderColor,borderWidth:this.borderWidth,showBackground:this.showBackground,backgroundColor:this.backgroundColor,backgroundMargin:this.backgroundMargin,backgroundOpacity:this.backgroundOpacity}))]}},e.prototype.updateData=function(t,e){var i=e.sview.getAtomData(this.getAtomParams(t)),r={};t&&!t.position||(r.position=i.position),t&&!t.radius||(r.size=i.radius),t&&!t.color||(r.color=i.color),e.bufferList[0].setAttributes(r)},e}(ky);df.add("label",nx);var ox=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="line",this.parameters=Object.assign({multipleBond:{type:"select",rebuild:!0,options:{off:"off",symmetric:"symmetric",offset:"offset"}},bondSpacing:{type:"number",precision:2,max:2,min:.5}},this.parameters,{flatShaded:null,side:null,wireframe:null,roughness:null,metalness:null,diffuse:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};this.multipleBond=dn(i.multipleBond,"off"),this.bondSpacing=dn(i.bondSpacing,1),t.prototype.init.call(this,i)},e.prototype.getBondParams=function(e,i){return i=Object.assign({multipleBond:this.multipleBond,bondSpacing:this.bondSpacing,radiusParams:{radius:.1,scale:1}},i),t.prototype.getBondParams.call(this,e,i)},e.prototype.createData=function(t){var e={position:!0,color:!0},i=t.getBondData(this.getBondParams(e));return{bufferList:[new By(i,this.getBufferParams())]}},e.prototype.updateData=function(t,e){var i=e.sview.getBondData(this.getBondParams(t)),r={};t&&!t.position||(r.position1=i.position1,r.position2=i.position2),t&&!t.color||(r.color=i.color,r.color2=i.color2),e.bufferList[0].setAttributes(r)},e.prototype.setParameters=function(e){var i={};return e&&e.bondSpacing&&(i.position=!0),t.prototype.setParameters.call(this,e,i,!1),this},e}(ky);df.add("line",ox),js.__deps=[qa,Xa,Ya,Qo,Us],Vs.__deps=[qa,Ya,Po,Qo,ca,ra,ua,Gs,dn],hf.add("molsurf",function(t,e){var i=t.data.args,r=t.data.params;if(i&&r){var n=new("av"===r.type?Vs:js)(i.coordList,i.radiusList,i.indexList).getSurface(r.type,r.probeRadius,r.scaleFactor,r.cutoff,!0,r.smooth,r.contour),o=[n.position.buffer,n.index.buffer];n.normal&&o.push(n.normal.buffer),n.atomindex&&o.push(n.atomindex.buffer),e({sd:n,p:r},o)}},[js,Vs]);var ax=function(t){this.structure=t};ax.prototype._getAtomData=function(){return this.structure.getAtomData({what:{position:!0,radius:!0,index:!0},radiusParams:{radius:"vdw",scale:1}})},ax.prototype._makeSurface=function(t,e){var i=new jg(e.name,"",t);return i.info.type=e.type,i.info.probeRadius=e.probeRadius,i.info.scaleFactor=e.scaleFactor,i.info.smooth=e.smooth,i.info.cutoff=e.cutoff,i},ax.prototype.getSurface=function(t){var e=t||{},i=this._getAtomData(),r=i.position,n=i.radius,o=i.index,a=new("av"===e.type?Vs:js)(r,n,o).getSurface(e.type,e.probeRadius,e.scaleFactor,e.cutoff,!0,e.smooth,e.contour);return this._makeSurface(a,e)},ax.prototype.getSurfaceWorker=function(t,e){var i=this,r=Object.assign({},t);if(window.Worker){void 0===this.worker&&(this.worker=new za("molsurf"));var n=this._getAtomData(),o=n.position,a=n.radius,s=n.index,c={args:{coordList:o,radiusList:a,indexList:s},params:r},u=[o.buffer,a.buffer,s.buffer];this.worker.post(c,u,function(t){e(i._makeSurface(t.data.sd,r))},function(t){console.warn("MolecularSurface.getSurfaceWorker error - trying without worker",t),i.worker.terminate(),i.worker=void 0;var n=i.getSurface(r);e(n)})}else{var h=this.getSurface(r);e(h)}},ax.prototype.dispose=function(){this.worker&&this.worker.terminate()};var sx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="surface",this.parameters=Object.assign({surfaceType:{type:"select",rebuild:!0,options:{vws:"vws",sas:"sas",ms:"ms",ses:"ses",av:"av"}},probeRadius:{type:"number",precision:1,max:20,min:0,rebuild:!0},smooth:{type:"integer",precision:1,max:10,min:0,rebuild:!0},scaleFactor:{type:"number",precision:1,max:5,min:0,rebuild:!0},cutoff:{type:"number",precision:2,max:50,min:0,rebuild:!0},contour:{type:"boolean",rebuild:!0},background:{type:"boolean",rebuild:!0},opaqueBack:{type:"boolean",buffer:!0},filterSele:{type:"text",rebuild:!0},colorVolume:{type:"hidden"},useWorker:{type:"boolean",rebuild:!0}},this.parameters,{radiusType:null,radius:null,scale:null}),this.__infoList=[],this.structure.signals.refreshed.add(function(){this.__forceNewMolsurf=!0},this),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"uniform"),i.colorValue=dn(i.colorValue,14540253),this.surfaceType=dn(i.surfaceType,"ms"),this.probeRadius=dn(i.probeRadius,1.4),this.smooth=dn(i.smooth,2),this.scaleFactor=dn(i.scaleFactor,2),this.cutoff=dn(i.cutoff,0),this.contour=dn(i.contour,!1),this.background=dn(i.background,!1),this.opaqueBack=dn(i.opaqueBack,!0),this.filterSele=dn(i.filterSele,""),this.colorVolume=dn(i.colorVolume,void 0),this.useWorker=dn(i.useWorker,!0),t.prototype.init.call(this,e)},e.prototype.prepareData=function(t,e,i){var r=this.__infoList[e];if(r||(r={},this.__infoList[e]=r),r.molsurf&&r.sele===t.selection.string)i(e);else{if(this.filterSele){var n=t.structure.getView(new Kd(this.filterSele)),o=n.boundingBox.getSize(),a=Math.max(o.x,o.y,o.z),s=t.getAtomSetWithinPoint(n.center,a/2+6);t=t.getView(new Kd(t.getAtomSetWithinSelection(s,3).toSeleString()))}r.sele=t.selection.string,r.molsurf=new ax(t);var c=this.getSurfaceParams(),u=function(t){r.surface=t,i(e)};this.useWorker?r.molsurf.getSurfaceWorker(c,u):u(r.molsurf.getSurface(c))}},e.prototype.prepare=function(t){var e=this;if((this.__forceNewMolsurf||this.__sele!==this.selection.string||this.__surfaceParams!==JSON.stringify(this.getSurfaceParams()))&&(this.__infoList.forEach(function(t){t.molsurf.dispose()}),this.__infoList.length=0),0===this.structureView.atomCount)return void t();var i=function(){this.__sele=this.selection.string,this.__surfaceParams=JSON.stringify(this.getSurfaceParams()),this.__forceNewMolsurf=!1,t()}.bind(this),r="default"===this.assembly?this.defaultAssembly:this.assembly,n=this.structure.biomolDict[r];n?n.partList.forEach(function(t,r){var o=t.getView(e.structureView);e.prepareData(o,r,function(t){t===n.partList.length-1&&i()})}):this.prepareData(this.structureView,0,i)},e.prototype.createData=function(t,e){var i=this.__infoList[e],r=i.surface,n={position:r.getPosition(),color:r.getColor(this.getColorParams()),index:r.getFilteredIndex(this.filterSele,t)},o=[];if(r.contour){var a=new Ty(n,this.getBufferParams({wireframe:!1}));o.push(a)}else{n.normal=r.getNormal(),n.picking=r.getPicking(t.getStructure());var s=new Ay(n,this.getBufferParams({background:this.background,opaqueBack:this.opaqueBack,dullInterior:!1})),c=new My(s);o.push(c)}return{bufferList:o,info:i}},e.prototype.updateData=function(t,e){var i={};if(t.position)return this.__forceNewMolsurf=!0,void this.build();t.color&&(i.color=e.info.surface.getColor(this.getColorParams())),t.index&&(i.index=e.info.surface.getFilteredIndex(this.filterSele,e.sview)),e.bufferList[0].setAttributes(i)},e.prototype.setParameters=function(e,i,r){return i=i||{},e&&e.filterSele&&(i.index=!0),e&&void 0!==e.colorVolume&&(i.color=!0),e&&e.wireframe&&(e.contour||void 0===e.contour&&this.contour)&&(e.wireframe=!1),t.prototype.setParameters.call(this,e,i,r),this},e.prototype.getSurfaceParams=function(t){return Object.assign({type:this.surfaceType,probeRadius:this.probeRadius,scaleFactor:this.scaleFactor,smooth:this.smooth&&!this.contour,cutoff:this.cutoff,contour:this.contour,useWorker:this.useWorker},t)},e.prototype.getColorParams=function(){var e=t.prototype.getColorParams.call(this);return e.volume=this.colorVolume,e},e.prototype.clear=function(){t.prototype.clear.call(this)},e.prototype.dispose=function(){this.__infoList.forEach(function(t){t.molsurf.dispose()}),this.__infoList.length=0,t.prototype.dispose.call(this)},e}(ky);df.add("surface",sx);var cx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="point",this.parameters=Object.assign({pointSize:{type:"number",precision:1,max:100,min:0,buffer:!0},sizeAttenuation:{type:"boolean",buffer:!0},sortParticles:{type:"boolean",rebuild:!0},useTexture:{type:"boolean",buffer:!0},alphaTest:{type:"range",step:.001,max:1,min:0,buffer:!0},forceTransparent:{type:"boolean",buffer:!0},edgeBleach:{type:"range",step:.001,max:1,min:0,buffer:!0}},this.parameters,{flatShaded:null,wireframe:null,linewidth:null,roughness:null,metalness:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};this.pointSize=dn(i.pointSize,1),this.sizeAttenuation=dn(i.sizeAttenuation,!0),this.sortParticles=dn(i.sortParticles,!1),this.useTexture=dn(i.useTexture,!1),this.alphaTest=dn(i.alphaTest,.5),this.forceTransparent=dn(i.forceTransparent,!1),this.edgeBleach=dn(i.edgeBleach,0),t.prototype.init.call(this,i)},e.prototype.createData=function(t){var e={position:!0,color:!0,picking:!0},i=t.getAtomData(this.getAtomParams(e));return{bufferList:[new Cy(i,this.getBufferParams({pointSize:this.pointSize,sizeAttenuation:this.sizeAttenuation,sortParticles:this.sortParticles,useTexture:this.useTexture,alphaTest:this.alphaTest,forceTransparent:this.forceTransparent,edgeBleach:this.edgeBleach}))]}},e.prototype.updateData=function(t,e){var i=e.sview.getAtomData(this.getAtomParams(t)),r={};t&&!t.position||(r.position=i.position),t&&!t.color||(r.color=i.color),e.bufferList[0].setAttributes(r)},e}(ky);df.add("point",cx),mf.add("shader/Ribbon.vert","#define STANDARD\nuniform float nearClip;\nuniform vec3 clipCenter;\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || !defined( PICKING )\nvarying vec3 vViewPosition;\n#endif\n#if defined( RADIUS_CLIP )\nvarying vec3 vClipCenter;\n#endif\nattribute vec3 dir;\nattribute float size;\n#ifdef PICKING\n#include unpack_color\nattribute float primitiveId;\nvarying vec3 vPickingColor;\n#else\n#include color_pars_vertex\n#ifndef FLAT_SHADED\nvarying vec3 vNormal;\n#endif\n#endif\n#include common\nvoid main(void){\n#ifdef PICKING\nvPickingColor = unpackColor( primitiveId );\n#else\n#include color_vertex\n#include beginnormal_vertex\n#include defaultnormal_vertex\n#ifndef FLAT_SHADED\nvNormal = normalize( transformedNormal );\n#endif\n#endif\n#include begin_vertex\ntransformed += normalize( dir ) * size;\n#include project_vertex\n#if defined( NEAR_CLIP ) || defined( RADIUS_CLIP ) || !defined( PICKING )\nvViewPosition = -mvPosition.xyz;\n#endif\n#if defined( RADIUS_CLIP )\nvClipCenter = -( modelViewMatrix * vec4( clipCenter, 1.0 ) ).xyz;\n#endif\n#include nearclip_vertex\n}");var ux=new Uint16Array([0,1,2,1,3,2]),hx=function(t){function e(e,i){var r=e||{},n=r.position.length/3-1,o=4*n,a=3*o,s=new Float32Array(a),c=new Float32Array(a),u=new Float32Array(a),h=Cn(a,a/3);t.call(this,{position:s,color:c,index:h,normal:u,picking:r.picking},i),this.addAttributes({dir:{type:"v3",value:new Float32Array(a)}}),this.addAttributes({size:{type:"f",value:new Float32Array(o)}}),r.primitiveId=Co(n),this.setAttributes(r),this.meshIndex=h,this.makeIndex()}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={vertexShader:{}};return e.prototype.setAttributes=function(t){var e,i,r,n,o,a,s,c,u,h,l,p,d=this.size/4,f=this.geometry.attributes;t.position&&(e=t.position,s=f.position.array,f.position.needsUpdate=!0),t.normal&&(i=t.normal,c=f.normal.array,f.normal.needsUpdate=!0),t.size&&(r=t.size,u=f.size.array,f.size.needsUpdate=!0),t.dir&&(n=t.dir,h=f.dir.array,f.dir.needsUpdate=!0),t.color&&(o=t.color,l=f.color.array,f.color.needsUpdate=!0),t.primitiveId&&(a=t.primitiveId,p=f.primitiveId.array,f.primitiveId.needsUpdate=!0);var m,g,v,y,b,x,_,w=r?r[0]:null;for(m=0;m<d;++m){for(x=3*m,v=3*m*4,b=4*m,e&&(s[v]=s[v+3]=e[x],s[v+1]=s[v+4]=e[x+1],s[v+2]=s[v+5]=e[x+2],s[v+6]=s[v+9]=e[x+3],s[v+7]=s[v+10]=e[x+4],s[v+8]=s[v+11]=e[x+5]),i&&(c[v]=c[v+3]=-i[x],c[v+1]=c[v+4]=-i[x+1],c[v+2]=c[v+5]=-i[x+2],c[v+6]=c[v+9]=-i[x+3],c[v+7]=c[v+10]=-i[x+4],c[v+8]=c[v+11]=-i[x+5]),g=0;g<4;++g)y=v+3*g,o&&(l[y]=o[x],l[y+1]=o[x+1],l[y+2]=o[x+2]),a&&(p[b+g]=a[m]);r&&(_=r[m],w!==r[m]?(u[b]=w,u[b+1]=w,u[b+2]=_,u[b+3]=_):(u[b]=_,u[b+1]=_,u[b+2]=_,u[b+3]=_),w=_),n&&(h[v]=n[x],h[v+1]=n[x+1],h[v+2]=n[x+2],h[v+3]=-n[x],h[v+4]=-n[x+1],h[v+5]=-n[x+2],h[v+6]=n[x+3],h[v+7]=n[x+4],h[v+8]=n[x+5],h[v+9]=-n[x+3],h[v+10]=-n[x+4],h[v+11]=-n[x+5])}},e.prototype.makeIndex=function(){var t,e,i,r,n=this.meshIndex,o=n.length/4/3;for(e=0;e<o;++e)for(i=6*e,r=4*e,n.set(ux,i),t=0;t<6;++t)n[i+t]+=r},i.vertexShader.get=function(){return"Ribbon.vert"},Object.defineProperties(e.prototype,i),e}(Ov),lx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="ribbon",this.parameters=Object.assign({subdiv:{type:"integer",max:50,min:1,rebuild:!0},tension:{type:"number",precision:1,max:1,min:.1},smoothSheet:{type:"boolean",rebuild:!0}},this.parameters,{side:null,wireframe:null,linewidth:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"chainname"),i.colorScale=dn(i.colorScale,"RdYlBu"),i.radius=dn(i.radius,"sstruc"),i.scale=dn(i.scale,4),"low"===i.quality?this.subdiv=3:"medium"===i.quality?this.subdiv=6:"high"===i.quality?this.subdiv=12:this.subdiv=dn(i.subdiv,6),this.tension=dn(i.tension,NaN),this.smoothSheet=dn(i.smoothSheet,!1),t.prototype.init.call(this,i)},e.prototype.getSplineParams=function(t){return Object.assign({subdiv:this.subdiv,tension:this.tension,directional:!0,smoothSheet:this.smoothSheet},t)},e.prototype.createData=function(t){var e=this,i=[],r=[];return this.structure.eachPolymer(function(t){if(!(t.residueCount<4)){r.push(t);var n=new ks(t,e.getSplineParams()),o=n.getSubdividedPosition(),a=n.getSubdividedOrientation(),s=n.getSubdividedColor(e.getColorParams()),c=n.getSubdividedPicking(),u=n.getSubdividedSize(e.radius,e.scale);i.push(new hx({position:o.position,normal:a.binormal,dir:a.normal,color:s.color,size:u.size,picking:c.picking},e.getBufferParams()))}},t.getSelection()),{bufferList:i,polymerList:r}},e.prototype.updateData=function(t,e){var i=this;t=t||{};var r=0,n=e.polymerList.length;for(r=0;r<n;++r){var o={},a=new ks(e.polymerList[r],i.getSplineParams());if(t.position){var s=a.getSubdividedPosition(),c=a.getSubdividedOrientation();o.position=s.position,o.normal=c.binormal,o.dir=c.normal}if(t.radius||t.scale){var u=a.getSubdividedSize(i.radius,i.scale);o.size=u.size}if(t.color){var h=a.getSubdividedColor(i.getColorParams());o.color=h.color}e.bufferList[r].setAttributes(o)}},e.prototype.setParameters=function(e){var i={};return e&&e.tension&&(i.position=!0),t.prototype.setParameters.call(this,e,i,!1),this},e}(ky);df.add("ribbon",lx);var px=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="rocket",this.parameters=Object.assign({localAngle:{type:"integer",max:180,min:0,rebuild:!0},centerDist:{type:"number",precision:1,max:10,min:0,rebuild:!0},ssBorder:{type:"boolean",rebuild:!0},radialSegments:!0,openEnded:!0,disableImpostor:!0},this.parameters),this.helixbundleList=[],this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"sstruc"),i.radius=dn(i.radius,1.5),i.scale=dn(i.scale,1),i.openEnded=dn(i.openEnded,!1),this.localAngle=dn(i.localAngle,30),this.centerDist=dn(i.centerDist,2.5),this.ssBorder=dn(i.ssBorder,!1),t.prototype.init.call(this,i)},e.prototype.createData=function(t){var e=this,i=0,r=[],n=[];this.structure.eachPolymer(function(t){if(!(t.residueCount<4||t.isNucleic())){var o=new Ka(t),a=o.getAxis(e.localAngle,e.centerDist,e.ssBorder,e.getColorParams(),e.radius,e.scale);i+=a.size.length,r.push(a),n.push(o)}},t.getSelection());var o={begin:new Float32Array(3*i),end:new Float32Array(3*i),size:new Float32Array(i),color:new Float32Array(3*i),picking:new Float32Array(i)},a=0;return r.forEach(function(t){o.begin.set(t.begin,3*a),o.end.set(t.end,3*a),o.size.set(t.size,a),o.color.set(t.color,3*a),o.picking.set(t.picking.array,a),a+=t.size.length}),i&&(o.picking=new $m(o.picking,t.getStructure())),{bufferList:[new oy({position1:o.begin,position2:o.end,color:o.color,color2:o.color,radius:o.size,picking:o.picking},this.getBufferParams({openEnded:this.openEnded,radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,dullInterior:!0}))],axisList:r,helixbundleList:n,axisData:o}},e.prototype.updateData=function(t,e){var i=this;if((t=t||{}).position)return void this.build();var r={};if(t.color||t.radius){var n=0;e.helixbundleList.forEach(function(r){var o=r.getAxis(i.localAngle,i.centerDist,i.ssBorder,i.getColorParams(),i.radius,i.scale);t.color&&e.axisData.color.set(o.color,3*n),(t.radius||t.scale)&&e.axisData.size.set(o.size,n),n+=o.size.length}),t.color&&(r.color=e.axisData.color,r.color2=e.axisData.color),(t.radius||t.scale)&&(r.radius=e.axisData.size)}e.bufferList[0].setAttributes(r)},e}(ky);df.add("rocket",px);var dx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="rope",this.parameters=Object.assign({smooth:{type:"integer",max:15,min:0,rebuild:!0}},this.parameters,{aspectRatio:null,smoothSheet:null})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.aspectRatio=1,i.tension=dn(i.tension,.5),i.scale=dn(i.scale,5),i.smoothSheet=!1,this.smooth=dn(i.smooth,2),t.prototype.init.call(this,i)},e.prototype.getSpline=function(t){var e=new Za(t);return new ks(t,this.getSplineParams({directional:!1,positionIterator:e.getCenterIterator(this.smooth)}))},e}(Wb);df.add("rope",dx);var fx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="spacefill",this.parameters=Object.assign({sphereDetail:!0,disableImpostor:!0},this.parameters),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};t.prototype.init.call(this,i)},e.prototype.createData=function(t){return{bufferList:[new $v(t.getAtomData(this.getAtomParams()),this.getBufferParams({sphereDetail:this.sphereDetail,dullInterior:!0,disableImpostor:this.disableImpostor}))]}},e.prototype.updateData=function(t,e){var i=e.sview.getAtomData(this.getAtomParams(t)),r={};t&&!t.position||(r.position=i.position),t&&!t.color||(r.color=i.color),t&&!t.radius||(r.radius=i.radius),e.bufferList[0].setAttributes(r)},e}(ky);df.add("spacefill",fx);var mx=function(t){function e(e,i){var r=e||{},n=i||{},o=r.position.length/3-1,a=new Float32Array(3*o*2),s=new Float32Array(3*o*2);t.call(this,{position:a,color:s},n),this.setAttributes(e)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={isLine:{},vertexShader:{},fragmentShader:{}};return e.prototype.setAttributes=function(t){var e,i,r,n,o=this.geometry.attributes;if(t.position&&(e=t.position,r=o.position.array,o.position.needsUpdate=!0),t.color&&(i=t.color,n=o.color.array,o.color.needsUpdate=!0),!e&&!i)return void cf.warn("TraceBuffer.prototype.setAttributes no data");for(var a,s,c=this.size-1,u=0;u<c;++u)a=3*u,s=3*u*2,e&&(r[s]=e[a],r[s+1]=e[a+1],r[s+2]=e[a+2],r[s+3]=e[a+3],r[s+4]=e[a+4],r[s+5]=e[a+5]),i&&(n[s]=i[a],n[s+1]=i[a+1],n[s+2]=i[a+2],n[s+3]=i[a+3],n[s+4]=i[a+4],n[s+5]=i[a+5])},i.isLine.get=function(){return!0},i.vertexShader.get=function(){return"Line.vert"},i.fragmentShader.get=function(){return"Line.frag"},Object.defineProperties(e.prototype,i),e}(Lv),gx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="trace",this.parameters=Object.assign({subdiv:{type:"integer",max:50,min:1,rebuild:!0},tension:{type:"number",precision:1,max:1,min:.1},smoothSheet:{type:"boolean",rebuild:!0}},this.parameters,{flatShaded:null,side:null,wireframe:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorScheme=dn(i.colorScheme,"chainname"),i.colorScale=dn(i.colorScale,"RdYlBu"),"low"===i.quality?this.subdiv=3:"medium"===i.quality?this.subdiv=6:"high"===i.quality?this.subdiv=12:this.subdiv=dn(i.subdiv,6),this.tension=dn(i.tension,NaN),this.smoothSheet=dn(i.smoothSheet,!1),t.prototype.init.call(this,i)},e.prototype.getSplineParams=function(t){return Object.assign({subdiv:this.subdiv,tension:this.tension,directional:!1,smoothSheet:this.smoothSheet},t)},e.prototype.createData=function(t){var e=this,i=[],r=[];return this.structure.eachPolymer(function(t){if(!(t.residueCount<4)){r.push(t);var n=new ks(t,e.getSplineParams()),o=n.getSubdividedPosition(),a=n.getSubdividedColor(e.getColorParams());i.push(new mx(Object.assign({},o,a),e.getBufferParams()))}},t.getSelection()),{bufferList:i,polymerList:r}},e.prototype.updateData=function(t,e){var i=this;t=t||{};var r=0,n=e.polymerList.length;for(r=0;r<n;++r){var o={},a=new ks(e.polymerList[r],i.getSplineParams());if(t.position){var s=a.getSubdividedPosition();o.position=s.position}if(t.color){var c=a.getSubdividedColor(i.getColorParams());o.color=c.color}e.bufferList[r].setAttributes(o)}},e.prototype.setParameters=function(e){var i={};return e&&e.tension&&(i.position=!0),t.prototype.setParameters.call(this,e,i,!1),this},e}(ky);df.add("trace",gx);var vx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="tube",this.parameters=Object.assign({},this.parameters,{aspectRatio:null})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.aspectRatio=1,i.scale=dn(i.scale,2),"low"===i.quality&&(this.radialSegments=5),t.prototype.init.call(this,i)},e.prototype.getSplineParams=function(){return t.prototype.getSplineParams.call(this,{directional:!1})},e}(Wb);df.add("tube",vx);var yx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="unitcell",this.parameters=Object.assign({radius:{type:"number",precision:3,max:10,min:.001},sphereDetail:!0,radialSegments:!0,disableImpostor:!0},this.parameters,{assembly:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{},r=.5;this.structure.unitcell&&(r=Math.cbrt(this.structure.unitcell.volume)/200),i.radius=dn(i.radius,r),i.colorValue=dn(i.colorValue,"orange"),t.prototype.init.call(this,i)},e.prototype.getUnitcellData=function(t){return t.unitcell.getData(t)},e.prototype.create=function(){var t=this.structureView.getStructure();if(t.unitcell){var e=this.getUnitcellData(t);this.sphereBuffer=new $v(e.vertex,this.getBufferParams({sphereDetail:this.sphereDetail,disableImpostor:this.disableImpostor,dullInterior:!0})),this.cylinderBuffer=new oy(e.edge,this.getBufferParams({openEnded:!0,radialSegments:this.radialSegments,disableImpostor:this.disableImpostor,dullInterior:!0})),this.dataList.push({sview:this.structureView,bufferList:[this.sphereBuffer,this.cylinderBuffer]})}},e.prototype.updateData=function(t,e){var i=e.sview.getStructure(),r=this.getUnitcellData(i),n={},o={};t&&!t.position||(n.position=r.vertexPosition,o.position1=r.edgePosition1,o.position2=r.edgePosition2),t&&!t.color||(n.color=r.vertexColor,o.color=r.edgeColor,o.color2=r.edgeColor),t&&!t.radius||(n.radius=r.vertexRadius,o.radius=r.edgeRadius),this.sphereBuffer.setAttributes(n),this.cylinderBuffer.setAttributes(o)},e}(ky);df.add("unitcell",yx);var bx=function(t){function e(e,i,r){t.call(this,e,i,r),this.type="validation",this.parameters=Object.assign({},this.parameters,{radiusType:null,radius:null,scale:null}),this.init(r)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.init=function(e){var i=e||{};i.colorValue=dn(i.colorValue,"#f0027f"),t.prototype.init.call(this,i)},e.prototype.createData=function(t){if(t.validation){var e=t.validation.getClashData({structure:t,color:this.colorValue});return{bufferList:[new oy(e,this.getBufferParams({openEnded:!1}))]}}},e}(ky);df.add("validation",bx);var xx=function(t,e){var i=e||{};this.streamer=t,this.name=dn(i.name,""),this.path=dn(i.path,"")},_x={type:{},__objName:{}};_x.type.get=function(){return""},_x.__objName.get=function(){return""},xx.prototype.parse=function(){var t=this;return this.streamer.read().then(function(){return t._beforeParse(),t._parse(),t._afterParse(),t[t.__objName]})},xx.prototype._parse=function(){},xx.prototype._beforeParse=function(){},xx.prototype._afterParse=function(){t.Debug&&cf.log(this[this.__objName])},Object.defineProperties(xx.prototype,_x);var wx=function(t){function e(e,i){var r=i||{};t.call(this,e,r),this.firstModelOnly=dn(r.firstModelOnly,!1),this.asTrajectory=dn(r.asTrajectory,!1),this.cAlphaOnly=dn(r.cAlphaOnly,!1),this.structure=new Mv(this.name,this.path),this.structureBuilder=new $s(this.structure)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},__objName:{}};return i.type.get=function(){return"structure"},i.__objName.get=function(){return"structure"},Object.defineProperties(e.prototype,i),e}(xx),Sx=function(t,e,i,r,n){this.structure=t,this.index=e,this.description=i||"",this.entityType=Hs(r||""),this.chainIndexList=n||[],n.forEach(function(i){t.chainStore.entityIndex[i]=e})},Ax={type:{}};Ax.type.get=function(){return"Entity"},Sx.prototype.getEntityType=function(){return this.entityType},Sx.prototype.isPolymer=function(){return this.entityType===sg},Sx.prototype.isNonPolymer=function(){return this.entityType===cg},Sx.prototype.isMacrolide=function(){return this.entityType===ug},Sx.prototype.isWater=function(){return this.entityType===hg},Sx.prototype.eachChain=function(t){var e=this.structure.getChainProxy();this.chainIndexList.forEach(function(i){e.index=i,t(e)})},Object.defineProperties(Sx.prototype,Ax);var Mx=function(t){var e=t||{};this.a=e.a||1,this.b=e.b||1,this.c=e.c||1,this.alpha=e.alpha||90,this.beta=e.beta||90,this.gamma=e.gamma||90,this.spacegroup=e.spacegroup||"P 1",this.cartToFrac=e.cartToFrac||e.scale,this.fracToCart=new v;var i=Gn(this.alpha),r=Gn(this.beta),n=Gn(this.gamma),o=Math.cos(i),a=Math.cos(r),s=Math.cos(n),c=Math.sin(r),u=Math.sin(n);if(this.volume=this.a*this.b*this.c*Math.sqrt(1-o*o-a*a-s*s+2*o*a*s),void 0===this.cartToFrac){var h=this.a*this.b*u/this.volume,l=(a*s-o)/(c*u);this.fracToCart.set(this.a,0,0,0,this.b*s,this.b*u,0,0,this.c*a,-this.c*c*l,1/h,0,0,0,0,1).transpose(),this.cartToFrac=(new v).getInverse(this.fracToCart)}else this.fracToCart.getInverse(this.cartToFrac)};Mx.prototype.getPosition=function(t){function e(t,e,s){o.set(t,e,s).multiply(n).applyMatrix4(r.fracToCart).toArray(i,a),a+=3}var i=new Float32Array(24),r=t.unitcell,n=t.center.clone().applyMatrix4(r.cartToFrac).floor().multiplyScalar(2).addScalar(1),o=new g,a=0;return e(0,0,0),e(1,0,0),e(0,1,0),e(0,0,1),e(1,1,0),e(1,0,1),e(0,1,1),e(1,1,1),i},Mx.prototype.getCenter=function(t){return Eo(this.getPosition(t))},Mx.prototype.getData=function(t,e){function i(t,e){s.fromArray(c,3*t).toArray(l,m),s.fromArray(c,3*e).toArray(p,m),m+=3}var r=e||{},n=dn(r.colorValue,"orange"),o=dn(r.radius,Math.cbrt(this.volume)/200),a=new tt(n),s=new g,c=this.getPosition(t),u=To(8,a.r,a.g,a.b),h=Po(8,o),l=new Float32Array(36),p=new Float32Array(36),d=To(12,a.r,a.g,a.b),f=Po(12,o),m=0;i(0,1),i(0,2),i(0,3),i(1,4),i(1,5),i(2,6),i(3,5),i(4,7),i(5,7),i(2,4),i(7,6),i(3,6);var v=new ig(this,t);return{vertex:{position:c,color:u,radius:h,picking:v},edge:{position1:l,position2:p,color:d,color2:d,radius:f,picking:v}}};var Px={1:"h",2:"h",3:"i",4:"h",5:"g",6:"h",7:"h",8:"h",9:"h",10:"h","":"h"},Tx=function(e){function i(t,i){var r=i||{};e.call(this,t,r),this.hex=dn(r.hex,!1)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"pdb"},i.prototype._parse=function(){function e(t,e,r){for(var n=t;n<e;++n)if(l=r[n],"ATOM  "===(p=l.substr(0,6))||"HETATM"===p){if(mt&&(X?(K?(a=new Float32Array(3*ht.count),Y.push(a)):a=[],s=0):W||(J={}),O=(R=1).toString(),D=!0,mt=!1),W&&ft>0)continue;var o=void 0,at=void 0,gt=void 0,vt=void 0,yt=void 0;if(z){if(vt=l.split(U),yt=10===vt.length?1:0,x=vt[2],q&&"CA"!==x)continue;o=parseFloat(vt[6-yt]),at=parseFloat(vt[7-yt]),gt=parseFloat(vt[8-yt])}else{if(x=l.substr(12,4).trim(),q&&"CA"!==x)continue;o=parseFloat(l.substr(30,8)),at=parseFloat(l.substr(38,8)),gt=parseFloat(l.substr(46,8))}if(X){var bt=3*s;if(a[bt+0]=o,a[bt+1]=at,a[bt+2]=gt,s+=1,K)continue}var xt=void 0;z?(d=parseInt(vt[1]),xt="",_="H"===l[0]?1:0,f=yt?"":vt[4],m=parseInt(vt[5-yt]),b="",g=vt[3],w=parseFloat(vt[9-yt]),S="",y=0):(d=parseInt(l.substr(6,5),$),V&&99999===d&&($=16),_="H"===l[0]?1:0,f=l[21].trim(),m=parseInt(l.substr(22,4),H)||1,V&&9999===m&&(H=16),b=l[26].trim(),g=l.substr(17,4).trim()||"MOL",w=parseFloat(l.substr(60,6)),S=l[16].trim(),y=parseFloat(l.substr(54,6)),i||(xt=l.substr(76,2).trim(),f||(f=l.substr(72,4).trim()))),ht.growIfFull(),ht.atomTypeId[dt]=ut.add(x,xt),ht.x[dt]=o,ht.y[dt]=at,ht.z[dt]=gt,ht.serial[dt]=d,ht.bfactor[dt]=isNaN(w)?0:w,ht.altloc[dt]=S.charCodeAt(0),ht.occupancy[dt]=isNaN(y)?0:y,_?N===f&&B===g&&(Ig.includes(g)||k===m&&F===b)||(O=(R+=1).toString(),k=m,B=g,F=b):D||N===f||(O=(R+=1).toString()),G.addAtom(ft,f,O,g,m,_,void 0,b),J[d]=dt,dt+=1,D=!1,N=f}else if("CONECT"===p){var _t=J[parseInt(l.substr(6,5))],wt=[11,16,21,26],St={};if(void 0===_t)continue;for(var At=0;At<4;++At){var Mt=parseInt(l.substr(wt[At],5));if(!Number.isNaN(Mt)&&void 0!==(Mt=J[Mt]))if(_t<Mt?(lt.index=_t,pt.index=Mt):(lt.index=Mt,pt.index=_t),void 0!==St[Mt])j.bondStore.bondOrder[St[Mt]]+=1;else{var Pt=lt.index+"|"+pt.index;void 0===et[Pt]&&(et[Pt]=!0,St[Mt]=j.bondStore.count,j.bondStore.addBond(lt,pt,1))}}}else if("HELIX "===p){A=l[19].trim(),M=parseInt(l.substr(21,4)),P=l[25].trim(),T=l[31].trim(),E=parseInt(l.substr(33,4)),C=l[37].trim();var Tt=parseInt(l.substr(39,1));Tt=(Px[Tt]||Px[""]).charCodeAt(0),st.push([A,M,P,T,E,C,Tt])}else if("SHEET "===p)A=l[21].trim(),M=parseInt(l.substr(22,4)),P=l[26].trim(),T=l[32].trim(),E=parseInt(l.substr(33,4)),C=l[37].trim(),ct.push([A,M,P,T,E,C]);else if("HETNAM"===p)ot[l.substr(11,3)]=l.substr(15).trim();else if("COMPND"===p){var Et=l.substr(10,70).trim(),Ct=Et.indexOf(":"),It=Et.substring(0,Ct),Lt=void 0;rt.includes(It)?(L=It,Lt=Et.substring(Ct+2)):Lt=Et,Lt=Lt.replace(/;$/,""),"MOL_ID"===L?(I={chainList:[],name:""},it.push(I)):"MOLECULE"===L?(I.name&&(I.name+=" "),I.name+=Lt):"CHAIN"===L&&Array.prototype.push.apply(I.chainList,Lt.split(/\s*,\s*/))}else if(l.startsWith("TER")){var Rt=j.getChainProxy(j.chainStore.count-1);nt[Rt.chainname]=Rt.index,O=(R+=1).toString(),D=!0}else if("REMARK"===p&&"350"===l.substr(7,3)){if("BIOMOLECULE:"===l.substr(11,12)){var Ot=l.substr(23).trim();/^(0|[1-9][0-9]*)$/.test(Ot)&&(Ot="BU"+Ot),c=new iv(Ot),Q[Ot]=c}else if("BIOMT"===l.substr(13,5)){var Dt=l.split(/\s+/),Nt=parseInt(l[18])-1;0===Nt&&(h=new v,u.matrixList.push(h));var kt=h.elements;kt[0+Nt]=parseFloat(Dt[4]),kt[4+Nt]=parseFloat(Dt[5]),kt[8+Nt]=parseFloat(Dt[6]),kt[12+Nt]=parseFloat(Dt[7])}else if("APPLY THE FOLLOWING TO CHAINS:"===l.substr(11,30)||"                   AND CHAINS:"===l.substr(11,30)){"APPLY"===l.substr(11,5)&&(u=c.addPart());for(var Bt=l.substr(41,30).split(","),Ft=0,zt=Bt.length;Ft<zt;++Ft){var Ut=Bt[Ft].trim();Ut&&u.chainList.push(Ut)}}}else if("HEADER"===p)j.id=l.substr(62,4);else if("TITLE "===p)j.title+=(j.title?" ":"")+l.substr(10,70).trim();else if("MODEL "===p)mt=!0;else if("ENDMDL"===p||l.startsWith("END")){if(mt)continue;X&&!K&&(Y.push(new Float32Array(a)),K=!0),ft+=1,mt=!0}else if("MTRIX"===l.substr(0,5)){if("1"===l[59])continue;var jt=l.split(/\s+/),Gt=jt[1].trim();if("1"===l[5]&&"1"===Gt){c=new iv("NCS"),Q.NCS=c,u=c.addPart()}var Vt=parseInt(l[5])-1;0===Vt&&(h=new v,u.matrixList.push(h));var $t=h.elements;$t[0+Vt]=parseFloat(jt[2]),$t[4+Vt]=parseFloat(jt[3]),$t[8+Vt]=parseFloat(jt[4]),$t[12+Vt]=parseFloat(jt[5])}else if("ORIGX"===l.substr(0,5)){tt.origx||(tt.origx=new v);var Ht=l.split(/\s+/),Wt=parseInt(l[5])-1,Xt=tt.origx.elements;Xt[0+Wt]=parseFloat(Ht[1]),Xt[4+Wt]=parseFloat(Ht[2]),Xt[8+Wt]=parseFloat(Ht[3]),Xt[12+Wt]=parseFloat(Ht[4])}else if("SCALE"===l.substr(0,5)){tt.scale||(tt.scale=new v);var qt=l.split(/\s+/),Yt=parseInt(l[5])-1,Zt=tt.scale.elements;Zt[0+Yt]=parseFloat(qt[1]),Zt[4+Yt]=parseFloat(qt[2]),Zt[8+Yt]=parseFloat(qt[3]),Zt[12+Yt]=parseFloat(qt[4])}else if("CRYST1"===p){var Kt=parseFloat(l.substr(6,9)),Qt=parseFloat(l.substr(15,9)),Jt=parseFloat(l.substr(24,9)),te=parseFloat(l.substr(33,7)),ee=parseFloat(l.substr(40,7)),ie=parseFloat(l.substr(47,7)),re=l.substr(55,11).trim(),ne=new Float32Array(9);ne[0]=Kt,ne[4]=Qt,ne[8]=Jt,Z.push(ne),0===ft&&(tt.a=Kt,tt.b=Qt,tt.c=Jt,tt.alpha=te,tt.beta=ee,tt.gamma=ie,tt.spacegroup=re)}}t.Debug&&cf.time("PdbParser._parse "+this.name);var i=!1,r=this.streamer.peekLines(1)[0],n=r.substr(62,4),o=r.substr(72,4);n===o&&o.trim()&&(i=!0);var a,s,c,u,h,l,p,d,f,m,g,y,b,x,_,w,S,A,M,P,T,E,C,I,L,R,O,D,N,k,B,F,z="pqr"===this.type,U=/\s+/,j=this.structure,G=this.structureBuilder,V=this.hex,$=10,H=10,W=this.firstModelOnly,X=this.asTrajectory,q=this.cAlphaOnly,Y=j.frames,Z=j.boxes,K=!1,Q=j.biomolDict,J={},tt={},et={},it=[],rt=["MOL_ID","MOLECULE","CHAIN","FRAGMENT","SYNONYM","EC","ENGINEERED","MUTATION","OTHER_DETAILS"],nt={},ot={},at={helices:[],sheets:[]},st=at.helices,ct=at.sheets,ut=j.atomMap,ht=j.atomStore;ht.resize(Math.round(this.streamer.data.length/80));var lt=j.getAtomProxy(),pt=j.getAtomProxy(),dt=0,ft=0,mt=!0;this.streamer.eachChunkOfLines(function(t){e(0,t.length,t)});var gt=it.length;if(it.length){j.eachChain(function(t){t.entityIndex=gt}),it.forEach(function(t,e){var i=t.chainList.map(function(t){return nt[t]});j.entityList.push(new Sx(j,e,t.name,"polymer",i))});var vt=it.length,yt=j.getResidueProxy(),bt={};j.eachChain(function(t){t.entityIndex===gt&&(yt.index=t.residueOffset,bt[yt.resname]||(bt[yt.resname]=[]),bt[yt.resname].push(t.index))}),Object.keys(bt).forEach(function(t){var e=bt[t],i="non-polymer",r=ot[t]||t;Ig.includes(t)&&(r="water",i="water"),j.entityList.push(new Sx(j,vt,r,i,e)),vt+=1})}void 0!==tt.a?j.unitcell=new Mx(tt):j.unitcell=void 0,(st.length||ct.length)&&rs(j,at),G.finalize(),j.finalizeAtoms(),i||ns(j),os(j),j.finalizeBonds(),st.length||ct.length||av(j),hs(j),t.Debug&&cf.timeEnd("PdbParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(wx);ff.add("pdb",Tx),ff.add("pdb1",Tx),ff.add("ent",Tx);var Ex=/\s+/,Cx=/'((?:(?!'\s).)*)'|"((?:(?!"\s).)*)"|(\S+)/g,Ix=/"/g,Lx=/^['"]+|['"]+$/g,Rx=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"cif"},i.prototype._parse=function(){function e(e,q,Y){for(var Z=e;Z<q;++Z)if(n=Y[Z],((o=n.trim())||R||N)&&"#"!==o[0])if("data_"===o.substring(0,5))C.data=o.substring(5).trim();else if(";"===o[0])R?(N?(F===B.length&&(F=0),B[F].push(O),F+=1):!1===U?C[z]=O:C[z][U]=O,R=!1,O=null):(R=!0,O=o.substring(1));else if("loop_"===o)N=!0,k=!0,B.length=0,G.length=0,F=0;else if("_"===o[0]){var K,Q,J;if(N&&!k&&(N=!1),N)Q=(K=o.split("."))[0].substring(1),J=K[1],1===K.length?(J=!1,C[Q]||(C[Q]=[]),B.push(C[Q])):(C[Q]||(C[Q]={}),C[Q][J]?t.Debug&&cf.warn(Q,J,"already exists"):(C[Q][J]=[],B.push(C[Q][J]),G.push(J))),z=Q,U=J,j=!0;else{var tt=o.match(Cx),et=tt[0],it=tt[1];Q=(K=et.split("."))[0].substring(1),J=K[1],1===K.length?(J=!1,C[Q]=it):(C[Q]||(C[Q]={}),C[Q][J]?t.Debug&&cf.warn(Q,J,"already exists"):C[Q][J]=it),it||(D=!0),z=Q,U=J}}else if(R)O+=n;else if(N){if(!o)continue;if("atom_site"===z){var rt=o.split(Ex);j&&(a=G.indexOf("auth_asym_id"),s=G.indexOf("auth_seq_id"),c=G.indexOf("label_atom_id"),u=G.indexOf("label_comp_id"),h=G.indexOf("label_asym_id"),l=G.indexOf("label_entity_id"),p=G.indexOf("label_alt_id"),y=G.indexOf("Cartn_x"),b=G.indexOf("Cartn_y"),x=G.indexOf("Cartn_z"),f=G.indexOf("id"),m=G.indexOf("type_symbol"),d=G.indexOf("group_PDB"),_=G.indexOf("B_iso_or_equiv"),g=G.indexOf("pdbx_PDB_model_num"),v=G.indexOf("pdbx_PDB_ins_code"),w=G.indexOf("occupancy"),j=!1,H=parseInt(rt[g]),P&&(i=[],r=0));var nt=parseInt(rt[g]);if(H!==nt&&(P&&(0===X&&E.push(new Float32Array(i)),i=new Float32Array(3*$.count),E.push(i),r=0),X+=1),H=nt,M&&X>0)continue;var ot=rt[c].replace(Ix,"");if(T&&"CA"!==ot)continue;var at=parseFloat(rt[y]),st=parseFloat(rt[b]),ct=parseFloat(rt[x]);if(P){var ut=3*r;if(i[ut+0]=at,i[ut+1]=st,i[ut+2]=ct,r+=1,X>0)continue}var ht=rt[u],lt=parseInt(rt[s]),pt=rt[v];pt="?"===pt?"":pt;var dt=rt[a],ft=rt[h],mt="H"===rt[d][0]?1:0,gt=rt[m],vt=parseFloat(rt[_]),yt=parseFloat(rt[w]),bt=rt[p];if(bt="."===bt?"":bt,$.growIfFull(),$.atomTypeId[W]=V.add(ot,gt),$.x[W]=at,$.y[W]=st,$.z[W]=ct,$.serial[W]=parseInt(rt[f]),$.bfactor[W]=isNaN(vt)?0:vt,$.occupancy[W]=isNaN(yt)?0:yt,$.altloc[W]=bt.charCodeAt(0),A.addAtom(X,dt,ft,ht,lt,mt,void 0,pt),t.Debug){var xt=I[ft];void 0!==xt&&xt!==dt&&t.Debug&&cf.warn(xt,dt)}I[ft]=dt;var _t=rt[l];L[_t]||(L[_t]=new Set),L[_t].add(S.chainStore.count-1),W+=1}else{var wt=o.match(Cx),St=wt.length;F===B.length&&(F=0);for(var At=0;At<St;++At)B[F+At].push(wt[At]);F+=St}k=!1}else if("'"===o[0]&&"'"===o[o.length-1]){var Mt=o.substring(1,o.length-1);!1===U?C[z]=Mt:C[z][U]=Mt}else D?!1===U?C[z]=o:C[z][U]=o:t.Debug&&cf.log("CifParser._parse: unknown state",o);else R=!1,N=!1,D=!1,B.length=0,F=null,z=null,U=null,j=null,G.length=0}cf.time("CifParser._parse "+this.name);var i,r,n,o,a,s,c,u,h,l,p,d,f,m,g,v,y,b,x,_,w,S=this.structure,A=this.structureBuilder,M=this.firstModelOnly,P=this.asTrajectory,T=this.cAlphaOnly,E=S.frames,C={},I={},L={},R=!1,O=null,D=!1,N=!1,k=!1,B=[],F=null,z=null,U=null,j=null,G=[],V=S.atomMap,$=S.atomStore;$.resize(this.streamer.data.length/100);var H,W=0,X=0;if(this.streamer.eachChunkOfLines(function(t){e(0,t.length,t)}),C.chem_comp&&C.chem_comp_atom)Ks(C,S,A),A.finalize(),S.finalizeAtoms(),S.finalizeBonds(),ps(S);else if(C.atom_site_type_symbol&&C.atom_site_label&&C.atom_site_fract_x)Qs(C,S,A),A.finalize(),S.finalizeAtoms(),os(S),S.finalizeBonds();else{var q=Js(C,S,I);if(tc(C,S,I),ec(C,S,I),ic(C,S,L),C.struct&&C.struct.title&&(S.title=C.struct.title.trim().replace(Lx,"")),C.entry&&C.entry.id&&(S.id=C.entry.id.trim().replace(Lx,"")),C.database_PDB_rev){if(C.database_PDB_rev.date){Xs(C.database_PDB_rev,"date");var Y=C.database_PDB_rev.date.filter(qs);Y.length&&(S.header.releaseDate=Y[Y.length-1])}if(C.database_PDB_rev.date_original){Xs(C.database_PDB_rev,"date_original");var Z=C.database_PDB_rev.date_original.filter(qs);Z.length&&(S.header.depositionDate=Z[Z.length-1])}}C.reflns&&C.reflns.d_resolution_high?qs(C.reflns.d_resolution_high)&&(S.header.resolution=parseFloat(C.reflns.d_resolution_high)):C.refine&&C.refine.ls_d_res_high&&qs(C.refine.ls_d_res_high)&&(S.header.resolution=parseFloat(C.refine.ls_d_res_high)),C.refine&&C.refine.ls_R_factor_R_free&&qs(C.refine.ls_R_factor_R_free)&&(S.header.rFree=parseFloat(C.refine.ls_R_factor_R_free)),C.refine&&C.refine.ls_R_factor_R_work&&qs(C.refine.ls_R_factor_R_work)&&(S.header.rWork=parseFloat(C.refine.ls_R_factor_R_work)),C.exptl&&C.exptl.method&&(Xs(C.exptl,"method"),S.header.experimentalMethods=C.exptl.method.map(function(t){return t.replace(Lx,"")})),A.finalize(),S.finalizeAtoms(),os(S),S.finalizeBonds(),q?rs(S,q):av(S),hs(S),S.extraData.cif=C}t.Debug&&cf.timeEnd("CifParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(wx);ff.add("cif",Rx),ff.add("mcif",Rx),ff.add("mmcif",Rx);var Ox=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"gro"},i.prototype._parse=function(){function e(t,e,n){for(var l=t;l<e;++l){var T=++P-1,E=n[l];if(E)if(T%_==0)s&&(i=new Float32Array(3*x),u.push(i),r=0);else if(T%_==1);else if(T%_==_-1){var C=E.trim().split(/\s+/),I=new Float32Array(9);if(I[0]=10*parseFloat(C[0]),I[4]=10*parseFloat(C[1]),I[8]=10*parseFloat(C[2]),h.push(I),a)return!0;M+=1}else{if(p=E.substr(10,5).trim(),c&&"CA"!==p)continue;var L=10*parseFloat(E.substr(v,g)),R=10*parseFloat(E.substr(y,g)),O=10*parseFloat(E.substr(b,g));if(s){var D=3*r;if(i[D+0]=L,i[D+1]=R,i[D+2]=O,r+=1,T>_)continue}d=E.substr(5,5).trim(),f=parseInt(E.substr(0,5)),m=parseInt(E.substr(15,5)),S.growIfFull(),S.atomTypeId[A]=w.add(p),S.x[A]=L,S.y[A]=R,S.z[A]=O,S.serial[A]=m,o.addAtom(M,"","",d,f,0,"l"),A+=1}}}t.Debug&&cf.time("GroParser._parse "+this.name);var i,r,n=this.structure,o=this.structureBuilder,a=this.firstModelOnly,s=this.asTrajectory,c=this.cAlphaOnly,u=n.frames,h=n.boxes,l=this.streamer.peekLines(3);n.title=l[0].trim();var p,d,f,m,g=5+(l[2].length-l[2].lastIndexOf(".")-1),v=20,y=20+g,b=20+2*g,x=parseInt(l[1]),_=x+3,w=n.atomMap,S=n.atomStore;S.resize(x);var A=0,M=0,P=0;this.streamer.eachChunkOfLines(function(t){e(0,t.length,t)}),o.finalize(),n.finalizeAtoms(),ns(n),os(n),n.finalizeBonds(),av(n),t.Debug&&cf.timeEnd("GroParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(wx);ff.add("gro",Ox);var Dx=["xCoordList","yCoordList","zCoordList","groupIdList","groupTypeList","chainIdList","bFactorList","atomIdList","altLocList","occupancyList","secStructList","insCodeList","sequenceIndexList","chainNameList","bondAtomList","bondOrderList"],Nx=["mmtfVersion","mmtfProducer","unitCell","spaceGroup","structureId","title","depositionDate","releaseDate","experimentalMethods","resolution","rFree","rWork","bioAssemblyList","ncsOperatorList","entityList","groupList","numBonds","numAtoms","numGroups","numChains","numModels","groupsPerChain","chainsPerModel"].concat(Dx),kx={0:"i".charCodeAt(0),1:"s".charCodeAt(0),2:"h".charCodeAt(0),3:"e".charCodeAt(0),4:"g".charCodeAt(0),5:"b".charCodeAt(0),6:"t".charCodeAt(0),7:"l".charCodeAt(0),"-1":"".charCodeAt(0)},Bx=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"mmtf"},i.prototype._parse=function(){t.Debug&&cf.time("MmtfParser._parse "+this.name);var e,i,r,n,o,a=this.structure,s=Ac(wc(this.streamer.data));["depositionDate","releaseDate","resolution","rFree","rWork","experimentalMethods"].forEach(function(t){void 0!==s[t]&&(a.header[t]=s[t])});var c,u,h,l,p,d;if(a.id=s.structureId,a.title=s.title,this.firstModelOnly||this.asTrajectory){for(p=1,h=0,e=0,i=l=s.chainsPerModel[0];e<i;++e)h+=s.groupsPerChain[e];for(u=0,e=0,i=h;e<i;++e)u+=(o=s.groupList[s.groupTypeList[e]]).atomNameList.length;c=s.numBonds,d=[l]}else c=s.numBonds,u=s.numAtoms,h=s.numGroups,l=s.numChains,p=s.numModels,d=s.chainsPerModel;if(c+=h,this.asTrajectory)for(e=0,i=s.numModels;e<i;++e){var f=new Float32Array(3*u),m=u*e;for(r=0;r<u;++r){var g=3*r,y=r+m;f[g]=s.xCoordList[y],f[g+1]=s.yCoordList[y],f[g+2]=s.zCoordList[y]}a.frames.push(f)}var b=new Uint32Array(c),x=new Uint32Array(c),_=new Uint8Array(c),w=new Uint32Array(u),S=new Uint32Array(h),A=new Uint32Array(h),M=new Uint16Array(h),P=new Uint16Array(l),T=new Uint32Array(l),E=new Uint32Array(l),C=new Uint32Array(p),I=new Uint32Array(p),L=0;for(e=0,i=p;e<i;++e){var R=d[e];for(C[e]=L,I[e]=R,r=0;r<R;++r)P[r+L]=e;L+=R}var O=s.groupsPerChain,D=0;for(e=0,i=l;e<i;++e){var N=O[e];for(T[e]=D,E[e]=N,r=0;r<N;++r)S[r+D]=e;D+=N}var k=0,B=0;for(e=0,i=h;e<i;++e){var F=(o=s.groupList[s.groupTypeList[e]]).atomNameList.length,z=o.bondAtomList,U=o.bondOrderList;for(r=0,n=U.length;r<n;++r)b[B]=k+z[2*r],x[B]=k+z[2*r+1],_[B]=U[r],B+=1;for(A[e]=k,M[e]=F,r=0;r<F;++r)w[k]=e,k+=1}var j=s.bondAtomList;if(j)for(s.bondOrderList&&_.set(s.bondOrderList,B),e=0,i=j.length;e<i;e+=2){var G=j[e],V=j[e+1];G<u&&V<u&&(b[B]=G,x[B]=V,B+=1)}a.bondStore.length=_.length,a.bondStore.count=B,a.bondStore.atomIndex1=b,a.bondStore.atomIndex2=x,a.bondStore.bondOrder=_,a.atomStore.length=u,a.atomStore.count=u,a.atomStore.residueIndex=w,a.atomStore.atomTypeId=new Uint16Array(u),a.atomStore.x=s.xCoordList.subarray(0,u),a.atomStore.y=s.yCoordList.subarray(0,u),a.atomStore.z=s.zCoordList.subarray(0,u),a.atomStore.serial=s.atomIdList.subarray(0,u),a.atomStore.bfactor=s.bFactorList.subarray(0,u),a.atomStore.altloc=s.altLocList.subarray(0,u),a.atomStore.occupancy=s.occupancyList.subarray(0,u),a.residueStore.length=h,a.residueStore.count=h,a.residueStore.chainIndex=S,a.residueStore.residueTypeId=s.groupTypeList,a.residueStore.atomOffset=A,a.residueStore.atomCount=M,a.residueStore.resno=s.groupIdList.subarray(0,h),a.residueStore.sstruc=s.secStructList.subarray(0,h),a.residueStore.inscode=s.insCodeList.subarray(0,h),a.chainStore.length=l,a.chainStore.count=l,a.chainStore.entityIndex=new Uint16Array(l),a.chainStore.modelIndex=P,a.chainStore.residueOffset=T,a.chainStore.residueCount=E,a.chainStore.chainname=s.chainNameList.subarray(0,4*l),a.chainStore.chainid=s.chainIdList.subarray(0,4*l),a.modelStore.length=p,a.modelStore.count=p,a.modelStore.chainOffset=C,a.modelStore.chainCount=I;var $={};for(e=0,i=s.groupList.length;e<i;++e){var H=s.groupList[e],W=[];for(r=0,n=H.atomNameList.length;r<n;++r){var X=H.elementList[r].toUpperCase(),q=H.atomNameList[r];W.push(a.atomMap.add(q,X))}var Y=H.chemCompType.toUpperCase(),Z=vg.includes(Y),K=H.bondOrderList.length,Q=new Array(K),J=new Array(K);for(r=0;r<K;++r)Q[r]=H.bondAtomList[2*r],J[r]=H.bondAtomList[2*r+1];var tt={atomIndices1:Q,atomIndices2:J,bondOrders:H.bondOrderList};$[e]=a.residueMap.add(H.groupName,W,Z,Y,tt)}for(e=0,i=h;e<i;++e)a.residueStore.residueTypeId[e]=$[a.residueStore.residueTypeId[e]];for(e=0,i=a.atomStore.count;e<i;++e){var et=a.atomStore.residueIndex[e],it=a.residueMap.list[a.residueStore.residueTypeId[et]],rt=a.residueStore.atomOffset[et];a.atomStore.atomTypeId[e]=it.atomTypeIdList[e-rt]}if(s.secStructList){var nt=s.secStructList.length;for(e=0,i=a.residueStore.count;e<i;++e){var ot=kx[a.residueStore.sstruc[e%nt]];void 0!==ot&&(a.residueStore.sstruc[e]=ot)}}if(s.entityList&&s.entityList.forEach(function(t,e){a.entityList[e]=new Sx(a,e,t.description,t.type,t.chainIndexList)}),s.bioAssemblyList&&s.bioAssemblyList.forEach(function(t,e){var i=e+1,r=new iv(i);a.biomolDict["BU"+i]=r;var n={};t.transformList.forEach(function(t){var e=(new v).fromArray(t.matrix).transpose(),i=t.chainIndexList.map(function(t){for(var e="",i=0;i<4;++i){var r=s.chainNameList[4*t+i];if(!r)break;e+=String.fromCharCode(r)}return e}),o=n[i];o?o.matrixList.push(e):n[i]=r.addPart([e],i)})}),s.ncsOperatorList){var at=new iv("NCS"),st=at.addPart();s.ncsOperatorList.forEach(function(t){var e=(new v).fromArray(t).transpose();st.matrixList.push(e)}),st.matrixList.length>0&&(a.biomolDict.NCS=at)}var ct=s.unitCell;ct&&Array.isArray(ct)&&ct[0]?a.unitcell=new Mx({a:ct[0],b:ct[1],c:ct[2],alpha:ct[3],beta:ct[4],gamma:ct[5],spacegroup:s.spaceGroup}):a.unitcell=void 0,us(a,!0),cs(a,!0),a.finalizeAtoms(),a.finalizeBonds(),hs(a),t.Debug&&cf.timeEnd("MmtfParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(wx);ff.add("mmtf",Bx);var Fx=/\s+/,zx=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"mol2"},i.prototype._parse=function(){function e(t,e,A){for(var M,P=t;P<e;++P){var T=A[P].trim();if(""!==T&&"#"!==T[0])if("@"===T[0])"@<TRIPOS>MOLECULE"===T?(v=y,d=0,++m):"@<TRIPOS>ATOM"===T?(v=b,f=l.count,s&&(r=0,i=new Float32Array(3*g),c.push(i),m>0&&(u=!0))):v="@<TRIPOS>BOND"===T?x:0;else if(v===y)0===d?(n.title=T,n.id=T):1===d&&(M=T.split(Fx),g=parseInt(M[0])),++d;else if(v===b){if(M=T.split(Fx),a&&m>0)continue;var E=parseFloat(M[2]),C=parseFloat(M[3]),I=parseFloat(M[4]);if(s){var L=3*r;if(i[L+0]=E,i[L+1]=C,i[L+2]=I,r+=1,u)continue}var R=M[0],O=M[1],D=M[5].split(".")[0],N=M[6]?parseInt(M[6]):1,k=M[7]?M[7]:"",B=M[8]?parseFloat(M[8]):0;l.growIfFull(),l.atomTypeId[p]=h.add(O,D),l.x[p]=E,l.y[p]=C,l.z[p]=I,l.serial[p]=R,l.bfactor[p]=B,o.addAtom(m,"","",k,N,1),p+=1}else if(v===x){if(a&&m>0)continue;if(s&&m>0)continue;M=T.split(Fx),_.index=parseInt(M[1])-1+f,w.index=parseInt(M[2])-1+f;var F=S[M[3]];n.bondStore.addBond(_,w,F)}}}t.Debug&&cf.time("Mol2Parser._parse "+this.name);var i,r,n=this.structure,o=this.structureBuilder,a=this.firstModelOnly,s=this.asTrajectory,c=n.frames,u=!1,h=n.atomMap,l=n.atomStore;l.resize(Math.round(this.streamer.data.length/60));var p=0,d=0,f=0,m=-1,g=0,v=0,y=1,b=2,x=3,_=n.getAtomProxy(),w=n.getAtomProxy(),S={1:1,2:2,3:3,am:1,ar:1,du:1,un:1,nc:0};this.streamer.eachChunkOfLines(function(t){e(0,t.length,t)}),o.finalize(),n.finalizeAtoms(),ns(n),cs(n,!0),us(n,!0),n.finalizeBonds(),ps(n),av(n),t.Debug&&cf.timeEnd("Mol2Parser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(wx);ff.add("mol2",zx);var Ux=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"pqr"},Object.defineProperties(e.prototype,i),e}(Tx);ff.add("pqr",Ux);var jx=1,Gx=2,Vx=3,$x=4,Hx=5,Wx=6,Xx=/\s+/,qx=/(^\*|REMARK)*/,Yx=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"psf"},i.prototype._parse=function(){function e(t,e,a){for(var d=t;d<e;++d){var f=a[d].trim();if(f)if(i===Gx){var m=f.split(Xx),g=parseInt(m[0]),v=parseInt(m[2]),y=m[3],b=m[4];u.growIfFull(),u.atomTypeId[l]=c.add(b),u.serial[l]=g,s.addAtom(0,"","",y,v,1),l+=1}else if(i===Vx)for(var x=f.split(Xx),_=0,w=x.length;_<w;_+=2)r[p]=parseInt(x[_])-1,n[p]=parseInt(x[_+1])-1,o[p]=1,p+=1;else if(i===jx)h.push(f.replace(qx,"").trim());else if(i===$x);else if(i===Hx);else if(i===Wx);else if(f.includes("!NATOM")){i=Gx;var S=parseInt(f.split(Xx)[0]);u.resize(S)}else if(f.includes("!NBOND")){i=Vx;var A=parseInt(f.split(Xx)[0]);r=new Uint32Array(A),n=new Uint32Array(A),o=new Uint8Array(A)}else f.includes("!NTITLE")?i=jx:f.includes("!NTHETA")?i=$x:f.includes("!NPHI")?i=Hx:f.includes("!NIMPHI")&&(i=Wx);else i=void 0}}t.Debug&&cf.time("PsfParser._parse "+this.name);var i,r,n,o,a=this.structure,s=this.structureBuilder,c=a.atomMap,u=a.atomStore,h=[],l=0,p=0;this.streamer.eachChunkOfLines(function(t){e(0,t.length,t)}),a.title=h.join(" "),a.bondStore.length=o.length,a.bondStore.count=p,a.bondStore.atomIndex1=r,a.bondStore.atomIndex2=n,a.bondStore.bondOrder=o,s.finalize(),a.finalizeAtoms(),ns(a),a.finalizeBonds(),ps(a),t.Debug&&cf.timeEnd("PsfParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(wx);ff.add("psf",Yx);var Zx=/> <(.+)>/,Kx=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"sdf"},i.prototype._parse=function(){function e(t,e,a){for(var C=t;C<e;++C){var I=a[C];if("$$$$"===I.substr(0,4))v=-1,++y,b=p.count,x.push(w),w={},_=!1;else if(3===v)S=parseInt(I.substr(0,3)),A=parseInt(I.substr(3,3)),E=(T=P=(M=4)+S)+A,o&&(c=0,s=new Float32Array(3*S),u.push(s),y>0&&(h=!0));else if(v>=M&&v<P){if(n&&y>0)continue;var L=parseFloat(I.substr(0,10)),R=parseFloat(I.substr(10,10)),O=parseFloat(I.substr(20,10));if(o){var D=3*c;if(s[D+0]=L,s[D+1]=R,s[D+2]=O,c+=1,h)continue}var N=I.substr(31,3).trim(),k=N+(g+1);p.growIfFull(),p.atomTypeId[g]=l.add(k,N),p.x[g]=L,p.y[g]=R,p.z[g]=O,p.serial[g]=g,r.addAtom(y,"","","HET",1,1),g+=1}else if(v>=T&&v<E){if(n&&y>0)continue;if(o&&y>0)continue;f.index=parseInt(I.substr(0,3))-1+b,m.index=parseInt(I.substr(3,3))-1+b;var B=parseInt(I.substr(6,3));i.bondStore.addBond(f,m,B)}else(d=I.match(Zx))?(_=d[1],w[_]=[]):!1!==_&&I&&w[_].push(I);++v}}t.Debug&&cf.time("SdfParser._parse "+this.name);var i=this.structure,r=this.structureBuilder,n=this.firstModelOnly,o=this.asTrajectory,a=this.streamer.peekLines(2);i.id=a[0].trim(),i.title=a[1].trim();var s,c,u=i.frames,h=!1,l=i.atomMap,p=i.atomStore;p.resize(Math.round(this.streamer.data.length/50));var d,f=i.getAtomProxy(),m=i.getAtomProxy(),g=0,v=0,y=0,b=0,x=[],_=!1,w={};i.extraData.sdf=x;var S,A,M,P,T,E;this.streamer.eachChunkOfLines(function(t){e(0,t.length,t)}),r.finalize(),i.finalizeAtoms(),i.finalizeBonds(),ps(i),t.Debug&&cf.timeEnd("SdfParser._parse "+this.name)},i.prototype._postProcess=function(){ps(this.structure)},Object.defineProperties(i.prototype,r),i}(wx);ff.add("sdf",Kx),ff.add("sd",Kx);var Qx=function(t,e){this.name=t,this.path=e,this.coordinates=[],this.boxes=[]},Jx={type:{}};Jx.type.get=function(){return"Frames"},Object.defineProperties(Qx.prototype,Jx);var t_=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"dcd"},i.prototype._parse=function(){t.Debug&&cf.time("DcdParser._parse "+this.name);var e=this.streamer.data;e instanceof Uint8Array&&(e=e.buffer);var i,r,n=new DataView(e),o=this.frames,a=o.coordinates,s=o.boxes,c={},u=0,h=new Int32Array(e,0,23),l=h[0]!==n.getInt32(0);if(84!==h[0])for(r=e.byteLength,i=0;i<r;i+=4)n.setFloat32(i,n.getFloat32(i),!0);84!==h[0]&&cf.error("dcd bad format, header block start"),"CORD"!==String.fromCharCode(n.getUint8(4),n.getUint8(5),n.getUint8(6),n.getUint8(7))&&cf.error("dcd bad format, format string");var p=!1,d=!1,f=!1;0!==h[22]&&(p=!0,0!==h[12]&&(d=!0),1===h[13]&&(f=!0)),c.NSET=h[2],c.ISTART=h[3],c.NSAVC=h[4],c.NAMNF=h[10],c.DELTA=p?n.getFloat32(44,l):n.getFloat64(44,l),84!==h[22]&&cf.error("dcd bad format, header block end"),u=u+84+8;var m=n.getInt32(u,l),g=u+1;if((m-4)%80!=0&&cf.error("dcd bad format, title block start"),c.TITLE=Pn(new Uint8Array(e,g,m)),n.getInt32(g+m+4-1,l)!==m&&cf.error("dcd bad format, title block end"),u=u+m+8,4!==n.getInt32(u,l)&&cf.error("dcd bad format, natom block start"),c.NATOM=n.getInt32(u+4,l),4!==n.getInt32(u+8,l)&&cf.error("dcd bad format, natom block end"),u=u+4+8,c.NAMNF>0)return void cf.error("dcd format with fixed atoms unsupported, aborting");var v=c.NATOM,y=4*v;for(i=0,r=c.NSET;i<r;++i){if(d){u+=4;var b=new Float32Array(9);b[0]=n.getFloat64(u,l),b[4]=n.getFloat64(u+16,l),b[8]=n.getFloat64(u+40,l),s.push(b),u+=48,u+=4}for(var x=new Float32Array(3*v),_=0;_<3;++_){n.getInt32(u,l)!==y&&cf.error("dcd bad format, coord block start",i,_),u+=4;for(var w=new Float32Array(e,u,v),S=0;S<v;++S)x[3*S+_]=w[S];u+=y,n.getInt32(u,l)!==y&&cf.error("dcd bad format, coord block end",i,_),u+=4}a.push(x),f&&(u+=4+n.getInt32(u,l)+4)}t.Debug&&cf.timeEnd("DcdParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(function(t){function e(e,i){t.call(this,e,i),this.frames=new Qx(this.name,this.path)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},__objName:{}};return i.type.get=function(){return"trajectory"},i.__objName.get=function(){return"frames"},Object.defineProperties(e.prototype,i),e}(xx));ff.add("dcd",t_);var e_=function(t){function e(e,i){var r=i||{};t.call(this,e,r),this.volume=new Vg(this.name,this.path),this.voxelSize=dn(r.voxelSize,1)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},__objName:{}};return i.type.get=function(){return"volume"},i.__objName.get=function(){return"volume"},e.prototype._afterParse=function(){this.volume.setMatrix(this.getMatrix())},e.prototype.getMatrix=function(){return new v},Object.defineProperties(e.prototype,i),e}(xx),i_=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"cube"},i.prototype._parse=function(){function e(t,e){var i=n[t].trim().split(a)[e];return parseFloat(i)}function i(t,e,i){for(var r=t;r<e;++r){var n=i[r].trim();if(""!==n&&h>=o.atomCount+6+l)for(var s=0,p=(n=n.split(a)).length;s<p;++s)1!==n.length&&(c[u]=parseFloat(n[s]),++u);++h}}t.Debug&&cf.time("CubeParser._parse "+this.name);var r=this.volume,n=this.streamer.peekLines(6),o={},a=/\s+/,s=.529177210859*this.voxelSize;o.atomCount=Math.abs(e(2,0)),o.originX=.529177210859*e(2,1),o.originY=.529177210859*e(2,2),o.originZ=.529177210859*e(2,3),o.NVX=e(3,0),o.NVY=e(4,0),o.NVZ=e(5,0),o.basisX=new g(e(3,1),e(3,2),e(3,3)).multiplyScalar(s),o.basisY=new g(e(4,1),e(4,2),e(4,3)).multiplyScalar(s),o.basisZ=new g(e(5,1),e(5,2),e(5,3)).multiplyScalar(s);var c=new Float32Array(o.NVX*o.NVY*o.NVZ),u=0,h=0,l=e(2,0)>0?0:1;this.streamer.eachChunkOfLines(function(t){i(0,t.length,t)}),r.header=o,r.setData(c,o.NVZ,o.NVY,o.NVX),t.Debug&&cf.timeEnd("CubeParser._parse "+this.name)},i.prototype.getMatrix=function(){var t=this.volume.header,e=new v;return e.multiply((new v).makeTranslation(t.originX,t.originY,t.originZ)),e.multiply((new v).makeBasis(t.basisZ,t.basisY,t.basisX)),e},Object.defineProperties(i.prototype,r),i}(e_);ff.add("cub",i_),ff.add("cube",i_);var r_=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"dsn6"},i.prototype._parse=function(){t.Debug&&cf.time("Dsn6Parser._parse "+this.name);var e=this.streamer.data;e instanceof Uint8Array&&(e=e.buffer);var i,r,n=this.volume,o={},a=new Int16Array(e),s=new Uint8Array(e),c=String.fromCharCode.apply(null,s.subarray(0,512));if(c.startsWith(":-)"))o.xStart=parseInt(c.substr(10,5)),o.yStart=parseInt(c.substr(15,5)),o.zStart=parseInt(c.substr(20,5)),o.xExtent=parseInt(c.substr(32,5)),o.yExtent=parseInt(c.substr(38,5)),o.zExtent=parseInt(c.substr(42,5)),o.xRate=parseInt(c.substr(52,5)),o.yRate=parseInt(c.substr(58,5)),o.zRate=parseInt(c.substr(62,5)),o.xlen=parseFloat(c.substr(73,10))*this.voxelSize,o.ylen=parseFloat(c.substr(83,10))*this.voxelSize,o.zlen=parseFloat(c.substr(93,10))*this.voxelSize,o.alpha=parseFloat(c.substr(103,10)),o.beta=parseFloat(c.substr(113,10)),o.gamma=parseFloat(c.substr(123,10)),i=parseFloat(c.substr(138,12))/100,r=parseInt(c.substr(155,8));else{if(100!==a[18])for(var u=0,h=a.length;u<h;++u){var l=a[u];a[u]=(255&l)<<8|l>>8&255}o.xStart=a[0],o.yStart=a[1],o.zStart=a[2],o.xExtent=a[3],o.yExtent=a[4],o.zExtent=a[5],o.xRate=a[6],o.yRate=a[7],o.zRate=a[8];var p=1/a[17],d=p*this.voxelSize;o.xlen=a[9]*d,o.ylen=a[10]*d,o.zlen=a[11]*d,o.alpha=a[12]*p,o.beta=a[13]*p,o.gamma=a[14]*p,i=a[15]/100,r=a[16]}n.header=o,cf.log(o,i,r);for(var f=new Float32Array(o.xExtent*o.yExtent*o.zExtent),m=512,g=Math.ceil(o.xExtent/8),v=Math.ceil(o.yExtent/8),y=Math.ceil(o.zExtent/8),b=0;b<y;++b)for(var x=0;x<v;++x)for(var _=0;_<g;++_)for(var w=0;w<8;++w)for(var S=8*b+w,A=0;A<8;++A)for(var M=8*x+A,P=0;P<8;++P){var T=8*_+P;if(!(T<o.xExtent&&M<o.yExtent&&S<o.zExtent)){m+=8-P;break}f[(T*o.yExtent+M)*o.zExtent+S]=(s[m]-r)/i,++m}n.setData(f,o.zExtent,o.yExtent,o.xExtent),t.Debug&&cf.timeEnd("Dsn6Parser._parse "+this.name)},i.prototype.getMatrix=function(){var t=this.volume.header,e=[t.xlen,0,0],i=[t.ylen*Math.cos(Math.PI/180*t.gamma),t.ylen*Math.sin(Math.PI/180*t.gamma),0],r=[t.zlen*Math.cos(Math.PI/180*t.beta),t.zlen*(Math.cos(Math.PI/180*t.alpha)-Math.cos(Math.PI/180*t.gamma)*Math.cos(Math.PI/180*t.beta))/Math.sin(Math.PI/180*t.gamma),0];r[2]=Math.sqrt(t.zlen*t.zlen*Math.sin(Math.PI/180*t.beta)*Math.sin(Math.PI/180*t.beta)-r[1]*r[1]);var n=[0,e,i,r],o=[0,t.xRate,t.yRate,t.zRate],a=[0,1,2,3],s=new v;return s.set(n[a[1]][0]/o[a[1]],n[a[2]][0]/o[a[2]],n[a[3]][0]/o[a[3]],0,n[a[1]][1]/o[a[1]],n[a[2]][1]/o[a[2]],n[a[3]][1]/o[a[3]],0,n[a[1]][2]/o[a[1]],n[a[2]][2]/o[a[2]],n[a[3]][2]/o[a[3]],0,0,0,0,1),s.multiply((new v).makeRotationY(Gn(90))),s.multiply((new v).makeTranslation(-t.zStart,t.yStart,t.xStart)),s.multiply((new v).makeScale(-1,1,1)),s},Object.defineProperties(i.prototype,r),i}(e_);ff.add("dsn6",r_),ff.add("brix",r_);var n_=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"dx"},i.prototype._parse=function(){function e(t,e,i){for(var r=t;r<e;++r){if(h<c&&l>a){var n=i[r].trim();if(""!==n)for(var o=n.split(s),p=0,d=o.length;p<d;++p)u[h]=parseFloat(o[p]),++h}++l}}t.Debug&&cf.time("DxParser._parse "+this.name);var i=this.volume,r=this.streamer.peekLines(30),n=this.parseHeaderLines(r),o=this.volume.header,a=n.dataLineStart,s=/\s+/,c=o.nx*o.ny*o.nz,u=new Float32Array(c),h=0,l=0;this.streamer.eachChunkOfLines(function(t){e(0,t.length,t)}),i.setData(u,o.nz,o.ny,o.nx),t.Debug&&cf.timeEnd("DxParser._parse "+this.name)},i.prototype.parseHeaderLines=function(t){for(var e=this,i={},r=t.length,n=0,o=0,a=0,s=0;s<r;++s){var c,u=t[s];if(u.startsWith("object 1"))c=u.split(/\s+/),i.nx=parseInt(c[5]),i.ny=parseInt(c[6]),i.nz=parseInt(c[7]);else if(u.startsWith("origin"))c=u.split(/\s+/),i.xmin=parseFloat(c[1]),i.ymin=parseFloat(c[2]),i.zmin=parseFloat(c[3]);else if(u.startsWith("delta"))c=u.split(/\s+/),0===a?i.hx=parseFloat(c[1])*e.voxelSize:1===a?i.hy=parseFloat(c[2])*e.voxelSize:2===a&&(i.hz=parseFloat(c[3])*e.voxelSize),a+=1;else if(u.startsWith("object 3")){n=s,o+=u.length+1;break}o+=u.length+1}return this.volume.header=i,{dataLineStart:n,headerByteCount:o}},i.prototype.getMatrix=function(){var t=this.volume.header,e=new v;return e.multiply((new v).makeRotationY(Gn(90))),e.multiply((new v).makeTranslation(-t.zmin,t.ymin,t.xmin)),e.multiply((new v).makeScale(-t.hz,t.hy,t.hx)),e},Object.defineProperties(i.prototype,r),i}(e_);ff.add("dx",n_);var o_=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"dxbin"},i.prototype._parse=function(){t.Debug&&cf.time("DxbinParser._parse "+this.name);var e=this.streamer.data;e instanceof Uint8Array&&(e=e.buffer);for(var i=Tn(new Uint8Array(e,0,1e3)),r=this.parseHeaderLines(i),n=this.volume.header,o=r.headerByteCount,a=n.nx*n.ny*n.nz,s=new DataView(e),c=new Float32Array(a),u=0;u<a;++u)c[u]=s.getFloat64(8*u+o,!0);this.volume.setData(c,n.nz,n.ny,n.nx),t.Debug&&cf.timeEnd("DxbinParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(n_);ff.add("dxbin",o_);var a_=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"mrc"},i.prototype._parse=function(){t.Debug&&cf.time("MrcParser._parse "+this.name);var e=this.streamer.data;e instanceof Uint8Array&&(e=e.buffer);var i=this.volume,r={},n=new Int32Array(e,0,56),o=new Float32Array(e,0,56),a=new DataView(e);if(r.MAP=String.fromCharCode(a.getUint8(208),a.getUint8(209),a.getUint8(210),a.getUint8(211)),r.MACHST=[a.getUint8(212),a.getUint8(213)],17===r.MACHST[0]&&17===r.MACHST[1])for(var s=e.byteLength,c=0;c<s;c+=4)a.setFloat32(c,a.getFloat32(c),!0);r.NX=n[0],r.NY=n[1],r.NZ=n[2],r.MODE=n[3],r.NXSTART=n[4],r.NYSTART=n[5],r.NZSTART=n[6],r.MX=n[7],r.MY=n[8],r.MZ=n[9],r.xlen=o[10]*this.voxelSize,r.ylen=o[11]*this.voxelSize,r.zlen=o[12]*this.voxelSize,r.alpha=o[13],r.beta=o[14],r.gamma=o[15],r.MAPC=n[16],r.MAPR=n[17],r.MAPS=n[18],r.DMIN=o[19],r.DMAX=o[20],r.DMEAN=o[21],r.ISPG=n[22],r.NSYMBT=n[23],r.LSKFLG=n[24],r.originX=o[49],r.originY=o[50],r.originZ=o[51],r.ARMS=o[54],i.header=r;var u;if(2===r.MODE)u=new Float32Array(e,1024+r.NSYMBT,r.NX*r.NY*r.NZ);else if(0===r.MODE){if(u=new Float32Array(new Int8Array(e,1024+r.NSYMBT,r.NX*r.NY*r.NZ)),-128===n[39]&&127===n[40])for(var h=(r.DMAX-r.DMIN)/255,l=.5*(r.DMIN+r.DMAX+h),p=0,d=u.length;p<d;++p)u[p]=h*u[p]+l}else cf.error("MrcParser unknown mode",r.MODE);i.setData(u,r.NX,r.NY,r.NZ),t.Debug&&cf.timeEnd("MrcParser._parse "+this.name)},i.prototype.getMatrix=function(){var t=this.volume.header,e=[t.xlen,0,0],i=[t.ylen*Math.cos(Math.PI/180*t.gamma),t.ylen*Math.sin(Math.PI/180*t.gamma),0],r=[t.zlen*Math.cos(Math.PI/180*t.beta),t.zlen*(Math.cos(Math.PI/180*t.alpha)-Math.cos(Math.PI/180*t.gamma)*Math.cos(Math.PI/180*t.beta))/Math.sin(Math.PI/180*t.gamma),0];r[2]=Math.sqrt(t.zlen*t.zlen*Math.sin(Math.PI/180*t.beta)*Math.sin(Math.PI/180*t.beta)-r[1]*r[1]);var n=[0,e,i,r],o=[0,t.MX,t.MY,t.MZ],a=[0,t.MAPC,t.MAPR,t.MAPS],s=new v;return s.set(n[a[1]][0]/o[a[1]],n[a[2]][0]/o[a[2]],n[a[3]][0]/o[a[3]],0,n[a[1]][1]/o[a[1]],n[a[2]][1]/o[a[2]],n[a[3]][1]/o[a[3]],0,n[a[1]][2]/o[a[1]],n[a[2]][2]/o[a[2]],n[a[3]][2]/o[a[3]],0,0,0,0,1),s.setPosition(new g(t.originX,t.originY,t.originZ)),s.multiply((new v).makeTranslation(t.NXSTART,t.NYSTART,t.NZSTART)),s},Object.defineProperties(i.prototype,r),i}(e_);ff.add("mrc",a_),ff.add("ccp4",a_),ff.add("map",a_);var s_=function(e){function i(){e.apply(this,arguments)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{}};return r.type.get=function(){return"xplor"},i.prototype._parse=function(){function e(t){return t.trim().split(s).map(parseFloat)}function i(t,e,i){for(var r=t;r<e;++r){var n=i[r];if(v>=c&&(v-c)%y!=0&&g<f)for(var o=0;o<6;++o)m[g]=parseFloat(n.substr(12*o,12)),++g;++v}}t.Debug&&cf.time("XplorParser._parse "+this.name);var r,n=this.volume,o=this.streamer.peekLines(8),a={},s=/\s+/,c=(r=o[2].startsWith("REMARKS")?parseInt(o[1].substring(0,8))+2:5)+3,u=e(o[r]);a.NA=u[0],a.AMIN=u[1],a.AMAX=u[2],a.NB=u[3],a.BMIN=u[4],a.BMAX=u[5],a.NC=u[6],a.CMIN=u[7],a.CMAX=u[8];var h=e(o[r+1]);a.a=h[0]*this.voxelSize,a.b=h[1]*this.voxelSize,a.c=h[2]*this.voxelSize,a.alpha=h[3],a.beta=h[4],a.gamma=h[5];var l=a.AMAX-a.AMIN+1,p=a.BMAX-a.BMIN+1,d=a.CMAX-a.CMIN+1,f=l*p*d,m=new Float32Array(f),g=0,v=0,y=1+l*p/6;this.streamer.eachChunkOfLines(function(t){i(0,t.length,t)}),n.header=a,n.setData(m,l,p,d),t.Debug&&cf.timeEnd("XplorParser._parse "+this.name)},i.prototype.getMatrix=function(){var t=this.volume.header,e=[t.a,0,0],i=[t.b*Math.cos(Math.PI/180*t.gamma),t.b*Math.sin(Math.PI/180*t.gamma),0],r=[t.c*Math.cos(Math.PI/180*t.beta),t.c*(Math.cos(Math.PI/180*t.alpha)-Math.cos(Math.PI/180*t.gamma)*Math.cos(Math.PI/180*t.beta))/Math.sin(Math.PI/180*t.gamma),0];r[2]=Math.sqrt(t.c*t.c*Math.sin(Math.PI/180*t.beta)*Math.sin(Math.PI/180*t.beta)-r[1]*r[1]);var n=[0,e,i,r],o=[0,t.NA,t.NB,t.NC],a=[0,1,2,3],s=new v;return s.set(n[a[1]][0]/o[a[1]],n[a[2]][0]/o[a[2]],n[a[3]][0]/o[a[3]],0,n[a[1]][1]/o[a[1]],n[a[2]][1]/o[a[2]],n[a[3]][1]/o[a[3]],0,n[a[1]][2]/o[a[1]],n[a[2]][2]/o[a[2]],n[a[3]][2]/o[a[3]],0,0,0,0,1),s.multiply((new v).makeTranslation(t.AMIN,t.BMIN,t.CMIN)),s},Object.defineProperties(i.prototype,r),i}(e_);ff.add("xplor",s_),ff.add("cns",s_);var c_=function(t){function e(e,i){t.call(this,e,i),this.loader=this.getLoader(),this.surface=new jg(this.name,this.path)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},__objName:{}};return i.type.get=function(){return"surface"},i.__objName.get=function(){return"surface"},e.prototype._parse=function(){var t=this.loader.parse(this.streamer.asText());this.surface.fromGeometry(t)},Object.defineProperties(e.prototype,i),e}(xx);Mc.prototype={constructor:Mc,setPath:function(t){this.path=t},_createParserState:function(){var t={objects:[],object:{},vertices:[],normals:[],startObject:function(t,e){if(this.object&&!1===this.object.fromDeclaration)return this.object.name=t,void(this.object.fromDeclaration=!1!==e);this.object={name:t||"",geometry:{vertices:[],normals:[]},fromDeclaration:!1!==e},this.objects.push(this.object)},parseVertexIndex:function(t,e){var i=parseInt(t,10);return 3*(i>=0?i-1:i+e/3)},parseNormalIndex:function(t,e){var i=parseInt(t,10);return 3*(i>=0?i-1:i+e/3)},addVertex:function(t,e,i){var r=this.vertices,n=this.object.geometry.vertices;n.push(r[t+0]),n.push(r[t+1]),n.push(r[t+2]),n.push(r[e+0]),n.push(r[e+1]),n.push(r[e+2]),n.push(r[i+0]),n.push(r[i+1]),n.push(r[i+2])},addVertexLine:function(t){var e=this.vertices,i=this.object.geometry.vertices;i.push(e[t+0]),i.push(e[t+1]),i.push(e[t+2])},addNormal:function(t,e,i){var r=this.normals,n=this.object.geometry.normals;n.push(r[t+0]),n.push(r[t+1]),n.push(r[t+2]),n.push(r[e+0]),n.push(r[e+1]),n.push(r[e+2]),n.push(r[i+0]),n.push(r[i+1]),n.push(r[i+2])},addFace:function(t,e,i,r,n,o,a,s){var c,u=this.vertices.length,h=this.parseVertexIndex(t,u),l=this.parseVertexIndex(e,u),p=this.parseVertexIndex(i,u);if(void 0===r?this.addVertex(h,l,p):(c=this.parseVertexIndex(r,u),this.addVertex(h,l,c),this.addVertex(l,p,c)),void 0!==n){var d=this.normals.length;h=this.parseNormalIndex(n,d),l=n===o?h:this.parseNormalIndex(o,d),p=n===a?h:this.parseNormalIndex(a,d),void 0===r?this.addNormal(h,l,p):(c=this.parseNormalIndex(s,d),this.addNormal(h,l,c),this.addNormal(l,p,c))}},addLineGeometry:function(t){var e=this;this.object.geometry.type="Line";for(var i=this.vertices.length,r=0,n=t.length;r<n;r++)e.addVertexLine(e.parseVertexIndex(t[r],i))}};return t.startObject("",!1),t},parse:function(t){var e=this,i=this._createParserState();-1!==t.indexOf("\r\n")&&(t=t.replace(/\r\n/g,"\n")),-1!==t.indexOf("\\\n")&&(t=t.replace(/\\\n/g,""));var r,n,o=t.split("\n"),a="",s="",c="",u=[],h="function"==typeof"".trimLeft;for(r=0,n=o.length;r<n;r++)if(a=o[r],a=h?a.trimLeft():a.trim(),0!==a.length&&"#"!==(s=a.charAt(0)))if("v"===s){if(" "===(c=a.charAt(1))&&null!==(u=e.regexp.vertex_pattern.exec(a)))i.vertices.push(parseFloat(u[1]),parseFloat(u[2]),parseFloat(u[3]));else if("n"===c&&null!==(u=e.regexp.normal_pattern.exec(a)))i.normals.push(parseFloat(u[1]),parseFloat(u[2]),parseFloat(u[3]));else if("t"!==c||null===(u=e.regexp.uv_pattern.exec(a)))throw new Error("Unexpected vertex/normal/uv line: '"+a+"'")}else if("f"===s)if(null!==(u=e.regexp.face_vertex_uv_normal.exec(a)))i.addFace(u[1],u[4],u[7],u[10],u[3],u[6],u[9],u[12]);else if(null!==(u=e.regexp.face_vertex_uv.exec(a)));else if(null!==(u=e.regexp.face_vertex_normal.exec(a)))i.addFace(u[1],u[3],u[5],u[7],u[2],u[4],u[6],u[8]);else{if(null===(u=e.regexp.face_vertex.exec(a)))throw new Error("Unexpected face line: '"+a+"'");i.addFace(u[1],u[2],u[3],u[4])}else if("l"===s){var l=a.substring(1).trim().split(" "),p=[],d=[];if(-1===a.indexOf("/"))p=l;else for(var f=0,m=l.length;f<m;f++){var g=l[f].split("/");""!==g[0]&&p.push(g[0]),""!==g[1]&&d.push(g[1])}i.addLineGeometry(p,d)}else if(null!==(u=e.regexp.object_pattern.exec(a))){var v=u[0].substr(1).trim();i.startObject(v)}else if(e.regexp.material_use_pattern.test(a));else if(e.regexp.material_library_pattern.test(a));else if(null===(u=e.regexp.smoothing_pattern.exec(a))){if("\0"===a)continue;throw new Error("Unexpected line: '"+a+"'")}var y=[];for(r=0,n=i.objects.length;r<n;r++){var b=i.objects[r].geometry;if(0!==b.vertices.length){var x=new Ct;x.addAttribute("position",new _t(new Float32Array(b.vertices),3)),b.normals.length>0?x.addAttribute("normal",new _t(new Float32Array(b.normals),3)):x.computeVertexNormals(),y.push(x)}}return y}};var u_=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"obj"},e.prototype.getLoader=function(){return new Mc},Object.defineProperties(e.prototype,i),e}(c_);ff.add("obj",u_),Pc.prototype={constructor:Pc,setPropertyNameMapping:function(t){this.propertyNameMapping=t},bin2str:function(t){for(var e=new Uint8Array(t),i="",r=0;r<t.byteLength;r++)i+=String.fromCharCode(e[r]);return i},isASCII:function(t){return"ascii"===this.parseHeader(this.bin2str(t)).format},parse:function(t){return t instanceof ArrayBuffer?this.isASCII(t)?this.parseASCII(this.bin2str(t)):this.parseBinary(t):this.parseASCII(t)},parseHeader:function(t){var e=this,i="",r=0,n=/ply([\s\S]*)end_header\s/.exec(t);null!==n&&(i=n[1],r=n[0].length);for(var o,a,s,c={comments:[],elements:[],headerLength:r},u=i.split("\n"),h=0;h<u.length;h++){var l=u[h];if(""!==(l=l.trim()))switch(s=l.split(/\s+/),a=s.shift(),l=s.join(" "),a){case"format":c.format=s[0],c.version=s[1];break;case"comment":c.comments.push(l);break;case"element":void 0!==o&&c.elements.push(o),(o={}).name=s[0],o.count=parseInt(s[1]),o.properties=[];break;case"property":o.properties.push(function(t,e){var i={type:t[0]};return"list"===i.type?(i.name=t[3],i.countType=t[1],i.itemType=t[2]):i.name=t[1],i.name in e&&(i.name=e[i.name]),i}(s,e.propertyNameMapping));break;default:console.log("unhandled",a,s)}}return void 0!==o&&c.elements.push(o),c},parseASCIINumber:function(t,e){switch(e){case"char":case"uchar":case"short":case"ushort":case"int":case"uint":case"int8":case"uint8":case"int16":case"uint16":case"int32":case"uint32":return parseInt(t);case"float":case"double":case"float32":case"float64":return parseFloat(t)}},parseASCIIElement:function(t,e){for(var i=this,r=e.split(/\s+/),n={},o=0;o<t.length;o++)if("list"===t[o].type){for(var a=[],s=i.parseASCIINumber(r.shift(),t[o].countType),c=0;c<s;c++)a.push(i.parseASCIINumber(r.shift(),t[o].itemType));n[t[o].name]=a}else n[t[o].name]=i.parseASCIINumber(r.shift(),t[o].type);return n},parseASCII:function(t){var e,i=this,r=new Et,n=this.parseHeader(t),o="";null!==(e=/end_header\s([\s\S]*)$/.exec(t))&&(o=e[1]);var a=o.split("\n"),s=0,c=0;r.useColor=!1;for(var u=0;u<a.length;u++){var h=a[u];if(""!==(h=h.trim())){c>=n.elements[s].count&&(s++,c=0);var l=i.parseASCIIElement(n.elements[s].properties,h);i.handleElement(r,n.elements[s].name,l),c++}}return this.postProcess(r)},postProcess:function(t){if(t.useColor){for(var e=0;e<t.faces.length;e++)t.faces[e].vertexColors=[t.colors[t.faces[e].a],t.colors[t.faces[e].b],t.colors[t.faces[e].c]];t.elementsNeedUpdate=!0}return t.computeBoundingSphere(),t},handleElement:function(t,e,i){if("vertex"===e){if(t.vertices.push(new g(i.x,i.y,i.z)),"red"in i&&"green"in i&&"blue"in i){t.useColor=!0;var r=new tt;r.setRGB(i.red/255,i.green/255,i.blue/255),t.colors.push(r)}}else if("face"===e){var n=i.vertex_indices;3===n.length?t.faces.push(new bt(n[0],n[1],n[2])):4===n.length&&t.faces.push(new bt(n[0],n[1],n[3]),new bt(n[1],n[2],n[3]))}},binaryRead:function(t,e,i,r){switch(i){case"int8":case"char":return[t.getInt8(e),1];case"uint8":case"uchar":return[t.getUint8(e),1];case"int16":case"short":return[t.getInt16(e,r),2];case"uint16":case"ushort":return[t.getUint16(e,r),2];case"int32":case"int":return[t.getInt32(e,r),4];case"uint32":case"uint":return[t.getUint32(e,r),4];case"float32":case"float":return[t.getFloat32(e,r),4];case"float64":case"double":return[t.getFloat64(e,r),8]}},binaryReadElement:function(t,e,i,r){for(var n,o=this,a={},s=0,c=0;c<i.length;c++)if("list"===i[c].type){var u=[],h=(n=o.binaryRead(t,e+s,i[c].countType,r))[0];s+=n[1];for(var l=0;l<h;l++)n=o.binaryRead(t,e+s,i[c].itemType,r),u.push(n[0]),s+=n[1];a[i[c].name]=u}else n=o.binaryRead(t,e+s,i[c].type,r),a[i[c].name]=n[0],s+=n[1];return[a,s]},parseBinary:function(t){for(var e,i=this,r=new Et,n=this.parseHeader(this.bin2str(t)),o="binary_little_endian"===n.format,a=new DataView(t,n.headerLength),s=0,c=0;c<n.elements.length;c++)for(var u=0;u<n.elements[c].count;u++){s+=(e=i.binaryReadElement(a,s,n.elements[c].properties,o))[1];var h=e[0];i.handleElement(r,n.elements[c].name,h)}return this.postProcess(r)}};var h_=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{}};return i.type.get=function(){return"ply"},e.prototype.getLoader=function(){return new Pc},Object.defineProperties(e.prototype,i),e}(c_);ff.add("ply",h_);var l_=function(t){function e(e,i){var r=i||{};t.call(this,e,r),this.delimiter=dn(r.delimiter,","),this.comment=dn(r.comment,"#"),this.columnNames=dn(r.columnNames,!1),this.table={name:this.name,path:this.path,columnNames:[],data:[]}}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},__objName:{}};return i.type.get=function(){return"csv"},i.__objName.get=function(){return"table"},e.prototype._parse=function(){var t=this,e=this.table.data,i=new RegExp("s*"+this.delimiter+"s*"),r=0;this.streamer.eachChunkOfLines(function(n){for(var o=n.length,a=0;a<o;++a){var s=n[a].trim();if(!s.startsWith(t.comment)){var c=s.split(i);0===r?t.table.columnNames=c:s&&e.push(c),++r}}})},Object.defineProperties(e.prototype,i),e}(xx);ff.add("csv",l_);var p_=function(t){function e(e,i){var r=i||{};t.call(this,e,r),this.string=dn(r.string,!1),this.json={name:this.name,path:this.path,data:{}}}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},__objName:{}};return i.type.get=function(){return"json"},i.__objName.get=function(){return"json"},e.prototype._parse=function(){this.streamer.isBinary()||this.string?this.json.data=JSON.parse(this.streamer.asText()):this.json.data=this.streamer.data},Object.defineProperties(e.prototype,i),e}(xx);ff.add("json",p_);var d_=function(t){function e(e,i){t.call(this,e,i),this.text={name:this.name,path:this.path,data:""}}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var i={type:{},__objName:{}};return i.type.get=function(){return"text"},i.__objName.get=function(){return"text"},e.prototype._parse=function(){this.text.data=this.streamer.asText()},Object.defineProperties(e.prototype,i),e}(xx);ff.add("txt",d_),ff.add("text",d_);var f_=/^['"]|['"]$/g,m_=/^<([\w-:.]+)\s*/,g_=/^([^<]*)/,v_=/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/,y_=function(e){function i(t,i){var r=i||{};e.call(this,t,r),this.useDomParser=dn(r.useDomParser,!1),this.xml={name:this.name,path:this.path,data:{}}}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={type:{},__objName:{}};return r.type.get=function(){return"xml"},r.__objName.get=function(){return"xml"},i.prototype.__xmlParser=function(t){return Ec(t)},i.prototype.__domParser=function(t){return(new window.DOMParser).parseFromString(t,"text/xml")},i.prototype._parse=function(){t.Debug&&cf.time("XmlParser._parse "+this.name),this.useDomParser?this.streamer.data instanceof Document?this.xml.data=this.streamer.data:this.xml.data=this.__domParser(this.streamer.asText()):this.xml.data=this.__xmlParser(this.streamer.asText()),t.Debug&&cf.timeEnd("XmlParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(xx);ff.add("xml",y_);var b_=function(t,e){this.name=t,this.path=e,this.rsrzDict={},this.rsccDict={},this.clashDict={},this.clashArray=[],this.geoDict={},this.geoAtomDict={},this.atomDict={},this.clashSele="NONE"},x_={type:{}};x_.type.get=function(){return"validation"},b_.prototype.fromXml=function(e){t.Debug&&cf.time("Validation.fromXml");var i=this.rsrzDict,r=this.rsccDict,n=this.clashDict,o=this.clashArray,a=this.geoDict,s=this.geoAtomDict,c=this.atomDict,u=e.getElementsByTagName("ModelledSubgroup"),h={},l=[];t.Debug&&cf.time("Validation.fromXml#clashDict");for(var p=0,d=u.length;p<d;++p){var f=u[p],m=f.attributes,g=Cc(m);void 0!==m.rsrz&&(i[g]=parseFloat(m.rsrz.value)),void 0!==m.rscc&&(r[g]=parseFloat(m.rscc.value)),m.sele=g;for(var v=f.getElementsByTagName("clash"),y=0,b=v.length;y<b;++y){var x=v[y].attributes,_=x.atom.value;if("H"!==ls(_)){var w=x.cid.value,S=Cc(m,_,!0);if(c[S]=!0,void 0===h[w])h[w]={sele1:S,res1:g};else{var A=h[w];A.res1!==g&&(A.sele2=S,A.res2=g,l.push(A.res1,g),n[w]=A,o.push(A))}}}}t.Debug&&cf.timeEnd("Validation.fromXml#clashDict");for(var M=0,P=u.length;M<P;++M){var T=u[M],E=T.attributes,C=E.sele;if("."!==E.seq.value){var I=Oc(n,T,E);I>0&&(a[C]=I)}else{var L=T.getElementsByTagName("clash"),R=T.getElementsByTagName("mog-bond-outlier"),O=T.getElementsByTagName("mog-angle-outlier");if(R.length>0||O.length>0||L.length>0){var D={};s[C]=D;for(var N=0,k=L.length;N<k;++N){var B=L[N].attributes;n[B.cid.value]&&Ic(D,B.atom.value,1)}for(var F=0,z=R.length;F<z;++F)R[F].attributes.atoms.value.split(",").forEach(function(t){Ic(D,t,2)});for(var U=0,j=O.length;U<j;++U)O[U].attributes.atoms.value.split(",").forEach(function(t){Ic(D,t,4)})}}}this.clashSele=l.length?l.join(" OR "):"NONE",t.Debug&&cf.timeEnd("Validation.fromXml")},b_.prototype.getClashData=function(e){t.Debug&&cf.time("Validation.getClashData");var i=e||{},r=i.structure,n=r.atomSet,o=new tt(dn(i.color,"#f0027f")),a=r.getAtomProxy(),s=r.getAtomProxy(),c=new g,u=new g,h=new g,l=this.clashArray,p=l.length,d=new Float32Array(3*p),f=new Float32Array(3*p),m=To(p,o.r,o.g,o.b),v=new Float32Array(p),y=new Float32Array(p);t.Debug&&cf.time("Validation.getClashData#atomDict");var b=this.atomDict;r.eachAtom(function(t){var e=Rc(t);!0===b[e]&&(b[e]=t.index)}),t.Debug&&cf.timeEnd("Validation.getClashData#atomDict");var x=0;return l.forEach(function(t,e){if(a.index=b[t.sele1],s.index=b[t.sele2],void 0!==a.index&&void 0!==s.index&&n.isSet(a.index,s.index)){c.subVectors(s,a).setLength(a.vdw),u.copy(a).add(c),c.subVectors(a,s).setLength(s.vdw),h.copy(s).add(c);var i=a.distanceTo(s)/2,r=Math.sqrt(a.vdw*a.vdw-i*i),o=Math.sqrt(s.vdw*s.vdw-i*i);u.toArray(d,3*x),h.toArray(f,3*x),v[x]=(r+o)/2,y[x]=e,++x}}),t.Debug&&cf.timeEnd("Validation.getClashData"),{position1:d.subarray(0,3*x),position2:f.subarray(0,3*x),color:m.subarray(0,3*x),color2:m.subarray(0,3*x),radius:v.subarray(0,x),picking:new Ym(y.subarray(0,x),this,r)}},Object.defineProperties(b_.prototype,x_);var __=function(e){function i(t,i){var r=i||{};e.call(this,t,r),this.useDomParser=!0,this.validation=new b_(this.name,this.path)}e&&(i.__proto__=e),i.prototype=Object.create(e&&e.prototype),i.prototype.constructor=i;var r={__objName:{}};return r.__objName.get=function(){return"validation"},i.prototype._parse=function(){e.prototype._parse.call(this),t.Debug&&cf.time("ValidationParser._parse "+this.name),this.validation.fromXml(this.xml.data),t.Debug&&cf.timeEnd("ValidationParser._parse "+this.name)},Object.defineProperties(i.prototype,r),i}(y_);ff.add("validation",__);var w_,S_,A_=function(){for(var t,e=[],i=0;i<256;i++){t=i;for(var r=0;r<8;r++)t=1&t?3988292384^t>>>1:t>>>1;e[i]=t}return e}(),M_=30,P_=12,T_=15,E_=852,C_=592,I_=0,L_=1,R_=2,O_=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],D_=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],N_=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],k_=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64],B_=0,F_=1,z_=2,U_=4,j_=5,G_=6,V_=0,$_=1,H_=2,W_=-2,X_=-3,q_=-4,Y_=-5,Z_=8,K_=1,Q_=2,J_=3,tw=4,ew=5,iw=6,rw=7,nw=8,ow=9,aw=10,sw=11,cw=12,uw=13,hw=14,lw=15,pw=16,dw=17,fw=18,mw=19,gw=20,vw=21,yw=22,bw=23,xw=24,_w=25,ww=26,Sw=27,Aw=28,Mw=29,Pw=30,Tw=31,Ew=32,Cw=852,Iw=592,Lw=!0,Rw=!0,Ow=!0;try{String.fromCharCode.apply(null,[0])}catch(t){Rw=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){Ow=!1}for(var Dw=new Uint8Array(256),Nw=0;Nw<256;Nw++)Dw[Nw]=Nw>=252?6:Nw>=248?5:Nw>=240?4:Nw>=224?3:Nw>=192?2:1;Dw[254]=Dw[254]=1;var kw=0,Bw={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},Fw=Object.prototype.toString;su.prototype.push=function(t,e){var i,r,n,o,a,s,c=this,u=this.strm,h=this.options.chunkSize,l=this.options.dictionary,p=!1;if(this.ended)return!1;r=e===~~e?e:!0===e?4:0,"string"==typeof t?u.input=iu(t):"[object ArrayBuffer]"===Fw.call(t)?u.input=new Uint8Array(t):u.input=t,u.next_in=0,u.avail_in=u.input.length;do{if(0===u.avail_out&&(u.output=new Uint8Array(h),u.next_out=0,u.avail_out=h),2===(i=Zc(u,0))&&l&&(s="string"==typeof l?tu(l):"[object ArrayBuffer]"===Fw.call(l)?new Uint8Array(l):l,i=Jc(c.strm,s)),-5===i&&!0===p&&(i=kw,p=!1),1!==i&&i!==kw)return c.onEnd(i),c.ended=!0,!1;u.next_out&&(0!==u.avail_out&&1!==i&&(0!==u.avail_in||4!==r&&2!==r)||("string"===c.options.to?(n=nu(u.output,u.next_out),o=u.next_out-n,a=ru(u.output,n),u.next_out=o,u.avail_out=h-o,o&&kc(u.output,u.output,n,o,0),c.onData(a)):c.onData(Nc(u.output,u.next_out)))),0===u.avail_in&&0===u.avail_out&&(p=!0)}while((u.avail_in>0||0===u.avail_out)&&1!==i);return 1===i&&(r=4),4===r?(i=Kc(this.strm),this.onEnd(i),this.ended=!0,i===kw):2!==r||(this.onEnd(kw),u.avail_out=0,!0)},su.prototype.onData=function(t){this.chunks.push(t)},su.prototype.onEnd=function(t){t===kw&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Bc(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},gf.add("gz",uu);var zw="//files.rcsb.org/download/",Uw="//mmtf.rcsb.org/v1.0/full/",jw="//mmtf.rcsb.org/v1.0/reduced/";pf.add("rcsb",new hu);var Gw="//pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/",Vw="/SDF?record_type=3d";pf.add("pubchem",new lu),pf.add("ftp",new pu),pf.add("http",new pu),pf.add("https",new pu);var $w=/^((http|https|ftp):)*\/\//;"undefined"==typeof window||window.Promise||(window.Promise=r),t.Version="0.10.3",t.setDebug=uo,t.DatasourceRegistry=pf,t.StaticDatasource=du,t.ParserRegistry=ff,t.autoLoad=mo,t.RepresentationRegistry=df,t.ColormakerRegistry=lf,t.Colormaker=Dd,t.Selection=Kd,t.PdbWriter=bo,t.Stage=Yy,t.Collection=Hy,t.ComponentCollection=Wy,t.RepresentationCollection=Xy,t.Assembly=iv,t.TrajectoryPlayer=Ev,t.superpose=Is,t.guessElement=ls,t.Queue=ms,t.Counter=Cf,t.throttle=bn,t.download=vn,t.getQuery=pn,t.getDataInfo=fo,t.getFileInfo=yn,t.uniqueArray=Mn,t.BufferRepresentation=Sy,t.SphereBuffer=$v,t.EllipsoidBuffer=Zv,t.CylinderBuffer=oy,t.ConeBuffer=ly,t.ArrowBuffer=dy,t.TextBuffer=vy,t.Shape=xy,t.Kdtree=ts,t.SpatialHash=Fa,t.MolecularSurface=ax,t.LeftMouseButton=1,t.MiddleMouseButton=2,t.RightMouseButton=3,t.MouseActions=Em,t.Signal=io,t.Matrix3=ut,t.Matrix4=v,t.Vector2=l,t.Vector3=g,t.Box3=st,t.Quaternion=m,t.Euler=ft,t.Plane=ht,t.Color=tt,Object.defineProperty(t,"__esModule",{value:!0})});
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('timers-browserify@2.0.2/main.js').setImmediate))
})
/** END DEFINE BLOCK for ngl@0.10.3/dist/ngl.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/draggable.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/draggable.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Draggable 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Draggable
	//>>group: Interactions
	//>>description: Enables dragging functionality for any element.
	//>>docs: http://api.jqueryui.com/draggable/
	//>>demos: http://jqueryui.com/draggable/
	//>>css.structure: ../../themes/base/draggable.css
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/mouse.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/data.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/plugin.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/safe-active-element.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/safe-blur.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/scroll-parent.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/version.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	$.widget( "ui.draggable", $.ui.mouse, {
		version: "1.12.1",
		widgetEventPrefix: "drag",
		options: {
			addClasses: true,
			appendTo: "parent",
			axis: false,
			connectToSortable: false,
			containment: false,
			cursor: "auto",
			cursorAt: false,
			grid: false,
			handle: false,
			helper: "original",
			iframeFix: false,
			opacity: false,
			refreshPositions: false,
			revert: false,
			revertDuration: 500,
			scope: "default",
			scroll: true,
			scrollSensitivity: 20,
			scrollSpeed: 20,
			snap: false,
			snapMode: "both",
			snapTolerance: 20,
			stack: false,
			zIndex: false,
	
			// Callbacks
			drag: null,
			start: null,
			stop: null
		},
		_create: function() {
	
			if ( this.options.helper === "original" ) {
				this._setPositionRelative();
			}
			if ( this.options.addClasses ) {
				this._addClass( "ui-draggable" );
			}
			this._setHandleClassName();
	
			this._mouseInit();
		},
	
		_setOption: function( key, value ) {
			this._super( key, value );
			if ( key === "handle" ) {
				this._removeHandleClassName();
				this._setHandleClassName();
			}
		},
	
		_destroy: function() {
			if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
				this.destroyOnClear = true;
				return;
			}
			this._removeHandleClassName();
			this._mouseDestroy();
		},
	
		_mouseCapture: function( event ) {
			var o = this.options;
	
			// Among others, prevent a drag on a resizable-handle
			if ( this.helper || o.disabled ||
					$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
				return false;
			}
	
			//Quit if we're not on a valid handle
			this.handle = this._getHandle( event );
			if ( !this.handle ) {
				return false;
			}
	
			this._blurActiveElement( event );
	
			this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
	
			return true;
	
		},
	
		_blockFrames: function( selector ) {
			this.iframeBlocks = this.document.find( selector ).map( function() {
				var iframe = $( this );
	
				return $( "<div>" )
					.css( "position", "absolute" )
					.appendTo( iframe.parent() )
					.outerWidth( iframe.outerWidth() )
					.outerHeight( iframe.outerHeight() )
					.offset( iframe.offset() )[ 0 ];
			} );
		},
	
		_unblockFrames: function() {
			if ( this.iframeBlocks ) {
				this.iframeBlocks.remove();
				delete this.iframeBlocks;
			}
		},
	
		_blurActiveElement: function( event ) {
			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
				target = $( event.target );
	
			// Don't blur if the event occurred on an element that is within
			// the currently focused element
			// See #10527, #12472
			if ( target.closest( activeElement ).length ) {
				return;
			}
	
			// Blur any element that currently has focus, see #4261
			$.ui.safeBlur( activeElement );
		},
	
		_mouseStart: function( event ) {
	
			var o = this.options;
	
			//Create and append the visible helper
			this.helper = this._createHelper( event );
	
			this._addClass( this.helper, "ui-draggable-dragging" );
	
			//Cache the helper size
			this._cacheHelperProportions();
	
			//If ddmanager is used for droppables, set the global draggable
			if ( $.ui.ddmanager ) {
				$.ui.ddmanager.current = this;
			}
	
			/*
			 * - Position generation -
			 * This block generates everything position related - it's the core of draggables.
			 */
	
			//Cache the margins of the original element
			this._cacheMargins();
	
			//Store the helper's css position
			this.cssPosition = this.helper.css( "position" );
			this.scrollParent = this.helper.scrollParent( true );
			this.offsetParent = this.helper.offsetParent();
			this.hasFixedAncestor = this.helper.parents().filter( function() {
					return $( this ).css( "position" ) === "fixed";
				} ).length > 0;
	
			//The element's absolute position on the page minus margins
			this.positionAbs = this.element.offset();
			this._refreshOffsets( event );
	
			//Generate the original position
			this.originalPosition = this.position = this._generatePosition( event, false );
			this.originalPageX = event.pageX;
			this.originalPageY = event.pageY;
	
			//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
			( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
	
			//Set a containment if given in the options
			this._setContainment();
	
			//Trigger event + callbacks
			if ( this._trigger( "start", event ) === false ) {
				this._clear();
				return false;
			}
	
			//Recache the helper size
			this._cacheHelperProportions();
	
			//Prepare the droppable offsets
			if ( $.ui.ddmanager && !o.dropBehaviour ) {
				$.ui.ddmanager.prepareOffsets( this, event );
			}
	
			// Execute the drag once - this causes the helper not to be visible before getting its
			// correct position
			this._mouseDrag( event, true );
	
			// If the ddmanager is used for droppables, inform the manager that dragging has started
			// (see #5003)
			if ( $.ui.ddmanager ) {
				$.ui.ddmanager.dragStart( this, event );
			}
	
			return true;
		},
	
		_refreshOffsets: function( event ) {
			this.offset = {
				top: this.positionAbs.top - this.margins.top,
				left: this.positionAbs.left - this.margins.left,
				scroll: false,
				parent: this._getParentOffset(),
				relative: this._getRelativeOffset()
			};
	
			this.offset.click = {
				left: event.pageX - this.offset.left,
				top: event.pageY - this.offset.top
			};
		},
	
		_mouseDrag: function( event, noPropagation ) {
	
			// reset any necessary cached properties (see #5009)
			if ( this.hasFixedAncestor ) {
				this.offset.parent = this._getParentOffset();
			}
	
			//Compute the helpers position
			this.position = this._generatePosition( event, true );
			this.positionAbs = this._convertPositionTo( "absolute" );
	
			//Call plugins and callbacks and use the resulting position if something is returned
			if ( !noPropagation ) {
				var ui = this._uiHash();
				if ( this._trigger( "drag", event, ui ) === false ) {
					this._mouseUp( new $.Event( "mouseup", event ) );
					return false;
				}
				this.position = ui.position;
			}
	
			this.helper[ 0 ].style.left = this.position.left + "px";
			this.helper[ 0 ].style.top = this.position.top + "px";
	
			if ( $.ui.ddmanager ) {
				$.ui.ddmanager.drag( this, event );
			}
	
			return false;
		},
	
		_mouseStop: function( event ) {
	
			//If we are using droppables, inform the manager about the drop
			var that = this,
				dropped = false;
			if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
				dropped = $.ui.ddmanager.drop( this, event );
			}
	
			//if a drop comes from outside (a sortable)
			if ( this.dropped ) {
				dropped = this.dropped;
				this.dropped = false;
			}
	
			if ( ( this.options.revert === "invalid" && !dropped ) ||
					( this.options.revert === "valid" && dropped ) ||
					this.options.revert === true || ( $.isFunction( this.options.revert ) &&
					this.options.revert.call( this.element, dropped ) )
			) {
				$( this.helper ).animate(
					this.originalPosition,
					parseInt( this.options.revertDuration, 10 ),
					function() {
						if ( that._trigger( "stop", event ) !== false ) {
							that._clear();
						}
					}
				);
			} else {
				if ( this._trigger( "stop", event ) !== false ) {
					this._clear();
				}
			}
	
			return false;
		},
	
		_mouseUp: function( event ) {
			this._unblockFrames();
	
			// If the ddmanager is used for droppables, inform the manager that dragging has stopped
			// (see #5003)
			if ( $.ui.ddmanager ) {
				$.ui.ddmanager.dragStop( this, event );
			}
	
			// Only need to focus if the event occurred on the draggable itself, see #10527
			if ( this.handleElement.is( event.target ) ) {
	
				// The interaction is over; whether or not the click resulted in a drag,
				// focus the element
				this.element.trigger( "focus" );
			}
	
			return $.ui.mouse.prototype._mouseUp.call( this, event );
		},
	
		cancel: function() {
	
			if ( this.helper.is( ".ui-draggable-dragging" ) ) {
				this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
			} else {
				this._clear();
			}
	
			return this;
	
		},
	
		_getHandle: function( event ) {
			return this.options.handle ?
				!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
				true;
		},
	
		_setHandleClassName: function() {
			this.handleElement = this.options.handle ?
				this.element.find( this.options.handle ) : this.element;
			this._addClass( this.handleElement, "ui-draggable-handle" );
		},
	
		_removeHandleClassName: function() {
			this._removeClass( this.handleElement, "ui-draggable-handle" );
		},
	
		_createHelper: function( event ) {
	
			var o = this.options,
				helperIsFunction = $.isFunction( o.helper ),
				helper = helperIsFunction ?
					$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
					( o.helper === "clone" ?
						this.element.clone().removeAttr( "id" ) :
						this.element );
	
			if ( !helper.parents( "body" ).length ) {
				helper.appendTo( ( o.appendTo === "parent" ?
					this.element[ 0 ].parentNode :
					o.appendTo ) );
			}
	
			// Http://bugs.jqueryui.com/ticket/9446
			// a helper function can return the original element
			// which wouldn't have been set to relative in _create
			if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
				this._setPositionRelative();
			}
	
			if ( helper[ 0 ] !== this.element[ 0 ] &&
					!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
				helper.css( "position", "absolute" );
			}
	
			return helper;
	
		},
	
		_setPositionRelative: function() {
			if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
				this.element[ 0 ].style.position = "relative";
			}
		},
	
		_adjustOffsetFromHelper: function( obj ) {
			if ( typeof obj === "string" ) {
				obj = obj.split( " " );
			}
			if ( $.isArray( obj ) ) {
				obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
			}
			if ( "left" in obj ) {
				this.offset.click.left = obj.left + this.margins.left;
			}
			if ( "right" in obj ) {
				this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
			}
			if ( "top" in obj ) {
				this.offset.click.top = obj.top + this.margins.top;
			}
			if ( "bottom" in obj ) {
				this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
			}
		},
	
		_isRootNode: function( element ) {
			return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
		},
	
		_getParentOffset: function() {
	
			//Get the offsetParent and cache its position
			var po = this.offsetParent.offset(),
				document = this.document[ 0 ];
	
			// This is a special case where we need to modify a offset calculated on start, since the
			// following happened:
			// 1. The position of the helper is absolute, so it's position is calculated based on the
			// next positioned parent
			// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
			// the document, which means that the scroll is included in the initial calculation of the
			// offset of the parent, and never recalculated upon drag
			if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
					$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
				po.left += this.scrollParent.scrollLeft();
				po.top += this.scrollParent.scrollTop();
			}
	
			if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
				po = { top: 0, left: 0 };
			}
	
			return {
				top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
				left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
			};
	
		},
	
		_getRelativeOffset: function() {
			if ( this.cssPosition !== "relative" ) {
				return { top: 0, left: 0 };
			}
	
			var p = this.element.position(),
				scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
	
			return {
				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
					( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
					( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
			};
	
		},
	
		_cacheMargins: function() {
			this.margins = {
				left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
				top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
				right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
				bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
			};
		},
	
		_cacheHelperProportions: function() {
			this.helperProportions = {
				width: this.helper.outerWidth(),
				height: this.helper.outerHeight()
			};
		},
	
		_setContainment: function() {
	
			var isUserScrollable, c, ce,
				o = this.options,
				document = this.document[ 0 ];
	
			this.relativeContainer = null;
	
			if ( !o.containment ) {
				this.containment = null;
				return;
			}
	
			if ( o.containment === "window" ) {
				this.containment = [
					$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
					$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
					$( window ).scrollLeft() + $( window ).width() -
						this.helperProportions.width - this.margins.left,
					$( window ).scrollTop() +
						( $( window ).height() || document.body.parentNode.scrollHeight ) -
						this.helperProportions.height - this.margins.top
				];
				return;
			}
	
			if ( o.containment === "document" ) {
				this.containment = [
					0,
					0,
					$( document ).width() - this.helperProportions.width - this.margins.left,
					( $( document ).height() || document.body.parentNode.scrollHeight ) -
						this.helperProportions.height - this.margins.top
				];
				return;
			}
	
			if ( o.containment.constructor === Array ) {
				this.containment = o.containment;
				return;
			}
	
			if ( o.containment === "parent" ) {
				o.containment = this.helper[ 0 ].parentNode;
			}
	
			c = $( o.containment );
			ce = c[ 0 ];
	
			if ( !ce ) {
				return;
			}
	
			isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
	
			this.containment = [
				( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
					( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
				( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
					( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
				( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
					( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
					( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
					this.helperProportions.width -
					this.margins.left -
					this.margins.right,
				( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
					( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
					( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
					this.helperProportions.height -
					this.margins.top -
					this.margins.bottom
			];
			this.relativeContainer = c;
		},
	
		_convertPositionTo: function( d, pos ) {
	
			if ( !pos ) {
				pos = this.position;
			}
	
			var mod = d === "absolute" ? 1 : -1,
				scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
	
			return {
				top: (
	
					// The absolute mouse position
					pos.top	+
	
					// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.relative.top * mod +
	
					// The offsetParent's offset without borders (offset + border)
					this.offset.parent.top * mod -
					( ( this.cssPosition === "fixed" ?
						-this.offset.scroll.top :
						( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
				),
				left: (
	
					// The absolute mouse position
					pos.left +
	
					// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.relative.left * mod +
	
					// The offsetParent's offset without borders (offset + border)
					this.offset.parent.left * mod	-
					( ( this.cssPosition === "fixed" ?
						-this.offset.scroll.left :
						( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
				)
			};
	
		},
	
		_generatePosition: function( event, constrainPosition ) {
	
			var containment, co, top, left,
				o = this.options,
				scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
				pageX = event.pageX,
				pageY = event.pageY;
	
			// Cache the scroll
			if ( !scrollIsRootNode || !this.offset.scroll ) {
				this.offset.scroll = {
					top: this.scrollParent.scrollTop(),
					left: this.scrollParent.scrollLeft()
				};
			}
	
			/*
			 * - Position constraining -
			 * Constrain the position to a mix of grid, containment.
			 */
	
			// If we are not dragging yet, we won't check for options
			if ( constrainPosition ) {
				if ( this.containment ) {
					if ( this.relativeContainer ) {
						co = this.relativeContainer.offset();
						containment = [
							this.containment[ 0 ] + co.left,
							this.containment[ 1 ] + co.top,
							this.containment[ 2 ] + co.left,
							this.containment[ 3 ] + co.top
						];
					} else {
						containment = this.containment;
					}
	
					if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
						pageX = containment[ 0 ] + this.offset.click.left;
					}
					if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
						pageY = containment[ 1 ] + this.offset.click.top;
					}
					if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
						pageX = containment[ 2 ] + this.offset.click.left;
					}
					if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
						pageY = containment[ 3 ] + this.offset.click.top;
					}
				}
	
				if ( o.grid ) {
	
					//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
					// argument errors in IE (see ticket #6950)
					top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
						this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
					pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
						top - this.offset.click.top > containment[ 3 ] ) ?
							top :
							( ( top - this.offset.click.top >= containment[ 1 ] ) ?
								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
	
					left = o.grid[ 0 ] ? this.originalPageX +
						Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
						this.originalPageX;
					pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
						left - this.offset.click.left > containment[ 2 ] ) ?
							left :
							( ( left - this.offset.click.left >= containment[ 0 ] ) ?
								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
				}
	
				if ( o.axis === "y" ) {
					pageX = this.originalPageX;
				}
	
				if ( o.axis === "x" ) {
					pageY = this.originalPageY;
				}
			}
	
			return {
				top: (
	
					// The absolute mouse position
					pageY -
	
					// Click offset (relative to the element)
					this.offset.click.top -
	
					// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.relative.top -
	
					// The offsetParent's offset without borders (offset + border)
					this.offset.parent.top +
					( this.cssPosition === "fixed" ?
						-this.offset.scroll.top :
						( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
				),
				left: (
	
					// The absolute mouse position
					pageX -
	
					// Click offset (relative to the element)
					this.offset.click.left -
	
					// Only for relative positioned nodes: Relative offset from element to offset parent
					this.offset.relative.left -
	
					// The offsetParent's offset without borders (offset + border)
					this.offset.parent.left +
					( this.cssPosition === "fixed" ?
						-this.offset.scroll.left :
						( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
				)
			};
	
		},
	
		_clear: function() {
			this._removeClass( this.helper, "ui-draggable-dragging" );
			if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
				this.helper.remove();
			}
			this.helper = null;
			this.cancelHelperRemoval = false;
			if ( this.destroyOnClear ) {
				this.destroy();
			}
		},
	
		// From now on bulk stuff - mainly helpers
	
		_trigger: function( type, event, ui ) {
			ui = ui || this._uiHash();
			$.ui.plugin.call( this, type, [ event, ui, this ], true );
	
			// Absolute position and offset (see #6884 ) have to be recalculated after plugins
			if ( /^(drag|start|stop)/.test( type ) ) {
				this.positionAbs = this._convertPositionTo( "absolute" );
				ui.offset = this.positionAbs;
			}
			return $.Widget.prototype._trigger.call( this, type, event, ui );
		},
	
		plugins: {},
	
		_uiHash: function() {
			return {
				helper: this.helper,
				position: this.position,
				originalPosition: this.originalPosition,
				offset: this.positionAbs
			};
		}
	
	} );
	
	$.ui.plugin.add( "draggable", "connectToSortable", {
		start: function( event, ui, draggable ) {
			var uiSortable = $.extend( {}, ui, {
				item: draggable.element
			} );
	
			draggable.sortables = [];
			$( draggable.options.connectToSortable ).each( function() {
				var sortable = $( this ).sortable( "instance" );
	
				if ( sortable && !sortable.options.disabled ) {
					draggable.sortables.push( sortable );
	
					// RefreshPositions is called at drag start to refresh the containerCache
					// which is used in drag. This ensures it's initialized and synchronized
					// with any changes that might have happened on the page since initialization.
					sortable.refreshPositions();
					sortable._trigger( "activate", event, uiSortable );
				}
			} );
		},
		stop: function( event, ui, draggable ) {
			var uiSortable = $.extend( {}, ui, {
				item: draggable.element
			} );
	
			draggable.cancelHelperRemoval = false;
	
			$.each( draggable.sortables, function() {
				var sortable = this;
	
				if ( sortable.isOver ) {
					sortable.isOver = 0;
	
					// Allow this sortable to handle removing the helper
					draggable.cancelHelperRemoval = true;
					sortable.cancelHelperRemoval = false;
	
					// Use _storedCSS To restore properties in the sortable,
					// as this also handles revert (#9675) since the draggable
					// may have modified them in unexpected ways (#8809)
					sortable._storedCSS = {
						position: sortable.placeholder.css( "position" ),
						top: sortable.placeholder.css( "top" ),
						left: sortable.placeholder.css( "left" )
					};
	
					sortable._mouseStop( event );
	
					// Once drag has ended, the sortable should return to using
					// its original helper, not the shared helper from draggable
					sortable.options.helper = sortable.options._helper;
				} else {
	
					// Prevent this Sortable from removing the helper.
					// However, don't set the draggable to remove the helper
					// either as another connected Sortable may yet handle the removal.
					sortable.cancelHelperRemoval = true;
	
					sortable._trigger( "deactivate", event, uiSortable );
				}
			} );
		},
		drag: function( event, ui, draggable ) {
			$.each( draggable.sortables, function() {
				var innermostIntersecting = false,
					sortable = this;
	
				// Copy over variables that sortable's _intersectsWith uses
				sortable.positionAbs = draggable.positionAbs;
				sortable.helperProportions = draggable.helperProportions;
				sortable.offset.click = draggable.offset.click;
	
				if ( sortable._intersectsWith( sortable.containerCache ) ) {
					innermostIntersecting = true;
	
					$.each( draggable.sortables, function() {
	
						// Copy over variables that sortable's _intersectsWith uses
						this.positionAbs = draggable.positionAbs;
						this.helperProportions = draggable.helperProportions;
						this.offset.click = draggable.offset.click;
	
						if ( this !== sortable &&
								this._intersectsWith( this.containerCache ) &&
								$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
							innermostIntersecting = false;
						}
	
						return innermostIntersecting;
					} );
				}
	
				if ( innermostIntersecting ) {
	
					// If it intersects, we use a little isOver variable and set it once,
					// so that the move-in stuff gets fired only once.
					if ( !sortable.isOver ) {
						sortable.isOver = 1;
	
						// Store draggable's parent in case we need to reappend to it later.
						draggable._parent = ui.helper.parent();
	
						sortable.currentItem = ui.helper
							.appendTo( sortable.element )
							.data( "ui-sortable-item", true );
	
						// Store helper option to later restore it
						sortable.options._helper = sortable.options.helper;
	
						sortable.options.helper = function() {
							return ui.helper[ 0 ];
						};
	
						// Fire the start events of the sortable with our passed browser event,
						// and our own helper (so it doesn't create a new one)
						event.target = sortable.currentItem[ 0 ];
						sortable._mouseCapture( event, true );
						sortable._mouseStart( event, true, true );
	
						// Because the browser event is way off the new appended portlet,
						// modify necessary variables to reflect the changes
						sortable.offset.click.top = draggable.offset.click.top;
						sortable.offset.click.left = draggable.offset.click.left;
						sortable.offset.parent.left -= draggable.offset.parent.left -
							sortable.offset.parent.left;
						sortable.offset.parent.top -= draggable.offset.parent.top -
							sortable.offset.parent.top;
	
						draggable._trigger( "toSortable", event );
	
						// Inform draggable that the helper is in a valid drop zone,
						// used solely in the revert option to handle "valid/invalid".
						draggable.dropped = sortable.element;
	
						// Need to refreshPositions of all sortables in the case that
						// adding to one sortable changes the location of the other sortables (#9675)
						$.each( draggable.sortables, function() {
							this.refreshPositions();
						} );
	
						// Hack so receive/update callbacks work (mostly)
						draggable.currentItem = draggable.element;
						sortable.fromOutside = draggable;
					}
	
					if ( sortable.currentItem ) {
						sortable._mouseDrag( event );
	
						// Copy the sortable's position because the draggable's can potentially reflect
						// a relative position, while sortable is always absolute, which the dragged
						// element has now become. (#8809)
						ui.position = sortable.position;
					}
				} else {
	
					// If it doesn't intersect with the sortable, and it intersected before,
					// we fake the drag stop of the sortable, but make sure it doesn't remove
					// the helper by using cancelHelperRemoval.
					if ( sortable.isOver ) {
	
						sortable.isOver = 0;
						sortable.cancelHelperRemoval = true;
	
						// Calling sortable's mouseStop would trigger a revert,
						// so revert must be temporarily false until after mouseStop is called.
						sortable.options._revert = sortable.options.revert;
						sortable.options.revert = false;
	
						sortable._trigger( "out", event, sortable._uiHash( sortable ) );
						sortable._mouseStop( event, true );
	
						// Restore sortable behaviors that were modfied
						// when the draggable entered the sortable area (#9481)
						sortable.options.revert = sortable.options._revert;
						sortable.options.helper = sortable.options._helper;
	
						if ( sortable.placeholder ) {
							sortable.placeholder.remove();
						}
	
						// Restore and recalculate the draggable's offset considering the sortable
						// may have modified them in unexpected ways. (#8809, #10669)
						ui.helper.appendTo( draggable._parent );
						draggable._refreshOffsets( event );
						ui.position = draggable._generatePosition( event, true );
	
						draggable._trigger( "fromSortable", event );
	
						// Inform draggable that the helper is no longer in a valid drop zone
						draggable.dropped = false;
	
						// Need to refreshPositions of all sortables just in case removing
						// from one sortable changes the location of other sortables (#9675)
						$.each( draggable.sortables, function() {
							this.refreshPositions();
						} );
					}
				}
			} );
		}
	} );
	
	$.ui.plugin.add( "draggable", "cursor", {
		start: function( event, ui, instance ) {
			var t = $( "body" ),
				o = instance.options;
	
			if ( t.css( "cursor" ) ) {
				o._cursor = t.css( "cursor" );
			}
			t.css( "cursor", o.cursor );
		},
		stop: function( event, ui, instance ) {
			var o = instance.options;
			if ( o._cursor ) {
				$( "body" ).css( "cursor", o._cursor );
			}
		}
	} );
	
	$.ui.plugin.add( "draggable", "opacity", {
		start: function( event, ui, instance ) {
			var t = $( ui.helper ),
				o = instance.options;
			if ( t.css( "opacity" ) ) {
				o._opacity = t.css( "opacity" );
			}
			t.css( "opacity", o.opacity );
		},
		stop: function( event, ui, instance ) {
			var o = instance.options;
			if ( o._opacity ) {
				$( ui.helper ).css( "opacity", o._opacity );
			}
		}
	} );
	
	$.ui.plugin.add( "draggable", "scroll", {
		start: function( event, ui, i ) {
			if ( !i.scrollParentNotHidden ) {
				i.scrollParentNotHidden = i.helper.scrollParent( false );
			}
	
			if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
					i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
				i.overflowOffset = i.scrollParentNotHidden.offset();
			}
		},
		drag: function( event, ui, i  ) {
	
			var o = i.options,
				scrolled = false,
				scrollParent = i.scrollParentNotHidden[ 0 ],
				document = i.document[ 0 ];
	
			if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
				if ( !o.axis || o.axis !== "x" ) {
					if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
							o.scrollSensitivity ) {
						scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
					} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
						scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
					}
				}
	
				if ( !o.axis || o.axis !== "y" ) {
					if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
							o.scrollSensitivity ) {
						scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
					} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
						scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
					}
				}
	
			} else {
	
				if ( !o.axis || o.axis !== "x" ) {
					if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
						scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
					} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
							o.scrollSensitivity ) {
						scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
					}
				}
	
				if ( !o.axis || o.axis !== "y" ) {
					if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
						scrolled = $( document ).scrollLeft(
							$( document ).scrollLeft() - o.scrollSpeed
						);
					} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
							o.scrollSensitivity ) {
						scrolled = $( document ).scrollLeft(
							$( document ).scrollLeft() + o.scrollSpeed
						);
					}
				}
	
			}
	
			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
				$.ui.ddmanager.prepareOffsets( i, event );
			}
	
		}
	} );
	
	$.ui.plugin.add( "draggable", "snap", {
		start: function( event, ui, i ) {
	
			var o = i.options;
	
			i.snapElements = [];
	
			$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
				.each( function() {
					var $t = $( this ),
						$o = $t.offset();
					if ( this !== i.element[ 0 ] ) {
						i.snapElements.push( {
							item: this,
							width: $t.outerWidth(), height: $t.outerHeight(),
							top: $o.top, left: $o.left
						} );
					}
				} );
	
		},
		drag: function( event, ui, inst ) {
	
			var ts, bs, ls, rs, l, r, t, b, i, first,
				o = inst.options,
				d = o.snapTolerance,
				x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
				y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
	
			for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
	
				l = inst.snapElements[ i ].left - inst.margins.left;
				r = l + inst.snapElements[ i ].width;
				t = inst.snapElements[ i ].top - inst.margins.top;
				b = t + inst.snapElements[ i ].height;
	
				if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
						!$.contains( inst.snapElements[ i ].item.ownerDocument,
						inst.snapElements[ i ].item ) ) {
					if ( inst.snapElements[ i ].snapping ) {
						( inst.options.snap.release &&
							inst.options.snap.release.call(
								inst.element,
								event,
								$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
							) );
					}
					inst.snapElements[ i ].snapping = false;
					continue;
				}
	
				if ( o.snapMode !== "inner" ) {
					ts = Math.abs( t - y2 ) <= d;
					bs = Math.abs( b - y1 ) <= d;
					ls = Math.abs( l - x2 ) <= d;
					rs = Math.abs( r - x1 ) <= d;
					if ( ts ) {
						ui.position.top = inst._convertPositionTo( "relative", {
							top: t - inst.helperProportions.height,
							left: 0
						} ).top;
					}
					if ( bs ) {
						ui.position.top = inst._convertPositionTo( "relative", {
							top: b,
							left: 0
						} ).top;
					}
					if ( ls ) {
						ui.position.left = inst._convertPositionTo( "relative", {
							top: 0,
							left: l - inst.helperProportions.width
						} ).left;
					}
					if ( rs ) {
						ui.position.left = inst._convertPositionTo( "relative", {
							top: 0,
							left: r
						} ).left;
					}
				}
	
				first = ( ts || bs || ls || rs );
	
				if ( o.snapMode !== "outer" ) {
					ts = Math.abs( t - y1 ) <= d;
					bs = Math.abs( b - y2 ) <= d;
					ls = Math.abs( l - x1 ) <= d;
					rs = Math.abs( r - x2 ) <= d;
					if ( ts ) {
						ui.position.top = inst._convertPositionTo( "relative", {
							top: t,
							left: 0
						} ).top;
					}
					if ( bs ) {
						ui.position.top = inst._convertPositionTo( "relative", {
							top: b - inst.helperProportions.height,
							left: 0
						} ).top;
					}
					if ( ls ) {
						ui.position.left = inst._convertPositionTo( "relative", {
							top: 0,
							left: l
						} ).left;
					}
					if ( rs ) {
						ui.position.left = inst._convertPositionTo( "relative", {
							top: 0,
							left: r - inst.helperProportions.width
						} ).left;
					}
				}
	
				if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
					( inst.options.snap.snap &&
						inst.options.snap.snap.call(
							inst.element,
							event,
							$.extend( inst._uiHash(), {
								snapItem: inst.snapElements[ i ].item
							} ) ) );
				}
				inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
	
			}
	
		}
	} );
	
	$.ui.plugin.add( "draggable", "stack", {
		start: function( event, ui, instance ) {
			var min,
				o = instance.options,
				group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
					return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
						( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
				} );
	
			if ( !group.length ) { return; }
	
			min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
			$( group ).each( function( i ) {
				$( this ).css( "zIndex", min + i );
			} );
			this.css( "zIndex", ( min + group.length ) );
		}
	} );
	
	$.ui.plugin.add( "draggable", "zIndex", {
		start: function( event, ui, instance ) {
			var t = $( ui.helper ),
				o = instance.options;
	
			if ( t.css( "zIndex" ) ) {
				o._zIndex = t.css( "zIndex" );
			}
			t.css( "zIndex", o.zIndex );
		},
		stop: function( event, ui, instance ) {
			var o = instance.options;
	
			if ( o._zIndex ) {
				$( ui.helper ).css( "zIndex", o._zIndex );
			}
		}
	} );
	
	return $.ui.draggable;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/draggable.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/data.js **/
jupyter.define('jquery-ui@1.12.1/ui/data.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI :data 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: :data Selector
	//>>group: Core
	//>>description: Selects elements which have data stored under the specified key.
	//>>docs: http://api.jqueryui.com/data-selector/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	return $.extend( $.expr[ ":" ], {
		data: $.expr.createPseudo ?
			$.expr.createPseudo( function( dataName ) {
				return function( elem ) {
					return !!$.data( elem, dataName );
				};
			} ) :
	
			// Support: jQuery <1.8
			function( elem, i, match ) {
				return !!$.data( elem, match[ 3 ] );
			}
	} );
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/data.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/plugin.js **/
jupyter.define('jquery-ui@1.12.1/ui/plugin.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	// $.ui.plugin is deprecated. Use $.widget() extensions instead.
	return $.ui.plugin = {
		add: function( module, option, set ) {
			var i,
				proto = $.ui[ module ].prototype;
			for ( i in set ) {
				proto.plugins[ i ] = proto.plugins[ i ] || [];
				proto.plugins[ i ].push( [ option, set[ i ] ] );
			}
		},
		call: function( instance, name, args, allowDisconnected ) {
			var i,
				set = instance.plugins[ name ];
	
			if ( !set ) {
				return;
			}
	
			if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
					instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
				return;
			}
	
			for ( i = 0; i < set.length; i++ ) {
				if ( instance.options[ set[ i ][ 0 ] ] ) {
					set[ i ][ 1 ].apply( instance.element, args );
				}
			}
		}
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/plugin.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/safe-blur.js **/
jupyter.define('jquery-ui@1.12.1/ui/safe-blur.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	return $.ui.safeBlur = function( element ) {
	
		// Support: IE9 - 10 only
		// If the <body> is blurred, IE will switch windows, see #9420
		if ( element && element.nodeName.toLowerCase() !== "body" ) {
			$( element ).trigger( "blur" );
		}
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/safe-blur.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/scroll-parent.js **/
jupyter.define('jquery-ui@1.12.1/ui/scroll-parent.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Scroll Parent 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: scrollParent
	//>>group: Core
	//>>description: Get the closest ancestor element that is scrollable.
	//>>docs: http://api.jqueryui.com/scrollParent/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	return $.fn.scrollParent = function( includeHidden ) {
		var position = this.css( "position" ),
			excludeStaticParent = position === "absolute",
			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
			scrollParent = this.parents().filter( function() {
				var parent = $( this );
				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
					return false;
				}
				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
					parent.css( "overflow-x" ) );
			} ).eq( 0 );
	
		return position === "fixed" || !scrollParent.length ?
			$( this[ 0 ].ownerDocument || document ) :
			scrollParent;
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/scroll-parent.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/safe-active-element.js **/
jupyter.define('jquery-ui@1.12.1/ui/safe-active-element.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	return $.ui.safeActiveElement = function( document ) {
		var activeElement;
	
		// Support: IE 9 only
		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
		try {
			activeElement = document.activeElement;
		} catch ( error ) {
			activeElement = document.body;
		}
	
		// Support: IE 9 - 11 only
		// IE may return null instead of an element
		// Interestingly, this only seems to occur when NOT in an iframe
		if ( !activeElement ) {
			activeElement = document.body;
		}
	
		// Support: IE 11 only
		// IE11 returns a seemingly empty object in some cases when accessing
		// document.activeElement from an <iframe>
		if ( !activeElement.nodeName ) {
			activeElement = document.body;
		}
	
		return activeElement;
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/safe-active-element.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/dialog.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/dialog.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Dialog 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Dialog
	//>>group: Widgets
	//>>description: Displays customizable dialog windows.
	//>>docs: http://api.jqueryui.com/dialog/
	//>>demos: http://jqueryui.com/dialog/
	//>>css.structure: ../../themes/base/core.css
	//>>css.structure: ../../themes/base/dialog.css
	//>>css.theme: ../../themes/base/theme.css
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/button.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/draggable.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/mouse.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/resizable.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/focusable.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/keycode.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/position.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/safe-active-element.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/safe-blur.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/tabbable.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/unique-id.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/version.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	$.widget( "ui.dialog", {
		version: "1.12.1",
		options: {
			appendTo: "body",
			autoOpen: true,
			buttons: [],
			classes: {
				"ui-dialog": "ui-corner-all",
				"ui-dialog-titlebar": "ui-corner-all"
			},
			closeOnEscape: true,
			closeText: "Close",
			draggable: true,
			hide: null,
			height: "auto",
			maxHeight: null,
			maxWidth: null,
			minHeight: 150,
			minWidth: 150,
			modal: false,
			position: {
				my: "center",
				at: "center",
				of: window,
				collision: "fit",
	
				// Ensure the titlebar is always visible
				using: function( pos ) {
					var topOffset = $( this ).css( pos ).offset().top;
					if ( topOffset < 0 ) {
						$( this ).css( "top", pos.top - topOffset );
					}
				}
			},
			resizable: true,
			show: null,
			title: null,
			width: 300,
	
			// Callbacks
			beforeClose: null,
			close: null,
			drag: null,
			dragStart: null,
			dragStop: null,
			focus: null,
			open: null,
			resize: null,
			resizeStart: null,
			resizeStop: null
		},
	
		sizeRelatedOptions: {
			buttons: true,
			height: true,
			maxHeight: true,
			maxWidth: true,
			minHeight: true,
			minWidth: true,
			width: true
		},
	
		resizableRelatedOptions: {
			maxHeight: true,
			maxWidth: true,
			minHeight: true,
			minWidth: true
		},
	
		_create: function() {
			this.originalCss = {
				display: this.element[ 0 ].style.display,
				width: this.element[ 0 ].style.width,
				minHeight: this.element[ 0 ].style.minHeight,
				maxHeight: this.element[ 0 ].style.maxHeight,
				height: this.element[ 0 ].style.height
			};
			this.originalPosition = {
				parent: this.element.parent(),
				index: this.element.parent().children().index( this.element )
			};
			this.originalTitle = this.element.attr( "title" );
			if ( this.options.title == null && this.originalTitle != null ) {
				this.options.title = this.originalTitle;
			}
	
			// Dialogs can't be disabled
			if ( this.options.disabled ) {
				this.options.disabled = false;
			}
	
			this._createWrapper();
	
			this.element
				.show()
				.removeAttr( "title" )
				.appendTo( this.uiDialog );
	
			this._addClass( "ui-dialog-content", "ui-widget-content" );
	
			this._createTitlebar();
			this._createButtonPane();
	
			if ( this.options.draggable && $.fn.draggable ) {
				this._makeDraggable();
			}
			if ( this.options.resizable && $.fn.resizable ) {
				this._makeResizable();
			}
	
			this._isOpen = false;
	
			this._trackFocus();
		},
	
		_init: function() {
			if ( this.options.autoOpen ) {
				this.open();
			}
		},
	
		_appendTo: function() {
			var element = this.options.appendTo;
			if ( element && ( element.jquery || element.nodeType ) ) {
				return $( element );
			}
			return this.document.find( element || "body" ).eq( 0 );
		},
	
		_destroy: function() {
			var next,
				originalPosition = this.originalPosition;
	
			this._untrackInstance();
			this._destroyOverlay();
	
			this.element
				.removeUniqueId()
				.css( this.originalCss )
	
				// Without detaching first, the following becomes really slow
				.detach();
	
			this.uiDialog.remove();
	
			if ( this.originalTitle ) {
				this.element.attr( "title", this.originalTitle );
			}
	
			next = originalPosition.parent.children().eq( originalPosition.index );
	
			// Don't try to place the dialog next to itself (#8613)
			if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
				next.before( this.element );
			} else {
				originalPosition.parent.append( this.element );
			}
		},
	
		widget: function() {
			return this.uiDialog;
		},
	
		disable: $.noop,
		enable: $.noop,
	
		close: function( event ) {
			var that = this;
	
			if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
				return;
			}
	
			this._isOpen = false;
			this._focusedElement = null;
			this._destroyOverlay();
			this._untrackInstance();
	
			if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
	
				// Hiding a focused element doesn't trigger blur in WebKit
				// so in case we have nothing to focus on, explicitly blur the active element
				// https://bugs.webkit.org/show_bug.cgi?id=47182
				$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
			}
	
			this._hide( this.uiDialog, this.options.hide, function() {
				that._trigger( "close", event );
			} );
		},
	
		isOpen: function() {
			return this._isOpen;
		},
	
		moveToTop: function() {
			this._moveToTop();
		},
	
		_moveToTop: function( event, silent ) {
			var moved = false,
				zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
					return +$( this ).css( "z-index" );
				} ).get(),
				zIndexMax = Math.max.apply( null, zIndices );
	
			if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
				this.uiDialog.css( "z-index", zIndexMax + 1 );
				moved = true;
			}
	
			if ( moved && !silent ) {
				this._trigger( "focus", event );
			}
			return moved;
		},
	
		open: function() {
			var that = this;
			if ( this._isOpen ) {
				if ( this._moveToTop() ) {
					this._focusTabbable();
				}
				return;
			}
	
			this._isOpen = true;
			this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
	
			this._size();
			this._position();
			this._createOverlay();
			this._moveToTop( null, true );
	
			// Ensure the overlay is moved to the top with the dialog, but only when
			// opening. The overlay shouldn't move after the dialog is open so that
			// modeless dialogs opened after the modal dialog stack properly.
			if ( this.overlay ) {
				this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
			}
	
			this._show( this.uiDialog, this.options.show, function() {
				that._focusTabbable();
				that._trigger( "focus" );
			} );
	
			// Track the dialog immediately upon openening in case a focus event
			// somehow occurs outside of the dialog before an element inside the
			// dialog is focused (#10152)
			this._makeFocusTarget();
	
			this._trigger( "open" );
		},
	
		_focusTabbable: function() {
	
			// Set focus to the first match:
			// 1. An element that was focused previously
			// 2. First element inside the dialog matching [autofocus]
			// 3. Tabbable element inside the content element
			// 4. Tabbable element inside the buttonpane
			// 5. The close button
			// 6. The dialog itself
			var hasFocus = this._focusedElement;
			if ( !hasFocus ) {
				hasFocus = this.element.find( "[autofocus]" );
			}
			if ( !hasFocus.length ) {
				hasFocus = this.element.find( ":tabbable" );
			}
			if ( !hasFocus.length ) {
				hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
			}
			if ( !hasFocus.length ) {
				hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
			}
			if ( !hasFocus.length ) {
				hasFocus = this.uiDialog;
			}
			hasFocus.eq( 0 ).trigger( "focus" );
		},
	
		_keepFocus: function( event ) {
			function checkFocus() {
				var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
					isActive = this.uiDialog[ 0 ] === activeElement ||
						$.contains( this.uiDialog[ 0 ], activeElement );
				if ( !isActive ) {
					this._focusTabbable();
				}
			}
			event.preventDefault();
			checkFocus.call( this );
	
			// support: IE
			// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
			// so we check again later
			this._delay( checkFocus );
		},
	
		_createWrapper: function() {
			this.uiDialog = $( "<div>" )
				.hide()
				.attr( {
	
					// Setting tabIndex makes the div focusable
					tabIndex: -1,
					role: "dialog"
				} )
				.appendTo( this._appendTo() );
	
			this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
			this._on( this.uiDialog, {
				keydown: function( event ) {
					if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
							event.keyCode === $.ui.keyCode.ESCAPE ) {
						event.preventDefault();
						this.close( event );
						return;
					}
	
					// Prevent tabbing out of dialogs
					if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
						return;
					}
					var tabbables = this.uiDialog.find( ":tabbable" ),
						first = tabbables.filter( ":first" ),
						last = tabbables.filter( ":last" );
	
					if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
							!event.shiftKey ) {
						this._delay( function() {
							first.trigger( "focus" );
						} );
						event.preventDefault();
					} else if ( ( event.target === first[ 0 ] ||
							event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
						this._delay( function() {
							last.trigger( "focus" );
						} );
						event.preventDefault();
					}
				},
				mousedown: function( event ) {
					if ( this._moveToTop( event ) ) {
						this._focusTabbable();
					}
				}
			} );
	
			// We assume that any existing aria-describedby attribute means
			// that the dialog content is marked up properly
			// otherwise we brute force the content as the description
			if ( !this.element.find( "[aria-describedby]" ).length ) {
				this.uiDialog.attr( {
					"aria-describedby": this.element.uniqueId().attr( "id" )
				} );
			}
		},
	
		_createTitlebar: function() {
			var uiDialogTitle;
	
			this.uiDialogTitlebar = $( "<div>" );
			this._addClass( this.uiDialogTitlebar,
				"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
			this._on( this.uiDialogTitlebar, {
				mousedown: function( event ) {
	
					// Don't prevent click on close button (#8838)
					// Focusing a dialog that is partially scrolled out of view
					// causes the browser to scroll it into view, preventing the click event
					if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
	
						// Dialog isn't getting focus when dragging (#8063)
						this.uiDialog.trigger( "focus" );
					}
				}
			} );
	
			// Support: IE
			// Use type="button" to prevent enter keypresses in textboxes from closing the
			// dialog in IE (#9312)
			this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
				.button( {
					label: $( "<a>" ).text( this.options.closeText ).html(),
					icon: "ui-icon-closethick",
					showLabel: false
				} )
				.appendTo( this.uiDialogTitlebar );
	
			this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
			this._on( this.uiDialogTitlebarClose, {
				click: function( event ) {
					event.preventDefault();
					this.close( event );
				}
			} );
	
			uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
			this._addClass( uiDialogTitle, "ui-dialog-title" );
			this._title( uiDialogTitle );
	
			this.uiDialogTitlebar.prependTo( this.uiDialog );
	
			this.uiDialog.attr( {
				"aria-labelledby": uiDialogTitle.attr( "id" )
			} );
		},
	
		_title: function( title ) {
			if ( this.options.title ) {
				title.text( this.options.title );
			} else {
				title.html( "&#160;" );
			}
		},
	
		_createButtonPane: function() {
			this.uiDialogButtonPane = $( "<div>" );
			this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
				"ui-widget-content ui-helper-clearfix" );
	
			this.uiButtonSet = $( "<div>" )
				.appendTo( this.uiDialogButtonPane );
			this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
	
			this._createButtons();
		},
	
		_createButtons: function() {
			var that = this,
				buttons = this.options.buttons;
	
			// If we already have a button pane, remove it
			this.uiDialogButtonPane.remove();
			this.uiButtonSet.empty();
	
			if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
				this._removeClass( this.uiDialog, "ui-dialog-buttons" );
				return;
			}
	
			$.each( buttons, function( name, props ) {
				var click, buttonOptions;
				props = $.isFunction( props ) ?
					{ click: props, text: name } :
					props;
	
				// Default to a non-submitting button
				props = $.extend( { type: "button" }, props );
	
				// Change the context for the click callback to be the main element
				click = props.click;
				buttonOptions = {
					icon: props.icon,
					iconPosition: props.iconPosition,
					showLabel: props.showLabel,
	
					// Deprecated options
					icons: props.icons,
					text: props.text
				};
	
				delete props.click;
				delete props.icon;
				delete props.iconPosition;
				delete props.showLabel;
	
				// Deprecated options
				delete props.icons;
				if ( typeof props.text === "boolean" ) {
					delete props.text;
				}
	
				$( "<button></button>", props )
					.button( buttonOptions )
					.appendTo( that.uiButtonSet )
					.on( "click", function() {
						click.apply( that.element[ 0 ], arguments );
					} );
			} );
			this._addClass( this.uiDialog, "ui-dialog-buttons" );
			this.uiDialogButtonPane.appendTo( this.uiDialog );
		},
	
		_makeDraggable: function() {
			var that = this,
				options = this.options;
	
			function filteredUi( ui ) {
				return {
					position: ui.position,
					offset: ui.offset
				};
			}
	
			this.uiDialog.draggable( {
				cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
				handle: ".ui-dialog-titlebar",
				containment: "document",
				start: function( event, ui ) {
					that._addClass( $( this ), "ui-dialog-dragging" );
					that._blockFrames();
					that._trigger( "dragStart", event, filteredUi( ui ) );
				},
				drag: function( event, ui ) {
					that._trigger( "drag", event, filteredUi( ui ) );
				},
				stop: function( event, ui ) {
					var left = ui.offset.left - that.document.scrollLeft(),
						top = ui.offset.top - that.document.scrollTop();
	
					options.position = {
						my: "left top",
						at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
							"top" + ( top >= 0 ? "+" : "" ) + top,
						of: that.window
					};
					that._removeClass( $( this ), "ui-dialog-dragging" );
					that._unblockFrames();
					that._trigger( "dragStop", event, filteredUi( ui ) );
				}
			} );
		},
	
		_makeResizable: function() {
			var that = this,
				options = this.options,
				handles = options.resizable,
	
				// .ui-resizable has position: relative defined in the stylesheet
				// but dialogs have to use absolute or fixed positioning
				position = this.uiDialog.css( "position" ),
				resizeHandles = typeof handles === "string" ?
					handles :
					"n,e,s,w,se,sw,ne,nw";
	
			function filteredUi( ui ) {
				return {
					originalPosition: ui.originalPosition,
					originalSize: ui.originalSize,
					position: ui.position,
					size: ui.size
				};
			}
	
			this.uiDialog.resizable( {
				cancel: ".ui-dialog-content",
				containment: "document",
				alsoResize: this.element,
				maxWidth: options.maxWidth,
				maxHeight: options.maxHeight,
				minWidth: options.minWidth,
				minHeight: this._minHeight(),
				handles: resizeHandles,
				start: function( event, ui ) {
					that._addClass( $( this ), "ui-dialog-resizing" );
					that._blockFrames();
					that._trigger( "resizeStart", event, filteredUi( ui ) );
				},
				resize: function( event, ui ) {
					that._trigger( "resize", event, filteredUi( ui ) );
				},
				stop: function( event, ui ) {
					var offset = that.uiDialog.offset(),
						left = offset.left - that.document.scrollLeft(),
						top = offset.top - that.document.scrollTop();
	
					options.height = that.uiDialog.height();
					options.width = that.uiDialog.width();
					options.position = {
						my: "left top",
						at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
							"top" + ( top >= 0 ? "+" : "" ) + top,
						of: that.window
					};
					that._removeClass( $( this ), "ui-dialog-resizing" );
					that._unblockFrames();
					that._trigger( "resizeStop", event, filteredUi( ui ) );
				}
			} )
				.css( "position", position );
		},
	
		_trackFocus: function() {
			this._on( this.widget(), {
				focusin: function( event ) {
					this._makeFocusTarget();
					this._focusedElement = $( event.target );
				}
			} );
		},
	
		_makeFocusTarget: function() {
			this._untrackInstance();
			this._trackingInstances().unshift( this );
		},
	
		_untrackInstance: function() {
			var instances = this._trackingInstances(),
				exists = $.inArray( this, instances );
			if ( exists !== -1 ) {
				instances.splice( exists, 1 );
			}
		},
	
		_trackingInstances: function() {
			var instances = this.document.data( "ui-dialog-instances" );
			if ( !instances ) {
				instances = [];
				this.document.data( "ui-dialog-instances", instances );
			}
			return instances;
		},
	
		_minHeight: function() {
			var options = this.options;
	
			return options.height === "auto" ?
				options.minHeight :
				Math.min( options.minHeight, options.height );
		},
	
		_position: function() {
	
			// Need to show the dialog to get the actual offset in the position plugin
			var isVisible = this.uiDialog.is( ":visible" );
			if ( !isVisible ) {
				this.uiDialog.show();
			}
			this.uiDialog.position( this.options.position );
			if ( !isVisible ) {
				this.uiDialog.hide();
			}
		},
	
		_setOptions: function( options ) {
			var that = this,
				resize = false,
				resizableOptions = {};
	
			$.each( options, function( key, value ) {
				that._setOption( key, value );
	
				if ( key in that.sizeRelatedOptions ) {
					resize = true;
				}
				if ( key in that.resizableRelatedOptions ) {
					resizableOptions[ key ] = value;
				}
			} );
	
			if ( resize ) {
				this._size();
				this._position();
			}
			if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
				this.uiDialog.resizable( "option", resizableOptions );
			}
		},
	
		_setOption: function( key, value ) {
			var isDraggable, isResizable,
				uiDialog = this.uiDialog;
	
			if ( key === "disabled" ) {
				return;
			}
	
			this._super( key, value );
	
			if ( key === "appendTo" ) {
				this.uiDialog.appendTo( this._appendTo() );
			}
	
			if ( key === "buttons" ) {
				this._createButtons();
			}
	
			if ( key === "closeText" ) {
				this.uiDialogTitlebarClose.button( {
	
					// Ensure that we always pass a string
					label: $( "<a>" ).text( "" + this.options.closeText ).html()
				} );
			}
	
			if ( key === "draggable" ) {
				isDraggable = uiDialog.is( ":data(ui-draggable)" );
				if ( isDraggable && !value ) {
					uiDialog.draggable( "destroy" );
				}
	
				if ( !isDraggable && value ) {
					this._makeDraggable();
				}
			}
	
			if ( key === "position" ) {
				this._position();
			}
	
			if ( key === "resizable" ) {
	
				// currently resizable, becoming non-resizable
				isResizable = uiDialog.is( ":data(ui-resizable)" );
				if ( isResizable && !value ) {
					uiDialog.resizable( "destroy" );
				}
	
				// Currently resizable, changing handles
				if ( isResizable && typeof value === "string" ) {
					uiDialog.resizable( "option", "handles", value );
				}
	
				// Currently non-resizable, becoming resizable
				if ( !isResizable && value !== false ) {
					this._makeResizable();
				}
			}
	
			if ( key === "title" ) {
				this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
			}
		},
	
		_size: function() {
	
			// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
			// divs will both have width and height set, so we need to reset them
			var nonContentHeight, minContentHeight, maxContentHeight,
				options = this.options;
	
			// Reset content sizing
			this.element.show().css( {
				width: "auto",
				minHeight: 0,
				maxHeight: "none",
				height: 0
			} );
	
			if ( options.minWidth > options.width ) {
				options.width = options.minWidth;
			}
	
			// Reset wrapper sizing
			// determine the height of all the non-content elements
			nonContentHeight = this.uiDialog.css( {
				height: "auto",
				width: options.width
			} )
				.outerHeight();
			minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
			maxContentHeight = typeof options.maxHeight === "number" ?
				Math.max( 0, options.maxHeight - nonContentHeight ) :
				"none";
	
			if ( options.height === "auto" ) {
				this.element.css( {
					minHeight: minContentHeight,
					maxHeight: maxContentHeight,
					height: "auto"
				} );
			} else {
				this.element.height( Math.max( 0, options.height - nonContentHeight ) );
			}
	
			if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
				this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
			}
		},
	
		_blockFrames: function() {
			this.iframeBlocks = this.document.find( "iframe" ).map( function() {
				var iframe = $( this );
	
				return $( "<div>" )
					.css( {
						position: "absolute",
						width: iframe.outerWidth(),
						height: iframe.outerHeight()
					} )
					.appendTo( iframe.parent() )
					.offset( iframe.offset() )[ 0 ];
			} );
		},
	
		_unblockFrames: function() {
			if ( this.iframeBlocks ) {
				this.iframeBlocks.remove();
				delete this.iframeBlocks;
			}
		},
	
		_allowInteraction: function( event ) {
			if ( $( event.target ).closest( ".ui-dialog" ).length ) {
				return true;
			}
	
			// TODO: Remove hack when datepicker implements
			// the .ui-front logic (#8989)
			return !!$( event.target ).closest( ".ui-datepicker" ).length;
		},
	
		_createOverlay: function() {
			if ( !this.options.modal ) {
				return;
			}
	
			// We use a delay in case the overlay is created from an
			// event that we're going to be cancelling (#2804)
			var isOpening = true;
			this._delay( function() {
				isOpening = false;
			} );
	
			if ( !this.document.data( "ui-dialog-overlays" ) ) {
	
				// Prevent use of anchors and inputs
				// Using _on() for an event handler shared across many instances is
				// safe because the dialogs stack and must be closed in reverse order
				this._on( this.document, {
					focusin: function( event ) {
						if ( isOpening ) {
							return;
						}
	
						if ( !this._allowInteraction( event ) ) {
							event.preventDefault();
							this._trackingInstances()[ 0 ]._focusTabbable();
						}
					}
				} );
			}
	
			this.overlay = $( "<div>" )
				.appendTo( this._appendTo() );
	
			this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
			this._on( this.overlay, {
				mousedown: "_keepFocus"
			} );
			this.document.data( "ui-dialog-overlays",
				( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
		},
	
		_destroyOverlay: function() {
			if ( !this.options.modal ) {
				return;
			}
	
			if ( this.overlay ) {
				var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
	
				if ( !overlays ) {
					this._off( this.document, "focusin" );
					this.document.removeData( "ui-dialog-overlays" );
				} else {
					this.document.data( "ui-dialog-overlays", overlays );
				}
	
				this.overlay.remove();
				this.overlay = null;
			}
		}
	} );
	
	// DEPRECATED
	// TODO: switch return back to widget declaration at top of file when this is removed
	if ( $.uiBackCompat !== false ) {
	
		// Backcompat for dialogClass option
		$.widget( "ui.dialog", $.ui.dialog, {
			options: {
				dialogClass: ""
			},
			_createWrapper: function() {
				this._super();
				this.uiDialog.addClass( this.options.dialogClass );
			},
			_setOption: function( key, value ) {
				if ( key === "dialogClass" ) {
					this.uiDialog
						.removeClass( this.options.dialogClass )
						.addClass( value );
				}
				this._superApply( arguments );
			}
		} );
	}
	
	return $.ui.dialog;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/dialog.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/button.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/button.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Button 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Button
	//>>group: Widgets
	//>>description: Enhances a form with themeable buttons.
	//>>docs: http://api.jqueryui.com/button/
	//>>demos: http://jqueryui.com/button/
	//>>css.structure: ../../themes/base/core.css
	//>>css.structure: ../../themes/base/button.css
	//>>css.theme: ../../themes/base/theme.css
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
	
				// These are only for backcompat
				// TODO: Remove after 1.12
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/controlgroup.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/checkboxradio.js'),
	
				__jupyter_require__('jquery-ui@1.12.1/ui/keycode.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	$.widget( "ui.button", {
		version: "1.12.1",
		defaultElement: "<button>",
		options: {
			classes: {
				"ui-button": "ui-corner-all"
			},
			disabled: null,
			icon: null,
			iconPosition: "beginning",
			label: null,
			showLabel: true
		},
	
		_getCreateOptions: function() {
			var disabled,
	
				// This is to support cases like in jQuery Mobile where the base widget does have
				// an implementation of _getCreateOptions
				options = this._super() || {};
	
			this.isInput = this.element.is( "input" );
	
			disabled = this.element[ 0 ].disabled;
			if ( disabled != null ) {
				options.disabled = disabled;
			}
	
			this.originalLabel = this.isInput ? this.element.val() : this.element.html();
			if ( this.originalLabel ) {
				options.label = this.originalLabel;
			}
	
			return options;
		},
	
		_create: function() {
			if ( !this.option.showLabel & !this.options.icon ) {
				this.options.showLabel = true;
			}
	
			// We have to check the option again here even though we did in _getCreateOptions,
			// because null may have been passed on init which would override what was set in
			// _getCreateOptions
			if ( this.options.disabled == null ) {
				this.options.disabled = this.element[ 0 ].disabled || false;
			}
	
			this.hasTitle = !!this.element.attr( "title" );
	
			// Check to see if the label needs to be set or if its already correct
			if ( this.options.label && this.options.label !== this.originalLabel ) {
				if ( this.isInput ) {
					this.element.val( this.options.label );
				} else {
					this.element.html( this.options.label );
				}
			}
			this._addClass( "ui-button", "ui-widget" );
			this._setOption( "disabled", this.options.disabled );
			this._enhance();
	
			if ( this.element.is( "a" ) ) {
				this._on( {
					"keyup": function( event ) {
						if ( event.keyCode === $.ui.keyCode.SPACE ) {
							event.preventDefault();
	
							// Support: PhantomJS <= 1.9, IE 8 Only
							// If a native click is available use it so we actually cause navigation
							// otherwise just trigger a click event
							if ( this.element[ 0 ].click ) {
								this.element[ 0 ].click();
							} else {
								this.element.trigger( "click" );
							}
						}
					}
				} );
			}
		},
	
		_enhance: function() {
			if ( !this.element.is( "button" ) ) {
				this.element.attr( "role", "button" );
			}
	
			if ( this.options.icon ) {
				this._updateIcon( "icon", this.options.icon );
				this._updateTooltip();
			}
		},
	
		_updateTooltip: function() {
			this.title = this.element.attr( "title" );
	
			if ( !this.options.showLabel && !this.title ) {
				this.element.attr( "title", this.options.label );
			}
		},
	
		_updateIcon: function( option, value ) {
			var icon = option !== "iconPosition",
				position = icon ? this.options.iconPosition : value,
				displayBlock = position === "top" || position === "bottom";
	
			// Create icon
			if ( !this.icon ) {
				this.icon = $( "<span>" );
	
				this._addClass( this.icon, "ui-button-icon", "ui-icon" );
	
				if ( !this.options.showLabel ) {
					this._addClass( "ui-button-icon-only" );
				}
			} else if ( icon ) {
	
				// If we are updating the icon remove the old icon class
				this._removeClass( this.icon, null, this.options.icon );
			}
	
			// If we are updating the icon add the new icon class
			if ( icon ) {
				this._addClass( this.icon, null, value );
			}
	
			this._attachIcon( position );
	
			// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
			// the iconSpace if there is one.
			if ( displayBlock ) {
				this._addClass( this.icon, null, "ui-widget-icon-block" );
				if ( this.iconSpace ) {
					this.iconSpace.remove();
				}
			} else {
	
				// Position is beginning or end so remove the ui-widget-icon-block class and add the
				// space if it does not exist
				if ( !this.iconSpace ) {
					this.iconSpace = $( "<span> </span>" );
					this._addClass( this.iconSpace, "ui-button-icon-space" );
				}
				this._removeClass( this.icon, null, "ui-wiget-icon-block" );
				this._attachIconSpace( position );
			}
		},
	
		_destroy: function() {
			this.element.removeAttr( "role" );
	
			if ( this.icon ) {
				this.icon.remove();
			}
			if ( this.iconSpace ) {
				this.iconSpace.remove();
			}
			if ( !this.hasTitle ) {
				this.element.removeAttr( "title" );
			}
		},
	
		_attachIconSpace: function( iconPosition ) {
			this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
		},
	
		_attachIcon: function( iconPosition ) {
			this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
		},
	
		_setOptions: function( options ) {
			var newShowLabel = options.showLabel === undefined ?
					this.options.showLabel :
					options.showLabel,
				newIcon = options.icon === undefined ? this.options.icon : options.icon;
	
			if ( !newShowLabel && !newIcon ) {
				options.showLabel = true;
			}
			this._super( options );
		},
	
		_setOption: function( key, value ) {
			if ( key === "icon" ) {
				if ( value ) {
					this._updateIcon( key, value );
				} else if ( this.icon ) {
					this.icon.remove();
					if ( this.iconSpace ) {
						this.iconSpace.remove();
					}
				}
			}
	
			if ( key === "iconPosition" ) {
				this._updateIcon( key, value );
			}
	
			// Make sure we can't end up with a button that has neither text nor icon
			if ( key === "showLabel" ) {
					this._toggleClass( "ui-button-icon-only", null, !value );
					this._updateTooltip();
			}
	
			if ( key === "label" ) {
				if ( this.isInput ) {
					this.element.val( value );
				} else {
	
					// If there is an icon, append it, else nothing then append the value
					// this avoids removal of the icon when setting label text
					this.element.html( value );
					if ( this.icon ) {
						this._attachIcon( this.options.iconPosition );
						this._attachIconSpace( this.options.iconPosition );
					}
				}
			}
	
			this._super( key, value );
	
			if ( key === "disabled" ) {
				this._toggleClass( null, "ui-state-disabled", value );
				this.element[ 0 ].disabled = value;
				if ( value ) {
					this.element.blur();
				}
			}
		},
	
		refresh: function() {
	
			// Make sure to only check disabled if its an element that supports this otherwise
			// check for the disabled class to determine state
			var isDisabled = this.element.is( "input, button" ) ?
				this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
	
			if ( isDisabled !== this.options.disabled ) {
				this._setOptions( { disabled: isDisabled } );
			}
	
			this._updateTooltip();
		}
	} );
	
	// DEPRECATED
	if ( $.uiBackCompat !== false ) {
	
		// Text and Icons options
		$.widget( "ui.button", $.ui.button, {
			options: {
				text: true,
				icons: {
					primary: null,
					secondary: null
				}
			},
	
			_create: function() {
				if ( this.options.showLabel && !this.options.text ) {
					this.options.showLabel = this.options.text;
				}
				if ( !this.options.showLabel && this.options.text ) {
					this.options.text = this.options.showLabel;
				}
				if ( !this.options.icon && ( this.options.icons.primary ||
						this.options.icons.secondary ) ) {
					if ( this.options.icons.primary ) {
						this.options.icon = this.options.icons.primary;
					} else {
						this.options.icon = this.options.icons.secondary;
						this.options.iconPosition = "end";
					}
				} else if ( this.options.icon ) {
					this.options.icons.primary = this.options.icon;
				}
				this._super();
			},
	
			_setOption: function( key, value ) {
				if ( key === "text" ) {
					this._super( "showLabel", value );
					return;
				}
				if ( key === "showLabel" ) {
					this.options.text = value;
				}
				if ( key === "icon" ) {
					this.options.icons.primary = value;
				}
				if ( key === "icons" ) {
					if ( value.primary ) {
						this._super( "icon", value.primary );
						this._super( "iconPosition", "beginning" );
					} else if ( value.secondary ) {
						this._super( "icon", value.secondary );
						this._super( "iconPosition", "end" );
					}
				}
				this._superApply( arguments );
			}
		} );
	
		$.fn.button = ( function( orig ) {
			return function() {
				if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
						( this.length && this[ 0 ].tagName === "INPUT" && (
							this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
						) ) ) {
					return orig.apply( this, arguments );
				}
				if ( !$.ui.checkboxradio ) {
					$.error( "Checkboxradio widget missing" );
				}
				if ( arguments.length === 0 ) {
					return this.checkboxradio( {
						"icon": false
					} );
				}
				return this.checkboxradio.apply( this, arguments );
			};
		} )( $.fn.button );
	
		$.fn.buttonset = function() {
			if ( !$.ui.controlgroup ) {
				$.error( "Controlgroup widget missing" );
			}
			if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
				return this.controlgroup.apply( this,
					[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
			}
			if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
				return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
			}
			if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
				arguments[ 0 ].items = {
					button: arguments[ 0 ].items
				};
			}
			return this.controlgroup.apply( this, arguments );
		};
	}
	
	return $.ui.button;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/button.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/controlgroup.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/controlgroup.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Controlgroup 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Controlgroup
	//>>group: Widgets
	//>>description: Visually groups form control widgets
	//>>docs: http://api.jqueryui.com/controlgroup/
	//>>demos: http://jqueryui.com/controlgroup/
	//>>css.structure: ../../themes/base/core.css
	//>>css.structure: ../../themes/base/controlgroup.css
	//>>css.theme: ../../themes/base/theme.css
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
	
	return $.widget( "ui.controlgroup", {
		version: "1.12.1",
		defaultElement: "<div>",
		options: {
			direction: "horizontal",
			disabled: null,
			onlyVisible: true,
			items: {
				"button": "input[type=button], input[type=submit], input[type=reset], button, a",
				"controlgroupLabel": ".ui-controlgroup-label",
				"checkboxradio": "input[type='checkbox'], input[type='radio']",
				"selectmenu": "select",
				"spinner": ".ui-spinner-input"
			}
		},
	
		_create: function() {
			this._enhance();
		},
	
		// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
		_enhance: function() {
			this.element.attr( "role", "toolbar" );
			this.refresh();
		},
	
		_destroy: function() {
			this._callChildMethod( "destroy" );
			this.childWidgets.removeData( "ui-controlgroup-data" );
			this.element.removeAttr( "role" );
			if ( this.options.items.controlgroupLabel ) {
				this.element
					.find( this.options.items.controlgroupLabel )
					.find( ".ui-controlgroup-label-contents" )
					.contents().unwrap();
			}
		},
	
		_initWidgets: function() {
			var that = this,
				childWidgets = [];
	
			// First we iterate over each of the items options
			$.each( this.options.items, function( widget, selector ) {
				var labels;
				var options = {};
	
				// Make sure the widget has a selector set
				if ( !selector ) {
					return;
				}
	
				if ( widget === "controlgroupLabel" ) {
					labels = that.element.find( selector );
					labels.each( function() {
						var element = $( this );
	
						if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
							return;
						}
						element.contents()
							.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
					} );
					that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
					childWidgets = childWidgets.concat( labels.get() );
					return;
				}
	
				// Make sure the widget actually exists
				if ( !$.fn[ widget ] ) {
					return;
				}
	
				// We assume everything is in the middle to start because we can't determine
				// first / last elements until all enhancments are done.
				if ( that[ "_" + widget + "Options" ] ) {
					options = that[ "_" + widget + "Options" ]( "middle" );
				} else {
					options = { classes: {} };
				}
	
				// Find instances of this widget inside controlgroup and init them
				that.element
					.find( selector )
					.each( function() {
						var element = $( this );
						var instance = element[ widget ]( "instance" );
	
						// We need to clone the default options for this type of widget to avoid
						// polluting the variable options which has a wider scope than a single widget.
						var instanceOptions = $.widget.extend( {}, options );
	
						// If the button is the child of a spinner ignore it
						// TODO: Find a more generic solution
						if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
							return;
						}
	
						// Create the widget if it doesn't exist
						if ( !instance ) {
							instance = element[ widget ]()[ widget ]( "instance" );
						}
						if ( instance ) {
							instanceOptions.classes =
								that._resolveClassesValues( instanceOptions.classes, instance );
						}
						element[ widget ]( instanceOptions );
	
						// Store an instance of the controlgroup to be able to reference
						// from the outermost element for changing options and refresh
						var widgetElement = element[ widget ]( "widget" );
						$.data( widgetElement[ 0 ], "ui-controlgroup-data",
							instance ? instance : element[ widget ]( "instance" ) );
	
						childWidgets.push( widgetElement[ 0 ] );
					} );
			} );
	
			this.childWidgets = $( $.unique( childWidgets ) );
			this._addClass( this.childWidgets, "ui-controlgroup-item" );
		},
	
		_callChildMethod: function( method ) {
			this.childWidgets.each( function() {
				var element = $( this ),
					data = element.data( "ui-controlgroup-data" );
				if ( data && data[ method ] ) {
					data[ method ]();
				}
			} );
		},
	
		_updateCornerClass: function( element, position ) {
			var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
			var add = this._buildSimpleOptions( position, "label" ).classes.label;
	
			this._removeClass( element, null, remove );
			this._addClass( element, null, add );
		},
	
		_buildSimpleOptions: function( position, key ) {
			var direction = this.options.direction === "vertical";
			var result = {
				classes: {}
			};
			result.classes[ key ] = {
				"middle": "",
				"first": "ui-corner-" + ( direction ? "top" : "left" ),
				"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
				"only": "ui-corner-all"
			}[ position ];
	
			return result;
		},
	
		_spinnerOptions: function( position ) {
			var options = this._buildSimpleOptions( position, "ui-spinner" );
	
			options.classes[ "ui-spinner-up" ] = "";
			options.classes[ "ui-spinner-down" ] = "";
	
			return options;
		},
	
		_buttonOptions: function( position ) {
			return this._buildSimpleOptions( position, "ui-button" );
		},
	
		_checkboxradioOptions: function( position ) {
			return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
		},
	
		_selectmenuOptions: function( position ) {
			var direction = this.options.direction === "vertical";
			return {
				width: direction ? "auto" : false,
				classes: {
					middle: {
						"ui-selectmenu-button-open": "",
						"ui-selectmenu-button-closed": ""
					},
					first: {
						"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
						"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
					},
					last: {
						"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
						"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
					},
					only: {
						"ui-selectmenu-button-open": "ui-corner-top",
						"ui-selectmenu-button-closed": "ui-corner-all"
					}
	
				}[ position ]
			};
		},
	
		_resolveClassesValues: function( classes, instance ) {
			var result = {};
			$.each( classes, function( key ) {
				var current = instance.options.classes[ key ] || "";
				current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
				result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
			} );
			return result;
		},
	
		_setOption: function( key, value ) {
			if ( key === "direction" ) {
				this._removeClass( "ui-controlgroup-" + this.options.direction );
			}
	
			this._super( key, value );
			if ( key === "disabled" ) {
				this._callChildMethod( value ? "disable" : "enable" );
				return;
			}
	
			this.refresh();
		},
	
		refresh: function() {
			var children,
				that = this;
	
			this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
	
			if ( this.options.direction === "horizontal" ) {
				this._addClass( null, "ui-helper-clearfix" );
			}
			this._initWidgets();
	
			children = this.childWidgets;
	
			// We filter here because we need to track all childWidgets not just the visible ones
			if ( this.options.onlyVisible ) {
				children = children.filter( ":visible" );
			}
	
			if ( children.length ) {
	
				// We do this last because we need to make sure all enhancment is done
				// before determining first and last
				$.each( [ "first", "last" ], function( index, value ) {
					var instance = children[ value ]().data( "ui-controlgroup-data" );
	
					if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
						var options = that[ "_" + instance.widgetName + "Options" ](
							children.length === 1 ? "only" : value
						);
						options.classes = that._resolveClassesValues( options.classes, instance );
						instance.element[ instance.widgetName ]( options );
					} else {
						that._updateCornerClass( children[ value ](), value );
					}
				} );
	
				// Finally call the refresh method on each of the child widgets.
				this._callChildMethod( "refresh" );
			}
		}
	} );
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/controlgroup.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/checkboxradio.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/checkboxradio.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Checkboxradio 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Checkboxradio
	//>>group: Widgets
	//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
	//>>docs: http://api.jqueryui.com/checkboxradio/
	//>>demos: http://jqueryui.com/checkboxradio/
	//>>css.structure: ../../themes/base/core.css
	//>>css.structure: ../../themes/base/button.css
	//>>css.structure: ../../themes/base/checkboxradio.css
	//>>css.theme: ../../themes/base/theme.css
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/escape-selector.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/form-reset-mixin.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/labels.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
		version: "1.12.1",
		options: {
			disabled: null,
			label: null,
			icon: true,
			classes: {
				"ui-checkboxradio-label": "ui-corner-all",
				"ui-checkboxradio-icon": "ui-corner-all"
			}
		},
	
		_getCreateOptions: function() {
			var disabled, labels;
			var that = this;
			var options = this._super() || {};
	
			// We read the type here, because it makes more sense to throw a element type error first,
			// rather then the error for lack of a label. Often if its the wrong type, it
			// won't have a label (e.g. calling on a div, btn, etc)
			this._readType();
	
			labels = this.element.labels();
	
			// If there are multiple labels, use the last one
			this.label = $( labels[ labels.length - 1 ] );
			if ( !this.label.length ) {
				$.error( "No label found for checkboxradio widget" );
			}
	
			this.originalLabel = "";
	
			// We need to get the label text but this may also need to make sure it does not contain the
			// input itself.
			this.label.contents().not( this.element[ 0 ] ).each( function() {
	
				// The label contents could be text, html, or a mix. We concat each element to get a
				// string representation of the label, without the input as part of it.
				that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
			} );
	
			// Set the label option if we found label text
			if ( this.originalLabel ) {
				options.label = this.originalLabel;
			}
	
			disabled = this.element[ 0 ].disabled;
			if ( disabled != null ) {
				options.disabled = disabled;
			}
			return options;
		},
	
		_create: function() {
			var checked = this.element[ 0 ].checked;
	
			this._bindFormResetHandler();
	
			if ( this.options.disabled == null ) {
				this.options.disabled = this.element[ 0 ].disabled;
			}
	
			this._setOption( "disabled", this.options.disabled );
			this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
			this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
	
			if ( this.type === "radio" ) {
				this._addClass( this.label, "ui-checkboxradio-radio-label" );
			}
	
			if ( this.options.label && this.options.label !== this.originalLabel ) {
				this._updateLabel();
			} else if ( this.originalLabel ) {
				this.options.label = this.originalLabel;
			}
	
			this._enhance();
	
			if ( checked ) {
				this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
				if ( this.icon ) {
					this._addClass( this.icon, null, "ui-state-hover" );
				}
			}
	
			this._on( {
				change: "_toggleClasses",
				focus: function() {
					this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
				},
				blur: function() {
					this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
				}
			} );
		},
	
		_readType: function() {
			var nodeName = this.element[ 0 ].nodeName.toLowerCase();
			this.type = this.element[ 0 ].type;
			if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
				$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
					" and element.type=" + this.type );
			}
		},
	
		// Support jQuery Mobile enhanced option
		_enhance: function() {
			this._updateIcon( this.element[ 0 ].checked );
		},
	
		widget: function() {
			return this.label;
		},
	
		_getRadioGroup: function() {
			var group;
			var name = this.element[ 0 ].name;
			var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
	
			if ( !name ) {
				return $( [] );
			}
	
			if ( this.form.length ) {
				group = $( this.form[ 0 ].elements ).filter( nameSelector );
			} else {
	
				// Not inside a form, check all inputs that also are not inside a form
				group = $( nameSelector ).filter( function() {
					return $( this ).form().length === 0;
				} );
			}
	
			return group.not( this.element );
		},
	
		_toggleClasses: function() {
			var checked = this.element[ 0 ].checked;
			this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
	
			if ( this.options.icon && this.type === "checkbox" ) {
				this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
					._toggleClass( this.icon, null, "ui-icon-blank", !checked );
			}
	
			if ( this.type === "radio" ) {
				this._getRadioGroup()
					.each( function() {
						var instance = $( this ).checkboxradio( "instance" );
	
						if ( instance ) {
							instance._removeClass( instance.label,
								"ui-checkboxradio-checked", "ui-state-active" );
						}
					} );
			}
		},
	
		_destroy: function() {
			this._unbindFormResetHandler();
	
			if ( this.icon ) {
				this.icon.remove();
				this.iconSpace.remove();
			}
		},
	
		_setOption: function( key, value ) {
	
			// We don't allow the value to be set to nothing
			if ( key === "label" && !value ) {
				return;
			}
	
			this._super( key, value );
	
			if ( key === "disabled" ) {
				this._toggleClass( this.label, null, "ui-state-disabled", value );
				this.element[ 0 ].disabled = value;
	
				// Don't refresh when setting disabled
				return;
			}
			this.refresh();
		},
	
		_updateIcon: function( checked ) {
			var toAdd = "ui-icon ui-icon-background ";
	
			if ( this.options.icon ) {
				if ( !this.icon ) {
					this.icon = $( "<span>" );
					this.iconSpace = $( "<span> </span>" );
					this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
				}
	
				if ( this.type === "checkbox" ) {
					toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
					this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
				} else {
					toAdd += "ui-icon-blank";
				}
				this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
				if ( !checked ) {
					this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
				}
				this.icon.prependTo( this.label ).after( this.iconSpace );
			} else if ( this.icon !== undefined ) {
				this.icon.remove();
				this.iconSpace.remove();
				delete this.icon;
			}
		},
	
		_updateLabel: function() {
	
			// Remove the contents of the label ( minus the icon, icon space, and input )
			var contents = this.label.contents().not( this.element[ 0 ] );
			if ( this.icon ) {
				contents = contents.not( this.icon[ 0 ] );
			}
			if ( this.iconSpace ) {
				contents = contents.not( this.iconSpace[ 0 ] );
			}
			contents.remove();
	
			this.label.append( this.options.label );
		},
	
		refresh: function() {
			var checked = this.element[ 0 ].checked,
				isDisabled = this.element[ 0 ].disabled;
	
			this._updateIcon( checked );
			this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
			if ( this.options.label !== null ) {
				this._updateLabel();
			}
	
			if ( isDisabled !== this.options.disabled ) {
				this._setOptions( { "disabled": isDisabled } );
			}
		}
	
	} ] );
	
	return $.ui.checkboxradio;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/checkboxradio.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/escape-selector.js **/
jupyter.define('jquery-ui@1.12.1/ui/escape-selector.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	// Internal use only
	return $.ui.escapeSelector = ( function() {
		var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
		return function( selector ) {
			return selector.replace( selectorEscape, "\\$1" );
		};
	} )();
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/escape-selector.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/form-reset-mixin.js **/
jupyter.define('jquery-ui@1.12.1/ui/form-reset-mixin.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Form Reset Mixin 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Form Reset Mixin
	//>>group: Core
	//>>description: Refresh input widgets when their form is reset
	//>>docs: http://api.jqueryui.com/form-reset-mixin/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/form.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/version.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	return $.ui.formResetMixin = {
		_formResetHandler: function() {
			var form = $( this );
	
			// Wait for the form reset to actually happen before refreshing
			setTimeout( function() {
				var instances = form.data( "ui-form-reset-instances" );
				$.each( instances, function() {
					this.refresh();
				} );
			} );
		},
	
		_bindFormResetHandler: function() {
			this.form = this.element.form();
			if ( !this.form.length ) {
				return;
			}
	
			var instances = this.form.data( "ui-form-reset-instances" ) || [];
			if ( !instances.length ) {
	
				// We don't use _on() here because we use a single event handler per form
				this.form.on( "reset.ui-form-reset", this._formResetHandler );
			}
			instances.push( this );
			this.form.data( "ui-form-reset-instances", instances );
		},
	
		_unbindFormResetHandler: function() {
			if ( !this.form.length ) {
				return;
			}
	
			var instances = this.form.data( "ui-form-reset-instances" );
			instances.splice( $.inArray( this, instances ), 1 );
			if ( instances.length ) {
				this.form.data( "ui-form-reset-instances", instances );
			} else {
				this.form
					.removeData( "ui-form-reset-instances" )
					.off( "reset.ui-form-reset" );
			}
		}
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/form-reset-mixin.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/form.js **/
jupyter.define('jquery-ui@1.12.1/ui/form.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	// Support: IE8 Only
	// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
	// with a string, so we need to find the proper form.
	return $.fn.form = function() {
		return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/form.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/labels.js **/
jupyter.define('jquery-ui@1.12.1/ui/labels.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Labels 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: labels
	//>>group: Core
	//>>description: Find all the labels associated with a given input
	//>>docs: http://api.jqueryui.com/labels/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js'), __jupyter_require__('jquery-ui@1.12.1/ui/escape-selector.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	return $.fn.labels = function() {
		var ancestor, selector, id, labels, ancestors;
	
		// Check control.labels first
		if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
			return this.pushStack( this[ 0 ].labels );
		}
	
		// Support: IE <= 11, FF <= 37, Android <= 2.3 only
		// Above browsers do not support control.labels. Everything below is to support them
		// as well as document fragments. control.labels does not work on document fragments
		labels = this.eq( 0 ).parents( "label" );
	
		// Look for the label based on the id
		id = this.attr( "id" );
		if ( id ) {
	
			// We don't search against the document in case the element
			// is disconnected from the DOM
			ancestor = this.eq( 0 ).parents().last();
	
			// Get a full set of top level ancestors
			ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
	
			// Create a selector for the label based on the id
			selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
	
			labels = labels.add( ancestors.find( selector ).addBack( selector ) );
	
		}
	
		// Return whatever we have found for labels
		return this.pushStack( labels );
	};
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/labels.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/resizable.js **/
jupyter.define('jquery-ui@1.12.1/ui/widgets/resizable.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Resizable 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: Resizable
	//>>group: Interactions
	//>>description: Enables resize functionality for any element.
	//>>docs: http://api.jqueryui.com/resizable/
	//>>demos: http://jqueryui.com/resizable/
	//>>css.structure: ../../themes/base/core.css
	//>>css.structure: ../../themes/base/resizable.css
	//>>css.theme: ../../themes/base/theme.css
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
				__jupyter_require__('jquery@2.2.4/dist/jquery.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widgets/mouse.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/disable-selection.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/plugin.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/version.js'),
				__jupyter_require__('jquery-ui@1.12.1/ui/widget.js')
			], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	
	$.widget( "ui.resizable", $.ui.mouse, {
		version: "1.12.1",
		widgetEventPrefix: "resize",
		options: {
			alsoResize: false,
			animate: false,
			animateDuration: "slow",
			animateEasing: "swing",
			aspectRatio: false,
			autoHide: false,
			classes: {
				"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
			},
			containment: false,
			ghost: false,
			grid: false,
			handles: "e,s,se",
			helper: false,
			maxHeight: null,
			maxWidth: null,
			minHeight: 10,
			minWidth: 10,
	
			// See #7960
			zIndex: 90,
	
			// Callbacks
			resize: null,
			start: null,
			stop: null
		},
	
		_num: function( value ) {
			return parseFloat( value ) || 0;
		},
	
		_isNumber: function( value ) {
			return !isNaN( parseFloat( value ) );
		},
	
		_hasScroll: function( el, a ) {
	
			if ( $( el ).css( "overflow" ) === "hidden" ) {
				return false;
			}
	
			var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
				has = false;
	
			if ( el[ scroll ] > 0 ) {
				return true;
			}
	
			// TODO: determine which cases actually cause this to happen
			// if the element doesn't have the scroll set, see if it's possible to
			// set the scroll
			el[ scroll ] = 1;
			has = ( el[ scroll ] > 0 );
			el[ scroll ] = 0;
			return has;
		},
	
		_create: function() {
	
			var margins,
				o = this.options,
				that = this;
			this._addClass( "ui-resizable" );
	
			$.extend( this, {
				_aspectRatio: !!( o.aspectRatio ),
				aspectRatio: o.aspectRatio,
				originalElement: this.element,
				_proportionallyResizeElements: [],
				_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
			} );
	
			// Wrap the element if it cannot hold child nodes
			if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
	
				this.element.wrap(
					$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
						position: this.element.css( "position" ),
						width: this.element.outerWidth(),
						height: this.element.outerHeight(),
						top: this.element.css( "top" ),
						left: this.element.css( "left" )
					} )
				);
	
				this.element = this.element.parent().data(
					"ui-resizable", this.element.resizable( "instance" )
				);
	
				this.elementIsWrapper = true;
	
				margins = {
					marginTop: this.originalElement.css( "marginTop" ),
					marginRight: this.originalElement.css( "marginRight" ),
					marginBottom: this.originalElement.css( "marginBottom" ),
					marginLeft: this.originalElement.css( "marginLeft" )
				};
	
				this.element.css( margins );
				this.originalElement.css( "margin", 0 );
	
				// support: Safari
				// Prevent Safari textarea resize
				this.originalResizeStyle = this.originalElement.css( "resize" );
				this.originalElement.css( "resize", "none" );
	
				this._proportionallyResizeElements.push( this.originalElement.css( {
					position: "static",
					zoom: 1,
					display: "block"
				} ) );
	
				// Support: IE9
				// avoid IE jump (hard set the margin)
				this.originalElement.css( margins );
	
				this._proportionallyResize();
			}
	
			this._setupHandles();
	
			if ( o.autoHide ) {
				$( this.element )
					.on( "mouseenter", function() {
						if ( o.disabled ) {
							return;
						}
						that._removeClass( "ui-resizable-autohide" );
						that._handles.show();
					} )
					.on( "mouseleave", function() {
						if ( o.disabled ) {
							return;
						}
						if ( !that.resizing ) {
							that._addClass( "ui-resizable-autohide" );
							that._handles.hide();
						}
					} );
			}
	
			this._mouseInit();
		},
	
		_destroy: function() {
	
			this._mouseDestroy();
	
			var wrapper,
				_destroy = function( exp ) {
					$( exp )
						.removeData( "resizable" )
						.removeData( "ui-resizable" )
						.off( ".resizable" )
						.find( ".ui-resizable-handle" )
							.remove();
				};
	
			// TODO: Unwrap at same DOM position
			if ( this.elementIsWrapper ) {
				_destroy( this.element );
				wrapper = this.element;
				this.originalElement.css( {
					position: wrapper.css( "position" ),
					width: wrapper.outerWidth(),
					height: wrapper.outerHeight(),
					top: wrapper.css( "top" ),
					left: wrapper.css( "left" )
				} ).insertAfter( wrapper );
				wrapper.remove();
			}
	
			this.originalElement.css( "resize", this.originalResizeStyle );
			_destroy( this.originalElement );
	
			return this;
		},
	
		_setOption: function( key, value ) {
			this._super( key, value );
	
			switch ( key ) {
			case "handles":
				this._removeHandles();
				this._setupHandles();
				break;
			default:
				break;
			}
		},
	
		_setupHandles: function() {
			var o = this.options, handle, i, n, hname, axis, that = this;
			this.handles = o.handles ||
				( !$( ".ui-resizable-handle", this.element ).length ?
					"e,s,se" : {
						n: ".ui-resizable-n",
						e: ".ui-resizable-e",
						s: ".ui-resizable-s",
						w: ".ui-resizable-w",
						se: ".ui-resizable-se",
						sw: ".ui-resizable-sw",
						ne: ".ui-resizable-ne",
						nw: ".ui-resizable-nw"
					} );
	
			this._handles = $();
			if ( this.handles.constructor === String ) {
	
				if ( this.handles === "all" ) {
					this.handles = "n,e,s,w,se,sw,ne,nw";
				}
	
				n = this.handles.split( "," );
				this.handles = {};
	
				for ( i = 0; i < n.length; i++ ) {
	
					handle = $.trim( n[ i ] );
					hname = "ui-resizable-" + handle;
					axis = $( "<div>" );
					this._addClass( axis, "ui-resizable-handle " + hname );
	
					axis.css( { zIndex: o.zIndex } );
	
					this.handles[ handle ] = ".ui-resizable-" + handle;
					this.element.append( axis );
				}
	
			}
	
			this._renderAxis = function( target ) {
	
				var i, axis, padPos, padWrapper;
	
				target = target || this.element;
	
				for ( i in this.handles ) {
	
					if ( this.handles[ i ].constructor === String ) {
						this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
					} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
						this.handles[ i ] = $( this.handles[ i ] );
						this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
					}
	
					if ( this.elementIsWrapper &&
							this.originalElement[ 0 ]
								.nodeName
								.match( /^(textarea|input|select|button)$/i ) ) {
						axis = $( this.handles[ i ], this.element );
	
						padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
							axis.outerHeight() :
							axis.outerWidth();
	
						padPos = [ "padding",
							/ne|nw|n/.test( i ) ? "Top" :
							/se|sw|s/.test( i ) ? "Bottom" :
							/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
	
						target.css( padPos, padWrapper );
	
						this._proportionallyResize();
					}
	
					this._handles = this._handles.add( this.handles[ i ] );
				}
			};
	
			// TODO: make renderAxis a prototype function
			this._renderAxis( this.element );
	
			this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
			this._handles.disableSelection();
	
			this._handles.on( "mouseover", function() {
				if ( !that.resizing ) {
					if ( this.className ) {
						axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
					}
					that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
				}
			} );
	
			if ( o.autoHide ) {
				this._handles.hide();
				this._addClass( "ui-resizable-autohide" );
			}
		},
	
		_removeHandles: function() {
			this._handles.remove();
		},
	
		_mouseCapture: function( event ) {
			var i, handle,
				capture = false;
	
			for ( i in this.handles ) {
				handle = $( this.handles[ i ] )[ 0 ];
				if ( handle === event.target || $.contains( handle, event.target ) ) {
					capture = true;
				}
			}
	
			return !this.options.disabled && capture;
		},
	
		_mouseStart: function( event ) {
	
			var curleft, curtop, cursor,
				o = this.options,
				el = this.element;
	
			this.resizing = true;
	
			this._renderProxy();
	
			curleft = this._num( this.helper.css( "left" ) );
			curtop = this._num( this.helper.css( "top" ) );
	
			if ( o.containment ) {
				curleft += $( o.containment ).scrollLeft() || 0;
				curtop += $( o.containment ).scrollTop() || 0;
			}
	
			this.offset = this.helper.offset();
			this.position = { left: curleft, top: curtop };
	
			this.size = this._helper ? {
					width: this.helper.width(),
					height: this.helper.height()
				} : {
					width: el.width(),
					height: el.height()
				};
	
			this.originalSize = this._helper ? {
					width: el.outerWidth(),
					height: el.outerHeight()
				} : {
					width: el.width(),
					height: el.height()
				};
	
			this.sizeDiff = {
				width: el.outerWidth() - el.width(),
				height: el.outerHeight() - el.height()
			};
	
			this.originalPosition = { left: curleft, top: curtop };
			this.originalMousePosition = { left: event.pageX, top: event.pageY };
	
			this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
				o.aspectRatio :
				( ( this.originalSize.width / this.originalSize.height ) || 1 );
	
			cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
			$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
	
			this._addClass( "ui-resizable-resizing" );
			this._propagate( "start", event );
			return true;
		},
	
		_mouseDrag: function( event ) {
	
			var data, props,
				smp = this.originalMousePosition,
				a = this.axis,
				dx = ( event.pageX - smp.left ) || 0,
				dy = ( event.pageY - smp.top ) || 0,
				trigger = this._change[ a ];
	
			this._updatePrevProperties();
	
			if ( !trigger ) {
				return false;
			}
	
			data = trigger.apply( this, [ event, dx, dy ] );
	
			this._updateVirtualBoundaries( event.shiftKey );
			if ( this._aspectRatio || event.shiftKey ) {
				data = this._updateRatio( data, event );
			}
	
			data = this._respectSize( data, event );
	
			this._updateCache( data );
	
			this._propagate( "resize", event );
	
			props = this._applyChanges();
	
			if ( !this._helper && this._proportionallyResizeElements.length ) {
				this._proportionallyResize();
			}
	
			if ( !$.isEmptyObject( props ) ) {
				this._updatePrevProperties();
				this._trigger( "resize", event, this.ui() );
				this._applyChanges();
			}
	
			return false;
		},
	
		_mouseStop: function( event ) {
	
			this.resizing = false;
			var pr, ista, soffseth, soffsetw, s, left, top,
				o = this.options, that = this;
	
			if ( this._helper ) {
	
				pr = this._proportionallyResizeElements;
				ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
				soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
				soffsetw = ista ? 0 : that.sizeDiff.width;
	
				s = {
					width: ( that.helper.width()  - soffsetw ),
					height: ( that.helper.height() - soffseth )
				};
				left = ( parseFloat( that.element.css( "left" ) ) +
					( that.position.left - that.originalPosition.left ) ) || null;
				top = ( parseFloat( that.element.css( "top" ) ) +
					( that.position.top - that.originalPosition.top ) ) || null;
	
				if ( !o.animate ) {
					this.element.css( $.extend( s, { top: top, left: left } ) );
				}
	
				that.helper.height( that.size.height );
				that.helper.width( that.size.width );
	
				if ( this._helper && !o.animate ) {
					this._proportionallyResize();
				}
			}
	
			$( "body" ).css( "cursor", "auto" );
	
			this._removeClass( "ui-resizable-resizing" );
	
			this._propagate( "stop", event );
	
			if ( this._helper ) {
				this.helper.remove();
			}
	
			return false;
	
		},
	
		_updatePrevProperties: function() {
			this.prevPosition = {
				top: this.position.top,
				left: this.position.left
			};
			this.prevSize = {
				width: this.size.width,
				height: this.size.height
			};
		},
	
		_applyChanges: function() {
			var props = {};
	
			if ( this.position.top !== this.prevPosition.top ) {
				props.top = this.position.top + "px";
			}
			if ( this.position.left !== this.prevPosition.left ) {
				props.left = this.position.left + "px";
			}
			if ( this.size.width !== this.prevSize.width ) {
				props.width = this.size.width + "px";
			}
			if ( this.size.height !== this.prevSize.height ) {
				props.height = this.size.height + "px";
			}
	
			this.helper.css( props );
	
			return props;
		},
	
		_updateVirtualBoundaries: function( forceAspectRatio ) {
			var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
				o = this.options;
	
			b = {
				minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
				maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
				minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
				maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
			};
	
			if ( this._aspectRatio || forceAspectRatio ) {
				pMinWidth = b.minHeight * this.aspectRatio;
				pMinHeight = b.minWidth / this.aspectRatio;
				pMaxWidth = b.maxHeight * this.aspectRatio;
				pMaxHeight = b.maxWidth / this.aspectRatio;
	
				if ( pMinWidth > b.minWidth ) {
					b.minWidth = pMinWidth;
				}
				if ( pMinHeight > b.minHeight ) {
					b.minHeight = pMinHeight;
				}
				if ( pMaxWidth < b.maxWidth ) {
					b.maxWidth = pMaxWidth;
				}
				if ( pMaxHeight < b.maxHeight ) {
					b.maxHeight = pMaxHeight;
				}
			}
			this._vBoundaries = b;
		},
	
		_updateCache: function( data ) {
			this.offset = this.helper.offset();
			if ( this._isNumber( data.left ) ) {
				this.position.left = data.left;
			}
			if ( this._isNumber( data.top ) ) {
				this.position.top = data.top;
			}
			if ( this._isNumber( data.height ) ) {
				this.size.height = data.height;
			}
			if ( this._isNumber( data.width ) ) {
				this.size.width = data.width;
			}
		},
	
		_updateRatio: function( data ) {
	
			var cpos = this.position,
				csize = this.size,
				a = this.axis;
	
			if ( this._isNumber( data.height ) ) {
				data.width = ( data.height * this.aspectRatio );
			} else if ( this._isNumber( data.width ) ) {
				data.height = ( data.width / this.aspectRatio );
			}
	
			if ( a === "sw" ) {
				data.left = cpos.left + ( csize.width - data.width );
				data.top = null;
			}
			if ( a === "nw" ) {
				data.top = cpos.top + ( csize.height - data.height );
				data.left = cpos.left + ( csize.width - data.width );
			}
	
			return data;
		},
	
		_respectSize: function( data ) {
	
			var o = this._vBoundaries,
				a = this.axis,
				ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
				ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
				isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
				isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
				dw = this.originalPosition.left + this.originalSize.width,
				dh = this.originalPosition.top + this.originalSize.height,
				cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
			if ( isminw ) {
				data.width = o.minWidth;
			}
			if ( isminh ) {
				data.height = o.minHeight;
			}
			if ( ismaxw ) {
				data.width = o.maxWidth;
			}
			if ( ismaxh ) {
				data.height = o.maxHeight;
			}
	
			if ( isminw && cw ) {
				data.left = dw - o.minWidth;
			}
			if ( ismaxw && cw ) {
				data.left = dw - o.maxWidth;
			}
			if ( isminh && ch ) {
				data.top = dh - o.minHeight;
			}
			if ( ismaxh && ch ) {
				data.top = dh - o.maxHeight;
			}
	
			// Fixing jump error on top/left - bug #2330
			if ( !data.width && !data.height && !data.left && data.top ) {
				data.top = null;
			} else if ( !data.width && !data.height && !data.top && data.left ) {
				data.left = null;
			}
	
			return data;
		},
	
		_getPaddingPlusBorderDimensions: function( element ) {
			var i = 0,
				widths = [],
				borders = [
					element.css( "borderTopWidth" ),
					element.css( "borderRightWidth" ),
					element.css( "borderBottomWidth" ),
					element.css( "borderLeftWidth" )
				],
				paddings = [
					element.css( "paddingTop" ),
					element.css( "paddingRight" ),
					element.css( "paddingBottom" ),
					element.css( "paddingLeft" )
				];
	
			for ( ; i < 4; i++ ) {
				widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
				widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
			}
	
			return {
				height: widths[ 0 ] + widths[ 2 ],
				width: widths[ 1 ] + widths[ 3 ]
			};
		},
	
		_proportionallyResize: function() {
	
			if ( !this._proportionallyResizeElements.length ) {
				return;
			}
	
			var prel,
				i = 0,
				element = this.helper || this.element;
	
			for ( ; i < this._proportionallyResizeElements.length; i++ ) {
	
				prel = this._proportionallyResizeElements[ i ];
	
				// TODO: Seems like a bug to cache this.outerDimensions
				// considering that we are in a loop.
				if ( !this.outerDimensions ) {
					this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
				}
	
				prel.css( {
					height: ( element.height() - this.outerDimensions.height ) || 0,
					width: ( element.width() - this.outerDimensions.width ) || 0
				} );
	
			}
	
		},
	
		_renderProxy: function() {
	
			var el = this.element, o = this.options;
			this.elementOffset = el.offset();
	
			if ( this._helper ) {
	
				this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
	
				this._addClass( this.helper, this._helper );
				this.helper.css( {
					width: this.element.outerWidth(),
					height: this.element.outerHeight(),
					position: "absolute",
					left: this.elementOffset.left + "px",
					top: this.elementOffset.top + "px",
					zIndex: ++o.zIndex //TODO: Don't modify option
				} );
	
				this.helper
					.appendTo( "body" )
					.disableSelection();
	
			} else {
				this.helper = this.element;
			}
	
		},
	
		_change: {
			e: function( event, dx ) {
				return { width: this.originalSize.width + dx };
			},
			w: function( event, dx ) {
				var cs = this.originalSize, sp = this.originalPosition;
				return { left: sp.left + dx, width: cs.width - dx };
			},
			n: function( event, dx, dy ) {
				var cs = this.originalSize, sp = this.originalPosition;
				return { top: sp.top + dy, height: cs.height - dy };
			},
			s: function( event, dx, dy ) {
				return { height: this.originalSize.height + dy };
			},
			se: function( event, dx, dy ) {
				return $.extend( this._change.s.apply( this, arguments ),
					this._change.e.apply( this, [ event, dx, dy ] ) );
			},
			sw: function( event, dx, dy ) {
				return $.extend( this._change.s.apply( this, arguments ),
					this._change.w.apply( this, [ event, dx, dy ] ) );
			},
			ne: function( event, dx, dy ) {
				return $.extend( this._change.n.apply( this, arguments ),
					this._change.e.apply( this, [ event, dx, dy ] ) );
			},
			nw: function( event, dx, dy ) {
				return $.extend( this._change.n.apply( this, arguments ),
					this._change.w.apply( this, [ event, dx, dy ] ) );
			}
		},
	
		_propagate: function( n, event ) {
			$.ui.plugin.call( this, n, [ event, this.ui() ] );
			( n !== "resize" && this._trigger( n, event, this.ui() ) );
		},
	
		plugins: {},
	
		ui: function() {
			return {
				originalElement: this.originalElement,
				element: this.element,
				helper: this.helper,
				position: this.position,
				size: this.size,
				originalSize: this.originalSize,
				originalPosition: this.originalPosition
			};
		}
	
	} );
	
	/*
	 * Resizable Extensions
	 */
	
	$.ui.plugin.add( "resizable", "animate", {
	
		stop: function( event ) {
			var that = $( this ).resizable( "instance" ),
				o = that.options,
				pr = that._proportionallyResizeElements,
				ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
				soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
				soffsetw = ista ? 0 : that.sizeDiff.width,
				style = {
					width: ( that.size.width - soffsetw ),
					height: ( that.size.height - soffseth )
				},
				left = ( parseFloat( that.element.css( "left" ) ) +
					( that.position.left - that.originalPosition.left ) ) || null,
				top = ( parseFloat( that.element.css( "top" ) ) +
					( that.position.top - that.originalPosition.top ) ) || null;
	
			that.element.animate(
				$.extend( style, top && left ? { top: top, left: left } : {} ), {
					duration: o.animateDuration,
					easing: o.animateEasing,
					step: function() {
	
						var data = {
							width: parseFloat( that.element.css( "width" ) ),
							height: parseFloat( that.element.css( "height" ) ),
							top: parseFloat( that.element.css( "top" ) ),
							left: parseFloat( that.element.css( "left" ) )
						};
	
						if ( pr && pr.length ) {
							$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
						}
	
						// Propagating resize, and updating values for each animation step
						that._updateCache( data );
						that._propagate( "resize", event );
	
					}
				}
			);
		}
	
	} );
	
	$.ui.plugin.add( "resizable", "containment", {
	
		start: function() {
			var element, p, co, ch, cw, width, height,
				that = $( this ).resizable( "instance" ),
				o = that.options,
				el = that.element,
				oc = o.containment,
				ce = ( oc instanceof $ ) ?
					oc.get( 0 ) :
					( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
	
			if ( !ce ) {
				return;
			}
	
			that.containerElement = $( ce );
	
			if ( /document/.test( oc ) || oc === document ) {
				that.containerOffset = {
					left: 0,
					top: 0
				};
				that.containerPosition = {
					left: 0,
					top: 0
				};
	
				that.parentData = {
					element: $( document ),
					left: 0,
					top: 0,
					width: $( document ).width(),
					height: $( document ).height() || document.body.parentNode.scrollHeight
				};
			} else {
				element = $( ce );
				p = [];
				$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
					p[ i ] = that._num( element.css( "padding" + name ) );
				} );
	
				that.containerOffset = element.offset();
				that.containerPosition = element.position();
				that.containerSize = {
					height: ( element.innerHeight() - p[ 3 ] ),
					width: ( element.innerWidth() - p[ 1 ] )
				};
	
				co = that.containerOffset;
				ch = that.containerSize.height;
				cw = that.containerSize.width;
				width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
				height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
	
				that.parentData = {
					element: ce,
					left: co.left,
					top: co.top,
					width: width,
					height: height
				};
			}
		},
	
		resize: function( event ) {
			var woset, hoset, isParent, isOffsetRelative,
				that = $( this ).resizable( "instance" ),
				o = that.options,
				co = that.containerOffset,
				cp = that.position,
				pRatio = that._aspectRatio || event.shiftKey,
				cop = {
					top: 0,
					left: 0
				},
				ce = that.containerElement,
				continueResize = true;
	
			if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
				cop = co;
			}
	
			if ( cp.left < ( that._helper ? co.left : 0 ) ) {
				that.size.width = that.size.width +
					( that._helper ?
						( that.position.left - co.left ) :
						( that.position.left - cop.left ) );
	
				if ( pRatio ) {
					that.size.height = that.size.width / that.aspectRatio;
					continueResize = false;
				}
				that.position.left = o.helper ? co.left : 0;
			}
	
			if ( cp.top < ( that._helper ? co.top : 0 ) ) {
				that.size.height = that.size.height +
					( that._helper ?
						( that.position.top - co.top ) :
						that.position.top );
	
				if ( pRatio ) {
					that.size.width = that.size.height * that.aspectRatio;
					continueResize = false;
				}
				that.position.top = that._helper ? co.top : 0;
			}
	
			isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
			isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
	
			if ( isParent && isOffsetRelative ) {
				that.offset.left = that.parentData.left + that.position.left;
				that.offset.top = that.parentData.top + that.position.top;
			} else {
				that.offset.left = that.element.offset().left;
				that.offset.top = that.element.offset().top;
			}
	
			woset = Math.abs( that.sizeDiff.width +
				( that._helper ?
					that.offset.left - cop.left :
					( that.offset.left - co.left ) ) );
	
			hoset = Math.abs( that.sizeDiff.height +
				( that._helper ?
					that.offset.top - cop.top :
					( that.offset.top - co.top ) ) );
	
			if ( woset + that.size.width >= that.parentData.width ) {
				that.size.width = that.parentData.width - woset;
				if ( pRatio ) {
					that.size.height = that.size.width / that.aspectRatio;
					continueResize = false;
				}
			}
	
			if ( hoset + that.size.height >= that.parentData.height ) {
				that.size.height = that.parentData.height - hoset;
				if ( pRatio ) {
					that.size.width = that.size.height * that.aspectRatio;
					continueResize = false;
				}
			}
	
			if ( !continueResize ) {
				that.position.left = that.prevPosition.left;
				that.position.top = that.prevPosition.top;
				that.size.width = that.prevSize.width;
				that.size.height = that.prevSize.height;
			}
		},
	
		stop: function() {
			var that = $( this ).resizable( "instance" ),
				o = that.options,
				co = that.containerOffset,
				cop = that.containerPosition,
				ce = that.containerElement,
				helper = $( that.helper ),
				ho = helper.offset(),
				w = helper.outerWidth() - that.sizeDiff.width,
				h = helper.outerHeight() - that.sizeDiff.height;
	
			if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
				$( this ).css( {
					left: ho.left - cop.left - co.left,
					width: w,
					height: h
				} );
			}
	
			if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
				$( this ).css( {
					left: ho.left - cop.left - co.left,
					width: w,
					height: h
				} );
			}
		}
	} );
	
	$.ui.plugin.add( "resizable", "alsoResize", {
	
		start: function() {
			var that = $( this ).resizable( "instance" ),
				o = that.options;
	
			$( o.alsoResize ).each( function() {
				var el = $( this );
				el.data( "ui-resizable-alsoresize", {
					width: parseFloat( el.width() ), height: parseFloat( el.height() ),
					left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
				} );
			} );
		},
	
		resize: function( event, ui ) {
			var that = $( this ).resizable( "instance" ),
				o = that.options,
				os = that.originalSize,
				op = that.originalPosition,
				delta = {
					height: ( that.size.height - os.height ) || 0,
					width: ( that.size.width - os.width ) || 0,
					top: ( that.position.top - op.top ) || 0,
					left: ( that.position.left - op.left ) || 0
				};
	
				$( o.alsoResize ).each( function() {
					var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
						css = el.parents( ui.originalElement[ 0 ] ).length ?
								[ "width", "height" ] :
								[ "width", "height", "top", "left" ];
	
					$.each( css, function( i, prop ) {
						var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
						if ( sum && sum >= 0 ) {
							style[ prop ] = sum || null;
						}
					} );
	
					el.css( style );
				} );
		},
	
		stop: function() {
			$( this ).removeData( "ui-resizable-alsoresize" );
		}
	} );
	
	$.ui.plugin.add( "resizable", "ghost", {
	
		start: function() {
	
			var that = $( this ).resizable( "instance" ), cs = that.size;
	
			that.ghost = that.originalElement.clone();
			that.ghost.css( {
				opacity: 0.25,
				display: "block",
				position: "relative",
				height: cs.height,
				width: cs.width,
				margin: 0,
				left: 0,
				top: 0
			} );
	
			that._addClass( that.ghost, "ui-resizable-ghost" );
	
			// DEPRECATED
			// TODO: remove after 1.12
			if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
	
				// Ghost option
				that.ghost.addClass( this.options.ghost );
			}
	
			that.ghost.appendTo( that.helper );
	
		},
	
		resize: function() {
			var that = $( this ).resizable( "instance" );
			if ( that.ghost ) {
				that.ghost.css( {
					position: "relative",
					height: that.size.height,
					width: that.size.width
				} );
			}
		},
	
		stop: function() {
			var that = $( this ).resizable( "instance" );
			if ( that.ghost && that.helper ) {
				that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
			}
		}
	
	} );
	
	$.ui.plugin.add( "resizable", "grid", {
	
		resize: function() {
			var outerDimensions,
				that = $( this ).resizable( "instance" ),
				o = that.options,
				cs = that.size,
				os = that.originalSize,
				op = that.originalPosition,
				a = that.axis,
				grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
				gridX = ( grid[ 0 ] || 1 ),
				gridY = ( grid[ 1 ] || 1 ),
				ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
				oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
				newWidth = os.width + ox,
				newHeight = os.height + oy,
				isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
				isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
				isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
				isMinHeight = o.minHeight && ( o.minHeight > newHeight );
	
			o.grid = grid;
	
			if ( isMinWidth ) {
				newWidth += gridX;
			}
			if ( isMinHeight ) {
				newHeight += gridY;
			}
			if ( isMaxWidth ) {
				newWidth -= gridX;
			}
			if ( isMaxHeight ) {
				newHeight -= gridY;
			}
	
			if ( /^(se|s|e)$/.test( a ) ) {
				that.size.width = newWidth;
				that.size.height = newHeight;
			} else if ( /^(ne)$/.test( a ) ) {
				that.size.width = newWidth;
				that.size.height = newHeight;
				that.position.top = op.top - oy;
			} else if ( /^(sw)$/.test( a ) ) {
				that.size.width = newWidth;
				that.size.height = newHeight;
				that.position.left = op.left - ox;
			} else {
				if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
					outerDimensions = that._getPaddingPlusBorderDimensions( this );
				}
	
				if ( newHeight - gridY > 0 ) {
					that.size.height = newHeight;
					that.position.top = op.top - oy;
				} else {
					newHeight = gridY - outerDimensions.height;
					that.size.height = newHeight;
					that.position.top = op.top + os.height - newHeight;
				}
				if ( newWidth - gridX > 0 ) {
					that.size.width = newWidth;
					that.position.left = op.left - ox;
				} else {
					newWidth = gridX - outerDimensions.width;
					that.size.width = newWidth;
					that.position.left = op.left + os.width - newWidth;
				}
			}
		}
	
	} );
	
	return $.ui.resizable;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/widgets/resizable.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/disable-selection.js **/
jupyter.define('jquery-ui@1.12.1/ui/disable-selection.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Disable Selection 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: disableSelection
	//>>group: Core
	//>>description: Disable selection of text content within the set of matched elements.
	//>>docs: http://api.jqueryui.com/disableSelection/
	
	// This file is deprecated
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	return $.fn.extend( {
		disableSelection: ( function() {
			var eventType = "onselectstart" in document.createElement( "div" ) ?
				"selectstart" :
				"mousedown";
	
			return function() {
				return this.on( eventType + ".ui-disableSelection", function( event ) {
					event.preventDefault();
				} );
			};
		} )(),
	
		enableSelection: function() {
			return this.off( ".ui-disableSelection" );
		}
	} );
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/disable-selection.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/focusable.js **/
jupyter.define('jquery-ui@1.12.1/ui/focusable.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Focusable 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: :focusable Selector
	//>>group: Core
	//>>description: Selects elements which can be focused.
	//>>docs: http://api.jqueryui.com/focusable-selector/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	// Selectors
	$.ui.focusable = function( element, hasTabindex ) {
		var map, mapName, img, focusableIfVisible, fieldset,
			nodeName = element.nodeName.toLowerCase();
	
		if ( "area" === nodeName ) {
			map = element.parentNode;
			mapName = map.name;
			if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
				return false;
			}
			img = $( "img[usemap='#" + mapName + "']" );
			return img.length > 0 && img.is( ":visible" );
		}
	
		if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
			focusableIfVisible = !element.disabled;
	
			if ( focusableIfVisible ) {
	
				// Form controls within a disabled fieldset are disabled.
				// However, controls within the fieldset's legend do not get disabled.
				// Since controls generally aren't placed inside legends, we skip
				// this portion of the check.
				fieldset = $( element ).closest( "fieldset" )[ 0 ];
				if ( fieldset ) {
					focusableIfVisible = !fieldset.disabled;
				}
			}
		} else if ( "a" === nodeName ) {
			focusableIfVisible = element.href || hasTabindex;
		} else {
			focusableIfVisible = hasTabindex;
		}
	
		return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
	};
	
	// Support: IE 8 only
	// IE 8 doesn't resolve inherit to visible/hidden for computed values
	function visible( element ) {
		var visibility = element.css( "visibility" );
		while ( visibility === "inherit" ) {
			element = element.parent();
			visibility = element.css( "visibility" );
		}
		return visibility !== "hidden";
	}
	
	$.extend( $.expr[ ":" ], {
		focusable: function( element ) {
			return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
		}
	} );
	
	return $.ui.focusable;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/focusable.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/tabbable.js **/
jupyter.define('jquery-ui@1.12.1/ui/tabbable.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Tabbable 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: :tabbable Selector
	//>>group: Core
	//>>description: Selects elements which can be tabbed to.
	//>>docs: http://api.jqueryui.com/tabbable-selector/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js'), __jupyter_require__('jquery-ui@1.12.1/ui/focusable.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	return $.extend( $.expr[ ":" ], {
		tabbable: function( element ) {
			var tabIndex = $.attr( element, "tabindex" ),
				hasTabindex = tabIndex != null;
			return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
		}
	} );
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/tabbable.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/unique-id.js **/
jupyter.define('jquery-ui@1.12.1/ui/unique-id.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Unique ID 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 */
	
	//>>label: uniqueId
	//>>group: Core
	//>>description: Functions to generate and remove uniqueId's
	//>>docs: http://api.jqueryui.com/uniqueId/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	} ( function( $ ) {
	
	return $.fn.extend( {
		uniqueId: ( function() {
			var uuid = 0;
	
			return function() {
				return this.each( function() {
					if ( !this.id ) {
						this.id = "ui-id-" + ( ++uuid );
					}
				} );
			};
		} )(),
	
		removeUniqueId: function() {
			return this.each( function() {
				if ( /^ui-id-\d+$/.test( this.id ) ) {
					$( this ).removeAttr( "id" );
				}
			} );
		}
	} );
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/unique-id.js **/


/** START DEFINE BLOCK for jquery-ui@1.12.1/ui/position.js **/
jupyter.define('jquery-ui@1.12.1/ui/position.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery UI Position 1.12.1
	 * http://jqueryui.com
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license.
	 * http://jquery.org/license
	 *
	 * http://api.jqueryui.com/position/
	 */
	
	//>>label: Position
	//>>group: Core
	//>>description: Positions elements relative to other elements.
	//>>docs: http://api.jqueryui.com/position/
	//>>demos: http://jqueryui.com/position/
	
	( function( factory ) {
		if ( true ) {
	
			// AMD. Register as an anonymous module.
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __jupyter_require__('jquery@2.2.4/dist/jquery.js'), __jupyter_require__('jquery-ui@1.12.1/ui/version.js') ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
	
			// Browser globals
			factory( jQuery );
		}
	}( function( $ ) {
	( function() {
	var cachedScrollbarWidth,
		max = Math.max,
		abs = Math.abs,
		rhorizontal = /left|center|right/,
		rvertical = /top|center|bottom/,
		roffset = /[\+\-]\d+(\.[\d]+)?%?/,
		rposition = /^\w+/,
		rpercent = /%$/,
		_position = $.fn.position;
	
	function getOffsets( offsets, width, height ) {
		return [
			parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
			parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
		];
	}
	
	function parseCss( element, property ) {
		return parseInt( $.css( element, property ), 10 ) || 0;
	}
	
	function getDimensions( elem ) {
		var raw = elem[ 0 ];
		if ( raw.nodeType === 9 ) {
			return {
				width: elem.width(),
				height: elem.height(),
				offset: { top: 0, left: 0 }
			};
		}
		if ( $.isWindow( raw ) ) {
			return {
				width: elem.width(),
				height: elem.height(),
				offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
			};
		}
		if ( raw.preventDefault ) {
			return {
				width: 0,
				height: 0,
				offset: { top: raw.pageY, left: raw.pageX }
			};
		}
		return {
			width: elem.outerWidth(),
			height: elem.outerHeight(),
			offset: elem.offset()
		};
	}
	
	$.position = {
		scrollbarWidth: function() {
			if ( cachedScrollbarWidth !== undefined ) {
				return cachedScrollbarWidth;
			}
			var w1, w2,
				div = $( "<div " +
					"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
					"<div style='height:100px;width:auto;'></div></div>" ),
				innerDiv = div.children()[ 0 ];
	
			$( "body" ).append( div );
			w1 = innerDiv.offsetWidth;
			div.css( "overflow", "scroll" );
	
			w2 = innerDiv.offsetWidth;
	
			if ( w1 === w2 ) {
				w2 = div[ 0 ].clientWidth;
			}
	
			div.remove();
	
			return ( cachedScrollbarWidth = w1 - w2 );
		},
		getScrollInfo: function( within ) {
			var overflowX = within.isWindow || within.isDocument ? "" :
					within.element.css( "overflow-x" ),
				overflowY = within.isWindow || within.isDocument ? "" :
					within.element.css( "overflow-y" ),
				hasOverflowX = overflowX === "scroll" ||
					( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
				hasOverflowY = overflowY === "scroll" ||
					( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
			return {
				width: hasOverflowY ? $.position.scrollbarWidth() : 0,
				height: hasOverflowX ? $.position.scrollbarWidth() : 0
			};
		},
		getWithinInfo: function( element ) {
			var withinElement = $( element || window ),
				isWindow = $.isWindow( withinElement[ 0 ] ),
				isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
				hasOffset = !isWindow && !isDocument;
			return {
				element: withinElement,
				isWindow: isWindow,
				isDocument: isDocument,
				offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
				scrollLeft: withinElement.scrollLeft(),
				scrollTop: withinElement.scrollTop(),
				width: withinElement.outerWidth(),
				height: withinElement.outerHeight()
			};
		}
	};
	
	$.fn.position = function( options ) {
		if ( !options || !options.of ) {
			return _position.apply( this, arguments );
		}
	
		// Make a copy, we don't want to modify arguments
		options = $.extend( {}, options );
	
		var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
			target = $( options.of ),
			within = $.position.getWithinInfo( options.within ),
			scrollInfo = $.position.getScrollInfo( within ),
			collision = ( options.collision || "flip" ).split( " " ),
			offsets = {};
	
		dimensions = getDimensions( target );
		if ( target[ 0 ].preventDefault ) {
	
			// Force left top to allow flipping
			options.at = "left top";
		}
		targetWidth = dimensions.width;
		targetHeight = dimensions.height;
		targetOffset = dimensions.offset;
	
		// Clone to reuse original targetOffset later
		basePosition = $.extend( {}, targetOffset );
	
		// Force my and at to have valid horizontal and vertical positions
		// if a value is missing or invalid, it will be converted to center
		$.each( [ "my", "at" ], function() {
			var pos = ( options[ this ] || "" ).split( " " ),
				horizontalOffset,
				verticalOffset;
	
			if ( pos.length === 1 ) {
				pos = rhorizontal.test( pos[ 0 ] ) ?
					pos.concat( [ "center" ] ) :
					rvertical.test( pos[ 0 ] ) ?
						[ "center" ].concat( pos ) :
						[ "center", "center" ];
			}
			pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
			pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
	
			// Calculate offsets
			horizontalOffset = roffset.exec( pos[ 0 ] );
			verticalOffset = roffset.exec( pos[ 1 ] );
			offsets[ this ] = [
				horizontalOffset ? horizontalOffset[ 0 ] : 0,
				verticalOffset ? verticalOffset[ 0 ] : 0
			];
	
			// Reduce to just the positions without the offsets
			options[ this ] = [
				rposition.exec( pos[ 0 ] )[ 0 ],
				rposition.exec( pos[ 1 ] )[ 0 ]
			];
		} );
	
		// Normalize collision option
		if ( collision.length === 1 ) {
			collision[ 1 ] = collision[ 0 ];
		}
	
		if ( options.at[ 0 ] === "right" ) {
			basePosition.left += targetWidth;
		} else if ( options.at[ 0 ] === "center" ) {
			basePosition.left += targetWidth / 2;
		}
	
		if ( options.at[ 1 ] === "bottom" ) {
			basePosition.top += targetHeight;
		} else if ( options.at[ 1 ] === "center" ) {
			basePosition.top += targetHeight / 2;
		}
	
		atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
		basePosition.left += atOffset[ 0 ];
		basePosition.top += atOffset[ 1 ];
	
		return this.each( function() {
			var collisionPosition, using,
				elem = $( this ),
				elemWidth = elem.outerWidth(),
				elemHeight = elem.outerHeight(),
				marginLeft = parseCss( this, "marginLeft" ),
				marginTop = parseCss( this, "marginTop" ),
				collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
					scrollInfo.width,
				collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
					scrollInfo.height,
				position = $.extend( {}, basePosition ),
				myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
	
			if ( options.my[ 0 ] === "right" ) {
				position.left -= elemWidth;
			} else if ( options.my[ 0 ] === "center" ) {
				position.left -= elemWidth / 2;
			}
	
			if ( options.my[ 1 ] === "bottom" ) {
				position.top -= elemHeight;
			} else if ( options.my[ 1 ] === "center" ) {
				position.top -= elemHeight / 2;
			}
	
			position.left += myOffset[ 0 ];
			position.top += myOffset[ 1 ];
	
			collisionPosition = {
				marginLeft: marginLeft,
				marginTop: marginTop
			};
	
			$.each( [ "left", "top" ], function( i, dir ) {
				if ( $.ui.position[ collision[ i ] ] ) {
					$.ui.position[ collision[ i ] ][ dir ]( position, {
						targetWidth: targetWidth,
						targetHeight: targetHeight,
						elemWidth: elemWidth,
						elemHeight: elemHeight,
						collisionPosition: collisionPosition,
						collisionWidth: collisionWidth,
						collisionHeight: collisionHeight,
						offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
						my: options.my,
						at: options.at,
						within: within,
						elem: elem
					} );
				}
			} );
	
			if ( options.using ) {
	
				// Adds feedback as second argument to using callback, if present
				using = function( props ) {
					var left = targetOffset.left - position.left,
						right = left + targetWidth - elemWidth,
						top = targetOffset.top - position.top,
						bottom = top + targetHeight - elemHeight,
						feedback = {
							target: {
								element: target,
								left: targetOffset.left,
								top: targetOffset.top,
								width: targetWidth,
								height: targetHeight
							},
							element: {
								element: elem,
								left: position.left,
								top: position.top,
								width: elemWidth,
								height: elemHeight
							},
							horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
							vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
						};
					if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
						feedback.horizontal = "center";
					}
					if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
						feedback.vertical = "middle";
					}
					if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
						feedback.important = "horizontal";
					} else {
						feedback.important = "vertical";
					}
					options.using.call( this, props, feedback );
				};
			}
	
			elem.offset( $.extend( position, { using: using } ) );
		} );
	};
	
	$.ui.position = {
		fit: {
			left: function( position, data ) {
				var within = data.within,
					withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
					outerWidth = within.width,
					collisionPosLeft = position.left - data.collisionPosition.marginLeft,
					overLeft = withinOffset - collisionPosLeft,
					overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
					newOverRight;
	
				// Element is wider than within
				if ( data.collisionWidth > outerWidth ) {
	
					// Element is initially over the left side of within
					if ( overLeft > 0 && overRight <= 0 ) {
						newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
							withinOffset;
						position.left += overLeft - newOverRight;
	
					// Element is initially over right side of within
					} else if ( overRight > 0 && overLeft <= 0 ) {
						position.left = withinOffset;
	
					// Element is initially over both left and right sides of within
					} else {
						if ( overLeft > overRight ) {
							position.left = withinOffset + outerWidth - data.collisionWidth;
						} else {
							position.left = withinOffset;
						}
					}
	
				// Too far left -> align with left edge
				} else if ( overLeft > 0 ) {
					position.left += overLeft;
	
				// Too far right -> align with right edge
				} else if ( overRight > 0 ) {
					position.left -= overRight;
	
				// Adjust based on position and margin
				} else {
					position.left = max( position.left - collisionPosLeft, position.left );
				}
			},
			top: function( position, data ) {
				var within = data.within,
					withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
					outerHeight = data.within.height,
					collisionPosTop = position.top - data.collisionPosition.marginTop,
					overTop = withinOffset - collisionPosTop,
					overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
					newOverBottom;
	
				// Element is taller than within
				if ( data.collisionHeight > outerHeight ) {
	
					// Element is initially over the top of within
					if ( overTop > 0 && overBottom <= 0 ) {
						newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
							withinOffset;
						position.top += overTop - newOverBottom;
	
					// Element is initially over bottom of within
					} else if ( overBottom > 0 && overTop <= 0 ) {
						position.top = withinOffset;
	
					// Element is initially over both top and bottom of within
					} else {
						if ( overTop > overBottom ) {
							position.top = withinOffset + outerHeight - data.collisionHeight;
						} else {
							position.top = withinOffset;
						}
					}
	
				// Too far up -> align with top
				} else if ( overTop > 0 ) {
					position.top += overTop;
	
				// Too far down -> align with bottom edge
				} else if ( overBottom > 0 ) {
					position.top -= overBottom;
	
				// Adjust based on position and margin
				} else {
					position.top = max( position.top - collisionPosTop, position.top );
				}
			}
		},
		flip: {
			left: function( position, data ) {
				var within = data.within,
					withinOffset = within.offset.left + within.scrollLeft,
					outerWidth = within.width,
					offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
					collisionPosLeft = position.left - data.collisionPosition.marginLeft,
					overLeft = collisionPosLeft - offsetLeft,
					overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
					myOffset = data.my[ 0 ] === "left" ?
						-data.elemWidth :
						data.my[ 0 ] === "right" ?
							data.elemWidth :
							0,
					atOffset = data.at[ 0 ] === "left" ?
						data.targetWidth :
						data.at[ 0 ] === "right" ?
							-data.targetWidth :
							0,
					offset = -2 * data.offset[ 0 ],
					newOverRight,
					newOverLeft;
	
				if ( overLeft < 0 ) {
					newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
						outerWidth - withinOffset;
					if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
						position.left += myOffset + atOffset + offset;
					}
				} else if ( overRight > 0 ) {
					newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
						atOffset + offset - offsetLeft;
					if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
						position.left += myOffset + atOffset + offset;
					}
				}
			},
			top: function( position, data ) {
				var within = data.within,
					withinOffset = within.offset.top + within.scrollTop,
					outerHeight = within.height,
					offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
					collisionPosTop = position.top - data.collisionPosition.marginTop,
					overTop = collisionPosTop - offsetTop,
					overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
					top = data.my[ 1 ] === "top",
					myOffset = top ?
						-data.elemHeight :
						data.my[ 1 ] === "bottom" ?
							data.elemHeight :
							0,
					atOffset = data.at[ 1 ] === "top" ?
						data.targetHeight :
						data.at[ 1 ] === "bottom" ?
							-data.targetHeight :
							0,
					offset = -2 * data.offset[ 1 ],
					newOverTop,
					newOverBottom;
				if ( overTop < 0 ) {
					newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
						outerHeight - withinOffset;
					if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
						position.top += myOffset + atOffset + offset;
					}
				} else if ( overBottom > 0 ) {
					newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
						offset - offsetTop;
					if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
						position.top += myOffset + atOffset + offset;
					}
				}
			}
		},
		flipfit: {
			left: function() {
				$.ui.position.flip.left.apply( this, arguments );
				$.ui.position.fit.left.apply( this, arguments );
			},
			top: function() {
				$.ui.position.flip.top.apply( this, arguments );
				$.ui.position.fit.top.apply( this, arguments );
			}
		}
	};
	
	} )();
	
	return $.ui.position;
	
	} ) );
	
})
/** END DEFINE BLOCK for jquery-ui@1.12.1/ui/position.js **/


/** START DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/package.json **/
jupyter.define('nglview-js-widgets@0.5.4-dev.2/package.json', function (module, exports, __jupyter_require__) {
	module.exports = {
		"name": "nglview-js-widgets",
		"version": "0.5.4-dev.2",
		"description": "nglview-js-widgets",
		"author": "Hai Nguyen <hainm.comp@gmail.com>, Alexander Rose <alexander.rose@weirdbyte.de>",
		"license": "MIT",
		"main": "src/index.js",
		"repository": {
			"type": "git",
			"url": "https://github.com/arose/nglview.git"
		},
		"bugs": {
			"url": "https://github.com/arose/nglview/issues"
		},
		"files": [
			"dist"
		],
		"keywords": [
			"molecular graphics",
			"molecular structure",
			"jupyter",
			"widgets",
			"ipython",
			"ipywidgets",
			"science"
		],
		"scripts": {
			"lint": "eslint src test",
			"prepublish": "webpack",
			"test": "mocha"
		},
		"devDependencies": {
			"@jupyterlab/extension-builder": "^0.10.0",
			"babel-eslint": "^7.0.0",
			"babel-register": "^6.11.6",
			"eslint": "^3.2.2",
			"eslint-config-google": "^0.7.1",
			"json-loader": "^0.5.4",
			"ngl": "0.10.3",
			"webpack": "^1.12.14"
		},
		"dependencies": {
			"jquery": "^2.1.4",
			"jquery-ui": "^1.12.1",
			"underscore": "^1.8.3",
			"jupyter-js-widgets": "3.0.0-alpha.6",
			"@jupyterlab/nbwidgets": "^0.6.15"
		}
	};
})
/** END DEFINE BLOCK for nglview-js-widgets@0.5.4-dev.2/package.json **/


/** START DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/index.js **/
jupyter.define('@jupyterlab/nbwidgets@0.6.17/lib/index.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var jupyter_js_widgets_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.1.0/lib/index.js');
	var semvercache_1 = __jupyter_require__('@jupyterlab/nbwidgets@0.6.17/lib/semvercache.js');
	var plugin_1 = __jupyter_require__('@jupyterlab/nbwidgets@0.6.17/lib/plugin.js');
	exports.default = plugin_1.default;
	/**
	 * The token identifying the JupyterLab plugin.
	 */
	exports.INBWidgetExtension = new coreutils_1.Token('jupyter.extensions.nbWidgetManager');
	/**
	 * The class name added to an BackboneViewWrapper widget.
	 */
	var BACKBONEVIEWWRAPPER_CLASS = 'jp-BackboneViewWrapper';
	var BackboneViewWrapper = (function (_super) {
	    __extends(BackboneViewWrapper, _super);
	    /**
	     * Construct a new `Backbone` wrapper widget.
	     *
	     * @param view - The `Backbone.View` instance being wrapped.
	     */
	    function BackboneViewWrapper(view) {
	        var _this = _super.call(this) || this;
	        _this._view = null;
	        _this._view = view;
	        view.on('remove', function () {
	            _this.dispose();
	        });
	        _this.addClass(BACKBONEVIEWWRAPPER_CLASS);
	        _this.node.appendChild(view.el);
	        return _this;
	    }
	    BackboneViewWrapper.prototype.onAfterAttach = function (msg) {
	        this._view.trigger('displayed');
	    };
	    BackboneViewWrapper.prototype.dispose = function () {
	        this._view = null;
	        _super.prototype.dispose.call(this);
	    };
	    return BackboneViewWrapper;
	}(widgets_1.Widget));
	exports.BackboneViewWrapper = BackboneViewWrapper;
	/**
	 * A widget manager that returns phosphor widgets.
	 */
	var WidgetManager = (function (_super) {
	    __extends(WidgetManager, _super);
	    function WidgetManager(context, rendermime) {
	        var _this = _super.call(this) || this;
	        _this._registry = new semvercache_1.SemVerCache();
	        _this._context = context;
	        _this._rendermime = rendermime;
	        context.session.kernelChanged.connect(function (sender, kernel) {
	            _this.newKernel(kernel);
	        });
	        if (context.session.kernel) {
	            _this.newKernel(context.session.kernel);
	        }
	        return _this;
	    }
	    WidgetManager.prototype.newKernel = function (kernel) {
	        var _this = this;
	        if (this._commRegistration) {
	            this._commRegistration.dispose();
	        }
	        if (!kernel) {
	            return;
	        }
	        this._commRegistration = kernel.registerCommTarget(this.comm_target_name, function (comm, msg) {
	            var oldComm = new jupyter_js_widgets_1.shims.services.Comm(comm);
	            _this.handle_comm_open(oldComm, msg);
	        });
	    };
	    ;
	    /**
	     * Return a phosphor widget representing the view
	     */
	    WidgetManager.prototype.display_view = function (msg, view, options) {
	        var widget = view.pWidget ? view.pWidget : new BackboneViewWrapper(view);
	        return Promise.resolve(widget);
	    };
	    /**
	     * Create a comm.
	     */
	    WidgetManager.prototype._create_comm = function (target_name, model_id, data) {
	        var comm = this._context.session.kernel.connectToComm(target_name, model_id);
	        comm.open(data);
	        return Promise.resolve(new jupyter_js_widgets_1.shims.services.Comm(comm));
	    };
	    /**
	     * Get the currently-registered comms.
	     */
	    WidgetManager.prototype._get_comm_info = function () {
	        return this._context.session.kernel.requestCommInfo({ target: 'jupyter.widget' }).then(function (reply) {
	            return reply.content.comms;
	        });
	    };
	    Object.defineProperty(WidgetManager.prototype, "isDisposed", {
	        /**
	         * Get whether the manager is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._context === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose the resources held by the manager.
	     */
	    WidgetManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        if (this._commRegistration) {
	            this._commRegistration.dispose();
	        }
	        this._context = null;
	    };
	    /**
	     * Load a class and return a promise to the loaded object.
	     */
	    WidgetManager.prototype.loadClass = function (className, moduleName, moduleVersion) {
	        var mod = this._registry.get(moduleName, moduleVersion);
	        if (!mod) {
	            return Promise.reject("Module " + moduleName + ", semver range " + moduleVersion + " is not registered as a widget module");
	        }
	        var cls = mod[className];
	        if (!cls) {
	            return Promise.reject("Class " + className + " not found in module " + moduleName);
	        }
	        return Promise.resolve(cls);
	    };
	    Object.defineProperty(WidgetManager.prototype, "context", {
	        get: function () {
	            return this._context;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(WidgetManager.prototype, "rendermime", {
	        get: function () {
	            return this._rendermime;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(WidgetManager.prototype, "displayWithOutput", {
	        get: function () {
	            return true;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    WidgetManager.prototype.register = function (data) {
	        this._registry.set(data.name, data.version, data.exports);
	    };
	    return WidgetManager;
	}(jupyter_js_widgets_1.ManagerBase));
	exports.WidgetManager = WidgetManager;
	/**
	 * A renderer for widgets.
	 */
	var WidgetRenderer = (function () {
	    function WidgetRenderer(widgetManager) {
	        this.mimeTypes = ['application/vnd.jupyter.widget-view+json'];
	        this._manager = widgetManager;
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     *
	     * @param options - The options that would be used to render the data.
	     */
	    WidgetRenderer.prototype.canRender = function (options) {
	        var source = options.model.data.get(options.mimeType);
	        var model = this._manager.get_model(source.model_id);
	        return model !== void 0;
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    WidgetRenderer.prototype.wouldSanitize = function (options) {
	        return false;
	    };
	    /**
	     * Render the transformed mime data.
	     *
	     * @param options - The options used to render the data.
	     */
	    WidgetRenderer.prototype.render = function (options) {
	        var _this = this;
	        // data is a model id
	        var w = new widgets_1.Panel();
	        var source = options.model.data.get(options.mimeType);
	        var model = this._manager.get_model(source.model_id);
	        if (model) {
	            model.then(function (model) {
	                return _this._manager.display_model(void 0, model, void 0);
	            }).then(function (view) {
	                w.addWidget(view);
	            });
	        }
	        else {
	            // Model doesn't exist
	            var error = document.createElement('p');
	            error.textContent = 'Widget not found.';
	            w.addWidget(new widgets_1.Widget({ node: error }));
	        }
	        return w;
	    };
	    Object.defineProperty(WidgetRenderer.prototype, "isDisposed", {
	        /**
	         * Get whether the manager is disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._manager === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose the resources held by the manager.
	     */
	    WidgetRenderer.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._manager = null;
	    };
	    return WidgetRenderer;
	}());
	exports.WidgetRenderer = WidgetRenderer;
	
})
/** END DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/index.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/index.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/index.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/manager-base.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_layout.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_style.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_link.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_bool.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_button.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_box.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_image.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_color.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_date.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/services-shim.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_int.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_float.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_controller.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selection.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selectioncontainer.js'));
	__export(__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_string.js'));
	exports.version = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/package.json').version;
	exports.PROTOCOL_VERSION = '2.0';
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/index.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/manager-base.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/manager-base.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js');
	var widget_string_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_string.js');
	/**
	 * Manager abstract base class
	 */
	var ManagerBase = (function () {
	    function ManagerBase() {
	        /**
	         * Dictionary of model ids and model instance promises
	         */
	        this._models = Object.create(null);
	    }
	    Object.defineProperty(ManagerBase.prototype, "comm_target_name", {
	        /**
	         * The comm target name to register.
	         */
	        get: function () {
	            return 'jupyter.widget';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Display a view for a particular model.
	     */
	    ManagerBase.prototype.display_model = function (msg, model, options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        return this.create_view(model, options).then(function (view) { return _this.display_view(msg, view, options); }).catch(utils.reject('Could not create view', true));
	    };
	    ;
	    /**
	     * Modifies view options. Generally overloaded in custom widget manager
	     * implementations.
	     */
	    ManagerBase.prototype.setViewOptions = function (options) {
	        return options || {};
	    };
	    ;
	    /**
	     * Takes a requirejs success handler and returns a requirejs error handler.
	     * The default implementation just throws the original error.
	     */
	    ManagerBase.prototype.require_error = function (success_callback, failure_callback, version) {
	        return failure_callback;
	    };
	    ;
	    /**
	     * Creates a promise for a view of a given model
	     *
	     * Make sure the view creation is not out of order with
	     * any state updates.
	     */
	    ManagerBase.prototype.create_view = function (model, options) {
	        var _this = this;
	        model.state_change = model.state_change.then(function () {
	            return _this.loadClass(model.get('_view_name'), model.get('_view_module'), model.get('_view_module_version')).then(function (ViewType) {
	                var view = new ViewType({
	                    model: model,
	                    options: _this.setViewOptions(options)
	                });
	                view.listenTo(model, 'destroy', view.remove);
	                return Promise.resolve(view.render()).then(function () { return view; });
	            }).catch(utils.reject('Could not create a view for model id ' + model.id, true));
	        });
	        var id = utils.uuid();
	        model.views[id] = model.state_change;
	        model.state_change.then(function (view) {
	            view.once('remove', function () { delete view.model.views[id]; }, _this);
	        });
	        return model.state_change;
	    };
	    ;
	    /**
	     * callback handlers specific to a view
	     */
	    ManagerBase.prototype.callbacks = function (view) {
	        return {};
	    };
	    ;
	    /**
	     * Get a promise for a model by model id.
	     */
	    ManagerBase.prototype.get_model = function (model_id) {
	        // Perhaps we should return a Promise.reject if the model is not found.
	        return this._models[model_id];
	    };
	    ;
	    /**
	     * Handle when a comm is opened.
	     */
	    ManagerBase.prototype.handle_comm_open = function (comm, msg) {
	        var data = msg.content.data;
	        var buffer_paths = data.buffer_paths || [];
	        // Make sure the buffers are DataViews
	        var buffers = (msg.buffers || []).map(function (b) {
	            if (b instanceof DataView) {
	                return b;
	            }
	            else {
	                return new DataView(b instanceof ArrayBuffer ? b : b.buffer);
	            }
	        });
	        utils.put_buffers(data.state, buffer_paths, buffers);
	        return this.new_model({
	            model_name: data.state['_model_name'],
	            model_module: data.state['_model_module'],
	            model_module_version: data.state['_model_module_version'],
	            comm: comm
	        }, data.state).catch(utils.reject('Could not create a model.', true));
	    };
	    ;
	    /**
	     * Create a comm and new widget model.
	     * @param  options - same options as new_model but comm is not
	     *                          required and additional options are available.
	     * @param  serialized_state - serialized model attributes.
	     */
	    ManagerBase.prototype.new_widget = function (options, serialized_state) {
	        var _this = this;
	        var commPromise;
	        // If no comm is provided, a new comm is opened for the jupyter.widget
	        // target.
	        if (options.comm) {
	            commPromise = Promise.resolve(options.comm);
	        }
	        else {
	            commPromise = this._create_comm(this.comm_target_name, options.model_id, {
	                state: {
	                    _model_module: options.model_module,
	                    _model_module_version: options.model_module_version,
	                    _model_name: options.model_name,
	                    _view_module: options.view_module,
	                    _view_module_version: options.view_module_version,
	                    _view_name: options.view_name
	                },
	            });
	        }
	        // The options dictionary is copied since data will be added to it.
	        var options_clone = _.clone(options);
	        // Create the model. In the case where the comm promise is rejected a
	        // comm-less model is still created with the required model id.
	        return commPromise.then(function (comm) {
	            // Comm Promise Resolved.
	            options_clone.comm = comm;
	            var widget_model = _this.new_model(options_clone, serialized_state);
	            return widget_model.then(function (model) {
	                model.sync('create', model);
	                return model;
	            });
	        }, function () {
	            // Comm Promise Rejected.
	            if (!options_clone.model_id) {
	                options_clone.model_id = utils.uuid();
	            }
	            return _this.new_model(options_clone, serialized_state);
	        });
	    };
	    ;
	    /**
	     * Create and return a promise for a new widget model
	     *
	     * Minimally, one must provide the model_name and widget_class
	     * parameters to create a model from Javascript.
	     *
	     * @param options - the options for creating the model.
	     * @param serialized_state - attribute values for the model.
	     *
	     * @example
	     * widget_manager.new_model({
	     *      model_name: 'WidgetModel',
	     *      widget_class: 'Jupyter.IntSlider'
	     *  })
	     *  .then((model) => { console.log('Create success!', model); },
	     *  (err) => {console.error(err)});
	     *
	     */
	    ManagerBase.prototype.new_model = function (options, serialized_state) {
	        if (serialized_state === void 0) { serialized_state = {}; }
	        var that = this;
	        var model_id;
	        if (options.model_id) {
	            model_id = options.model_id;
	        }
	        else if (options.comm) {
	            model_id = options.comm.comm_id;
	        }
	        else {
	            throw new Error('Neither comm nor model_id provided in options object. At least one must exist.');
	        }
	        var error_handler = function (error) {
	            var modelOptions = {
	                widget_manager: that,
	                model_id: model_id,
	                comm: options.comm,
	            };
	            var widget_model = new widget_string_1.HTMLModel({}, modelOptions);
	            widget_model.once('comm:close', function () {
	                delete that._models[model_id];
	            });
	            var placeholder = "<table style=\"width:100%\">\n                <thead>\n                    <tr>\n                        <th colspan=\"2\">\n                        Could not create model:\n                        </th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td>Model name</td>\n                        <td> " + options.model_name + " </td>\n                    </tr>\n                    <tr>\n                        <td>Model module</td>\n                        <td> " + options.model_module + " </td>\n                    </tr>\n                    <tr>\n                        <td>Model module version</td>\n                        <td> " + options.model_module_version + " </td>\n                    </tr>\n                <tbody>\n                <tfoot>\n                    <tr>\n                        <th colspan=\"2\">\n                        " + error.message + "\n                        </th>\n                    </tr>\n                </tfoot>\n                </table>";
	            widget_model.set('value', placeholder);
	            return widget_model;
	        };
	        var model_promise = this.loadClass(options.model_name, options.model_module, options.model_module_version).then(function (ModelType) {
	            try {
	                return ModelType._deserialize_state(serialized_state || {}, that)
	                    .then(function (attributes) {
	                    var modelOptions = {
	                        widget_manager: that,
	                        model_id: model_id,
	                        comm: options.comm,
	                    };
	                    var widget_model = new ModelType(attributes, modelOptions);
	                    widget_model.once('comm:close', function () {
	                        delete that._models[model_id];
	                    });
	                    widget_model.name = options.model_name;
	                    widget_model.module = options.model_module;
	                    return widget_model;
	                });
	            }
	            catch (error) {
	                error_handler(error); // error handler call if ModelType is undefined.
	            }
	        }, error_handler); // error handler call if module cannot be loaded.
	        this._models[model_id] = model_promise;
	        return model_promise;
	    };
	    ;
	    /**
	     * Close all widgets and empty the widget state.
	     * @param commlessOnly should only commless widgets be removed
	     * @return promise that resolves when the widget state is cleared.
	     */
	    ManagerBase.prototype.clear_state = function (commlessOnly) {
	        var _this = this;
	        return utils.resolvePromisesDict(this._models).then(function (models) {
	            Object.keys(models).forEach(function (id) {
	                if (!commlessOnly || models[id].comm) {
	                    models[id].close();
	                }
	            });
	            _this._models = {};
	        });
	    };
	    ;
	    /**
	     * Asynchronously get the state of the widget manager.
	     *
	     * This includes all of the widget models, and follows the format given in
	     * the jupyter-widgets-schema package.
	     *
	     * @param options - The options for what state to return.
	     * @returns Promise for a state dictionary
	     */
	    ManagerBase.prototype.get_state = function (options) {
	        return utils.resolvePromisesDict(this._models).then(function (models) {
	            var state = {};
	            Object.keys(models).forEach(function (model_id) {
	                var model = models[model_id];
	                var split = utils.remove_buffers(model.serialize(model.get_state(options.drop_defaults)));
	                var buffers = split.buffers.map(function (buffer, index) {
	                    return { data: utils.bufferToBase64(buffer), path: split.buffer_paths[index], encoding: 'base64' };
	                });
	                state[model_id] = {
	                    model_name: model.name,
	                    model_module: model.module,
	                    model_module_version: model.get('_model_module_version'),
	                    state: split.state
	                };
	                // To save space, only include the buffer key if we have buffers
	                if (buffers.length > 0) {
	                    state[model_id].buffers = buffers;
	                }
	            });
	            return { version_major: 2, version_minor: 0, state: state };
	        }).catch(utils.reject('Could not get state of widget manager', true));
	    };
	    ;
	    /**
	     * Set the widget manager state.
	     *
	     * @param state - a Javascript object conforming to the application/vnd.jupyter.widget-state+json spec.
	     *
	     * Reconstructs all of the widget models in the state, merges that with the
	     * current manager state, and then attempts to redisplay the widgets in the
	     * state.
	     */
	    ManagerBase.prototype.set_state = function (state, displayOptions) {
	        var _this = this;
	        // Check to make sure that it's the same version we are parsing.
	        if (!(state.version_major && state.version_major <= 2)) {
	            throw "Unsupported widget state format";
	        }
	        var models = state.state;
	        // Recreate all the widget models for the given widget manager state.
	        var all_models = this._get_comm_info().then(function (live_comms) {
	            return Promise.all(Object.keys(models).map(function (model_id) {
	                // First put back the binary buffers
	                var decode = { 'base64': utils.base64ToBuffer, 'hex': utils.hexToBuffer };
	                var model = models[model_id];
	                var modelState = model.state;
	                if (model.buffers) {
	                    var bufferPaths = model.buffers.map(function (b) { return b.path; });
	                    // put_buffers expects buffers to be DataViews
	                    var buffers = model.buffers.map(function (b) { return new DataView(decode[b.encoding](b.data)); });
	                    utils.put_buffers(model.state, bufferPaths, buffers);
	                }
	                // If the model has already been created, set its state and then
	                // return it.
	                if (_this._models[model_id]) {
	                    return _this._models[model_id].then(function (model) {
	                        // deserialize state
	                        return model.constructor._deserialize_state(modelState || {}, _this).then(function (attributes) {
	                            model.set_state(attributes);
	                            return model;
	                        });
	                    });
	                }
	                var modelCreate = {
	                    model_id: model_id,
	                    model_name: model.model_name,
	                    model_module: model.model_module,
	                    model_module_version: model.model_module_version
	                };
	                if (live_comms.hasOwnProperty(model_id)) {
	                    return _this._create_comm(_this.comm_target_name, model_id).then(function (comm) {
	                        modelCreate.comm = comm;
	                        return _this.new_model(modelCreate);
	                    });
	                }
	                else {
	                    return _this.new_model(modelCreate, modelState);
	                }
	            }));
	        });
	        return all_models;
	    };
	    ;
	    return ManagerBase;
	}());
	exports.ManagerBase = ManagerBase;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/manager-base.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var base64_js_1 = __jupyter_require__('base64-js@1.2.0/index.js');
	/**
	 * http://www.ietf.org/rfc/rfc4122.txt
	 */
	function uuid() {
	    var s = [];
	    var hexDigits = '0123456789ABCDEF';
	    for (var i = 0; i < 32; i++) {
	        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
	    }
	    s[12] = '4'; // bits 12-15 of the time_hi_and_version field to 0010
	    s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
	    return s.join('');
	}
	exports.uuid = uuid;
	/**
	 * Wrappable Error class
	 *
	 * The Error class doesn't actually act on `this`.  Instead it always
	 * returns a new instance of Error.  Here we capture that instance so we
	 * can apply it's properties to `this`.
	 */
	var WrappedError = (function (_super) {
	    __extends(WrappedError, _super);
	    function WrappedError(message, error) {
	        var _this = _super.call(this, message) || this;
	        // Keep a stack of the original error messages.
	        if (error instanceof WrappedError) {
	            _this.error_stack = error.error_stack;
	        }
	        else {
	            _this.error_stack = [error];
	        }
	        _this.error_stack.push(_this);
	        return _this;
	    }
	    return WrappedError;
	}(Error));
	exports.WrappedError = WrappedError;
	/**
	 * Resolve a promiseful dictionary.
	 * Returns a single Promise.
	 */
	function resolvePromisesDict(d) {
	    var keys = Object.keys(d);
	    var values = [];
	    keys.forEach(function (key) {
	        values.push(d[key]);
	    });
	    return Promise.all(values).then(function (v) {
	        d = {};
	        for (var i = 0; i < keys.length; i++) {
	            d[keys[i]] = v[i];
	        }
	        return d;
	    });
	}
	exports.resolvePromisesDict = resolvePromisesDict;
	/**
	 * Creates a wrappable Promise rejection function.
	 *
	 * Creates a function that returns a Promise.reject with a new WrappedError
	 * that has the provided message and wraps the original error that
	 * caused the promise to reject.
	 */
	function reject(message, log) {
	    return function promiseRejection(error) {
	        var wrapped_error = new WrappedError(message, error);
	        if (log)
	            console.error(wrapped_error);
	        return Promise.reject(wrapped_error);
	    };
	}
	exports.reject = reject;
	/**
	 * Apply MathJax rendering to an element, and optionally set its text.
	 *
	 * If MathJax is not available, make no changes.
	 *
	 * Parameters
	 * ----------
	 * element: Node
	 * text: optional string
	 */
	function typeset(element, text) {
	    if (text !== void 0) {
	        element.textContent = text;
	    }
	    if (window.MathJax !== void 0) {
	        MathJax.Hub.Queue(['Typeset', MathJax.Hub, element]);
	    }
	}
	exports.typeset = typeset;
	/**
	 * escape text to HTML
	 */
	function escape_html(text) {
	    var esc = document.createElement('div');
	    esc.textContent = text;
	    return esc.innerHTML;
	}
	exports.escape_html = escape_html;
	;
	/**
	 * Takes an object 'state' and fills in buffer[i] at 'path' buffer_paths[i]
	 * where buffer_paths[i] is a list indicating where in the object buffer[i] should
	 * be placed
	 * Example: state = {a: 1, b: {}, c: [0, null]}
	 * buffers = [array1, array2]
	 * buffer_paths = [['b', 'data'], ['c', 1]]
	 * Will lead to {a: 1, b: {data: array1}, c: [0, array2]}
	 */
	function put_buffers(state, buffer_paths, buffers) {
	    for (var i = 0; i < buffer_paths.length; i++) {
	        var buffer_path = buffer_paths[i];
	        // say we want to set state[x][y][z] = buffers[i]
	        var obj = state;
	        // we first get obj = state[x][y]
	        for (var j = 0; j < buffer_path.length - 1; j++)
	            obj = obj[buffer_path[j]];
	        // and then set: obj[z] = buffers[i]
	        obj[buffer_path[buffer_path.length - 1]] = buffers[i];
	    }
	}
	exports.put_buffers = put_buffers;
	/**
	 * The inverse of put_buffers, return an objects with the new state where all buffers(ArrayBuffer)
	 * are removed. If a buffer is a member of an object, that object is cloned, and the key removed. If a buffer
	 * is an element of an array, that array is cloned, and the element is set to null.
	 * See put_buffers for the meaning of buffer_paths
	 * Returns an object with the new state (.state) an array with paths to the buffers (.buffer_paths),
	 * and the buffers associated to those paths (.buffers).
	 */
	function remove_buffers(state) {
	    var buffers = [];
	    var buffer_paths = [];
	    // if we need to remove an object from a list, we need to clone that list, otherwise we may modify
	    // the internal state of the widget model
	    // however, we do not want to clone everything, for performance
	    function remove(obj, path) {
	        if (obj.toJSON) {
	            // We need to get the JSON form of the object before recursing.
	            // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior
	            obj = obj.toJSON();
	        }
	        if (Array.isArray(obj)) {
	            var is_cloned = false;
	            for (var i = 0; i < obj.length; i++) {
	                var value = obj[i];
	                if (value) {
	                    if (value.buffer instanceof ArrayBuffer || value instanceof ArrayBuffer) {
	                        if (!is_cloned) {
	                            obj = _.clone(obj);
	                            is_cloned = true;
	                        }
	                        buffers.push(value instanceof ArrayBuffer ? value : value.buffer);
	                        buffer_paths.push(path.concat([i]));
	                        // easier to just keep the array, but clear the entry, otherwise we have to think
	                        // about array length, much easier this way
	                        obj[i] = null;
	                    }
	                    else {
	                        var new_value = remove(value, path.concat([i]));
	                        // only assigned when the value changes, we may serialize objects that don't support assignment
	                        if (new_value !== value) {
	                            if (!is_cloned) {
	                                obj = _.clone(obj);
	                                is_cloned = true;
	                            }
	                            obj[i] = new_value;
	                        }
	                    }
	                }
	            }
	        }
	        else if (_.isObject(obj)) {
	            for (var key in obj) {
	                var is_cloned = false;
	                if (obj.hasOwnProperty(key)) {
	                    var value = obj[key];
	                    if (value) {
	                        if (value.buffer instanceof ArrayBuffer || value instanceof ArrayBuffer) {
	                            if (!is_cloned) {
	                                obj = _.clone(obj);
	                                is_cloned = true;
	                            }
	                            buffers.push(value instanceof ArrayBuffer ? value : value.buffer);
	                            buffer_paths.push(path.concat([key]));
	                            delete obj[key]; // for objects/dicts we just delete them
	                        }
	                        else {
	                            var new_value = remove(value, path.concat([key]));
	                            // only assigned when the value changes, we may serialize objects that don't support assignment
	                            if (new_value !== value) {
	                                if (!is_cloned) {
	                                    obj = _.clone(obj);
	                                    is_cloned = true;
	                                }
	                                obj[key] = new_value;
	                            }
	                        }
	                    }
	                }
	            }
	        }
	        return obj;
	    }
	    var new_state = remove(state, []);
	    return { state: new_state, buffers: buffers, buffer_paths: buffer_paths };
	}
	exports.remove_buffers = remove_buffers;
	var hexTable = [
	    '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0A', '0B', '0C', '0D', '0E', '0F',
	    '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1A', '1B', '1C', '1D', '1E', '1F',
	    '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2A', '2B', '2C', '2D', '2E', '2F',
	    '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3A', '3B', '3C', '3D', '3E', '3F',
	    '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4A', '4B', '4C', '4D', '4E', '4F',
	    '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5A', '5B', '5C', '5D', '5E', '5F',
	    '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6A', '6B', '6C', '6D', '6E', '6F',
	    '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7A', '7B', '7C', '7D', '7E', '7F',
	    '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8A', '8B', '8C', '8D', '8E', '8F',
	    '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9A', '9B', '9C', '9D', '9E', '9F',
	    'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF',
	    'B0', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'BA', 'BB', 'BC', 'BD', 'BE', 'BF',
	    'C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'CA', 'CB', 'CC', 'CD', 'CE', 'CF',
	    'D0', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'DA', 'DB', 'DC', 'DD', 'DE', 'DF',
	    'E0', 'E1', 'E2', 'E3', 'E4', 'E5', 'E6', 'E7', 'E8', 'E9', 'EA', 'EB', 'EC', 'ED', 'EE', 'EF',
	    'F0', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'FA', 'FB', 'FC', 'FD', 'FE', 'FF'
	];
	/**
	 * Convert an ArrayBuffer to a hex string.
	 */
	function bufferToHex(buffer) {
	    var x = new Uint8Array(buffer);
	    var s = [];
	    for (var i = 0; i < x.length; i++) {
	        s.push(hexTable[x[i]]);
	    }
	    return s.join('');
	}
	exports.bufferToHex = bufferToHex;
	/**
	 * Convert a hex string to an ArrayBuffer.
	 */
	function hexToBuffer(hex) {
	    var x = new Uint8Array(hex.length / 2);
	    for (var i = 0; i < hex.length; i += 2) {
	        x[i / 2] = parseInt(hex.slice(i, i + 2), 16);
	    }
	    return x.buffer;
	}
	exports.hexToBuffer = hexToBuffer;
	/**
	 * Convert an ArrayBuffer to a base64 string.
	 */
	function bufferToBase64(buffer) {
	    return base64_js_1.fromByteArray(new Uint8Array(buffer));
	}
	exports.bufferToBase64 = bufferToBase64;
	/**
	 * Convert a base64 string to an ArrayBuffer.
	 */
	function base64ToBuffer(base64) {
	    return base64_js_1.toByteArray(base64).buffer;
	}
	exports.base64ToBuffer = base64ToBuffer;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_string.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_string.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var StringModel = (function (_super) {
	    __extends(StringModel, _super);
	    function StringModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    StringModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: '',
	            disabled: false,
	            placeholder: '\u200b',
	            _model_name: 'StringModel'
	        });
	    };
	    return StringModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.StringModel = StringModel;
	var HTMLModel = (function (_super) {
	    __extends(HTMLModel, _super);
	    function HTMLModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    HTMLModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'HTMLView',
	            _model_name: 'HTMLModel'
	        });
	    };
	    return HTMLModel;
	}(StringModel));
	exports.HTMLModel = HTMLModel;
	var HTMLView = (function (_super) {
	    __extends(HTMLView, _super);
	    function HTMLView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    HTMLView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-html');
	        this.content = document.createElement('div');
	        this.content.classList.add('widget-html-content');
	        this.el.appendChild(this.content);
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    HTMLView.prototype.update = function () {
	        this.content.innerHTML = this.model.get('value');
	        return _super.prototype.update.call(this);
	    };
	    return HTMLView;
	}(widget_1.LabeledDOMWidgetView));
	exports.HTMLView = HTMLView;
	var HTMLMathModel = (function (_super) {
	    __extends(HTMLMathModel, _super);
	    function HTMLMathModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    HTMLMathModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'HTMLMathView',
	            _model_name: 'HTMLMathModel'
	        });
	    };
	    return HTMLMathModel;
	}(StringModel));
	exports.HTMLMathModel = HTMLMathModel;
	var HTMLMathView = (function (_super) {
	    __extends(HTMLMathView, _super);
	    function HTMLMathView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    HTMLMathView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-htmlmath');
	        this.content = document.createElement('div');
	        this.content.classList.add('widget-htmlmath-content');
	        this.el.appendChild(this.content);
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     */
	    HTMLMathView.prototype.update = function () {
	        this.content.innerHTML = this.model.get('value');
	        this.typeset(this.content);
	        return _super.prototype.update.call(this);
	    };
	    return HTMLMathView;
	}(widget_1.LabeledDOMWidgetView));
	exports.HTMLMathView = HTMLMathView;
	var LabelModel = (function (_super) {
	    __extends(LabelModel, _super);
	    function LabelModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LabelModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'LabelView',
	            _model_name: 'LabelModel'
	        });
	    };
	    return LabelModel;
	}(StringModel));
	exports.LabelModel = LabelModel;
	var LabelView = (function (_super) {
	    __extends(LabelView, _super);
	    function LabelView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    LabelView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-label');
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    LabelView.prototype.update = function () {
	        this.typeset(this.el, this.model.get('value'));
	        return _super.prototype.update.call(this);
	    };
	    return LabelView;
	}(widget_1.LabeledDOMWidgetView));
	exports.LabelView = LabelView;
	var TextareaModel = (function (_super) {
	    __extends(TextareaModel, _super);
	    function TextareaModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    TextareaModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'TextareaView',
	            _model_name: 'TextareaModel',
	            rows: null
	        });
	    };
	    return TextareaModel;
	}(StringModel));
	exports.TextareaModel = TextareaModel;
	var TextareaView = (function (_super) {
	    __extends(TextareaView, _super);
	    function TextareaView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    TextareaView.prototype.render = function () {
	        var _this = this;
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-textarea');
	        this.textbox = document.createElement('textarea');
	        this.textbox.setAttribute('rows', '5');
	        this.el.appendChild(this.textbox);
	        this.update(); // Set defaults.
	        this.listenTo(this.model, 'msg:custom', function (content) {
	            _this._handle_textarea_msg(content);
	        });
	        this.listenTo(this.model, 'change:placeholder', function (model, value, options) {
	            this.update_placeholder(value);
	        });
	        this.update_placeholder();
	    };
	    /**
	     * Handle when a custom msg is recieved from the back-end.
	     */
	    TextareaView.prototype._handle_textarea_msg = function (content) {
	        if (content.method == 'scroll_to_bottom') {
	            this.scroll_to_bottom();
	        }
	    };
	    TextareaView.prototype.update_placeholder = function (value) {
	        value = value || this.model.get('placeholder');
	        this.textbox.setAttribute('placeholder', value.toString());
	    };
	    /**
	     * Scroll the text-area view to the bottom.
	     */
	    TextareaView.prototype.scroll_to_bottom = function () {
	        //this.$textbox.scrollTop(this.$textbox[0].scrollHeight); // DW TODO
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    TextareaView.prototype.update = function (options) {
	        if (options === undefined || options.updated_view != this) {
	            this.textbox.value = this.model.get('value');
	            this.textbox.rows = this.model.get('rows');
	            var disabled = this.model.get('disabled');
	            this.textbox.disabled = disabled;
	        }
	        return _super.prototype.update.call(this);
	    };
	    TextareaView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'keydown textarea': 'handleKeyDown',
	            'keypress textarea': 'handleKeypress',
	            'keyup textarea': 'handleChanging',
	            'paste textarea': 'handleChanging',
	            'cut textarea': 'handleChanging'
	        };
	    };
	    /**
	     * Handle key down
	     *
	     * Stop propagation so the event isn't sent to the application.
	     */
	    TextareaView.prototype.handleKeyDown = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles key press
	     *
	     * Stop propagation so the keypress isn't sent to the application.
	     */
	    TextareaView.prototype.handleKeypress = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles and validates user input.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    TextareaView.prototype.handleChanging = function (e) {
	        this.model.set('value', e.target.value, { updated_view: this });
	        this.touch();
	    };
	    return TextareaView;
	}(widget_1.LabeledDOMWidgetView));
	exports.TextareaView = TextareaView;
	var TextModel = (function (_super) {
	    __extends(TextModel, _super);
	    function TextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    TextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'TextView',
	            _model_name: 'TextModel'
	        });
	    };
	    return TextModel;
	}(StringModel));
	exports.TextModel = TextModel;
	var TextView = (function (_super) {
	    __extends(TextView, _super);
	    function TextView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this.inputType = 'text';
	        return _this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    TextView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-text');
	        this.textbox = document.createElement('input');
	        this.textbox.setAttribute('type', this.inputType);
	        this.el.appendChild(this.textbox);
	        this.update(); // Set defaults.
	        this.listenTo(this.model, 'change:placeholder', function (model, value, options) {
	            this.update_placeholder(value);
	        });
	        this.update_placeholder();
	    };
	    TextView.prototype.update_placeholder = function (value) {
	        if (!value) {
	            value = this.model.get('placeholder');
	        }
	        this.textbox.setAttribute('placeholder', value);
	    };
	    TextView.prototype.update = function (options) {
	        /**
	         * Update the contents of this view
	         *
	         * Called when the model is changed.  The model may have been
	         * changed by another view or by a state update from the back-end.
	         */
	        if (options === undefined || options.updated_view != this) {
	            if (this.textbox.value != this.model.get('value')) {
	                this.textbox.value = this.model.get('value');
	            }
	            var disabled = this.model.get('disabled');
	            this.textbox.disabled = disabled;
	        }
	        return _super.prototype.update.call(this);
	    };
	    TextView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'keydown input': 'handleKeyDown',
	            'keypress input': 'handleKeypress',
	            'keyup input': 'handleChanging',
	            'paste input': 'handleChanging',
	            'cut input': 'handleChanging',
	            'blur input': 'handleBlur',
	            'focusout input': 'handleFocusOut'
	        };
	    };
	    /**
	     * Handle key down
	     *
	     * Stop propagation so the keypress isn't sent to the application.
	     */
	    TextView.prototype.handleKeyDown = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles text submission
	     */
	    TextView.prototype.handleKeypress = function (e) {
	        e.stopPropagation();
	        if (e.keyCode == 13) {
	            this.send({ event: 'submit' });
	            e.preventDefault();
	        }
	    };
	    /**
	     * Handles user input.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    TextView.prototype.handleChanging = function (e) {
	        e.stopPropagation();
	        this.model.set('value', e.target.value, { updated_view: this });
	        this.touch();
	    };
	    /**
	     * Prevent a blur from firing if the blur was not user intended.
	     * This is a workaround for the return-key focus loss bug.
	     * TODO: Is the original bug actually a fault of the keyboard
	     * manager?
	     */
	    TextView.prototype.handleBlur = function (e) {
	        if (e.relatedTarget === null) {
	            e.stopPropagation();
	            e.preventDefault();
	        }
	    };
	    /**
	     * Prevent a blur from firing if the blur was not user intended.
	     * This is a workaround for the return-key focus loss bug.
	     */
	    TextView.prototype.handleFocusOut = function (e) {
	        if (e.relatedTarget === null) {
	            e.stopPropagation();
	            e.preventDefault();
	        }
	    };
	    return TextView;
	}(widget_1.LabeledDOMWidgetView));
	exports.TextView = TextView;
	var PasswordModel = (function (_super) {
	    __extends(PasswordModel, _super);
	    function PasswordModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    PasswordModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'PasswordView',
	            _model_name: 'PasswordModel'
	        });
	    };
	    return PasswordModel;
	}(TextModel));
	exports.PasswordModel = PasswordModel;
	var PasswordView = (function (_super) {
	    __extends(PasswordView, _super);
	    function PasswordView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this.inputType = 'password';
	        return _this;
	    }
	    return PasswordView;
	}(TextView));
	exports.PasswordView = PasswordView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_string.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var Backbone = __jupyter_require__('backbone@1.2.0/backbone.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	var nativeview_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/nativeview.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.1.0/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.1.0/lib/index.js');
	/**
	 * Replace model ids with models recursively.
	 */
	function unpack_models(value, manager) {
	    var unpacked;
	    if (_.isArray(value)) {
	        unpacked = [];
	        _.each(value, function (sub_value, key) {
	            unpacked.push(unpack_models(sub_value, manager));
	        });
	        return Promise.all(unpacked);
	    }
	    else if (value instanceof Object) {
	        unpacked = {};
	        _.each(value, function (sub_value, key) {
	            unpacked[key] = unpack_models(sub_value, manager);
	        });
	        return utils.resolvePromisesDict(unpacked);
	    }
	    else if (typeof value === 'string' && value.slice(0, 10) === 'IPY_MODEL_') {
	        // get_model returns a promise already
	        return manager.get_model(value.slice(10, value.length));
	    }
	    else {
	        return Promise.resolve(value);
	    }
	}
	exports.unpack_models = unpack_models;
	;
	var WidgetModel = (function (_super) {
	    __extends(WidgetModel, _super);
	    function WidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * The default attributes.
	     */
	    WidgetModel.prototype.defaults = function () {
	        return {
	            _model_module: "jupyter-js-widgets",
	            _model_name: "WidgetModel",
	            _model_module_version: "*",
	            _view_module: "jupyter-js-widgets",
	            _view_name: null,
	            _view_module_version: "*",
	            _view_count: 0,
	            msg_throttle: 1,
	        };
	    };
	    /**
	     * Test to see if the model has been synced with the server.
	     *
	     * #### Notes
	     * As of backbone 1.1, backbone ignores `patch` if it thinks the
	     * model has never been pushed.
	     */
	    WidgetModel.prototype.isNew = function () {
	        return false;
	    };
	    /**
	     * Constructor
	     *
	     * Creates a WidgetModel instance.
	     *
	     * Parameters
	     * ----------
	     * widget_manager : WidgetManager instance
	     * model_id : string
	     *      An ID unique to this model.
	     * comm : Comm instance (optional)
	     */
	    WidgetModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.widget_manager = options.widget_manager;
	        this.id = options.model_id;
	        var comm = options.comm;
	        this.state_change = Promise.resolve();
	        this.pending_msgs = 0;
	        this.msg_buffer = null;
	        this.state_lock = null;
	        this._buffered_state_diff = {};
	        this.views = {};
	        if (comm) {
	            // Remember comm associated with the model.
	            this.comm = comm;
	            comm.model = this;
	            // Hook comm messages up to model.
	            comm.on_close(_.bind(this._handle_comm_closed, this));
	            comm.on_msg(_.bind(this._handle_comm_msg, this));
	            this.comm_live = true;
	        }
	        else {
	            this.comm_live = false;
	        }
	    };
	    /**
	     * Send a custom msg over the comm.
	     *
	     * Any custom callbacks must include calls to the model callbacks returned
	     * from model.callbacks()
	     */
	    WidgetModel.prototype.send = function (content, callbacks, buffers) {
	        if (this.comm !== undefined) {
	            var data = { method: 'custom', content: content };
	            this.comm.send(data, callbacks, {}, buffers);
	            this.pending_msgs++;
	        }
	    };
	    /**
	     * Close model
	     */
	    WidgetModel.prototype.close = function (comm_closed) {
	        if (this.comm && !comm_closed) {
	            this.comm.close();
	        }
	        this.stopListening();
	        this.trigger('destroy', this);
	        if (this.comm) {
	            delete this.comm.model; // Delete ref so GC will collect widget model.
	            delete this.comm;
	        }
	        delete this.model_id; // Delete id from model so widget manager cleans up.
	        _.each(this.views, function (v, id, views) {
	            v.then(function (view) {
	                view.remove();
	                delete views[id];
	            });
	        });
	    };
	    /**
	     * Handle when a widget is closed.
	     */
	    WidgetModel.prototype._handle_comm_closed = function (msg) {
	        this.trigger('comm:close');
	        this.close(true);
	    };
	    /**
	     * Handle incoming comm msg.
	     */
	    WidgetModel.prototype._handle_comm_msg = function (msg) {
	        var _this = this;
	        var method = msg.content.data.method;
	        switch (method) {
	            case 'update':
	                this.state_change = this.state_change
	                    .then(function () {
	                    // see Widget.open/_split_state_buffers about why we need state_with_buffers
	                    var state = msg.content.data.state;
	                    var buffer_paths = msg.content.data.buffer_paths || [];
	                    // Make sure the buffers are DataViews
	                    var buffers = (msg.buffers || []).map(function (b) {
	                        if (b instanceof DataView) {
	                            return b;
	                        }
	                        else {
	                            return new DataView(b instanceof ArrayBuffer ? b : b.buffer);
	                        }
	                    });
	                    utils.put_buffers(state, buffer_paths, buffers);
	                    return _this.constructor._deserialize_state(state, _this.widget_manager);
	                }).then(function (state) {
	                    _this.set_state(state);
	                }).catch(utils.reject('Could not process update msg for model id: ' + String(this.id), true));
	                return this.state_change;
	            case 'custom':
	                this.trigger('msg:custom', msg.content.data.content, msg.buffers);
	                return Promise.resolve();
	            case 'display':
	                if (this.widget_manager.displayWithOutput) {
	                    return;
	                }
	                this.state_change = this.state_change.then(function () {
	                    _this.widget_manager.display_model(msg, _this);
	                }).catch(utils.reject('Could not process display view msg', true));
	                return this.state_change;
	        }
	    };
	    /**
	     * Handle when a widget is updated from the backend.
	     */
	    WidgetModel.prototype.set_state = function (state) {
	        this.state_lock = state;
	        try {
	            this.set(state);
	        }
	        catch (e) {
	            console.error('Error setting state:', e.message);
	        }
	        finally {
	            this.state_lock = null;
	        }
	    };
	    /**
	     * Get the serializable state of the model.
	     *
	     * If drop_default is thruthy, attributes that are equal to their default
	     * values are dropped.
	     */
	    WidgetModel.prototype.get_state = function (drop_defaults) {
	        var state = this.attributes;
	        if (drop_defaults) {
	            var defaults = _.result(this, 'defaults');
	            return Object.keys(state).reduce(function (obj, key) {
	                if (!_.isEqual(state[key], defaults[key])) {
	                    obj[key] = state[key];
	                }
	                return obj;
	            }, {});
	        }
	        else {
	            return _.clone(state);
	        }
	    };
	    /**
	     * Handle status msgs.
	     *
	     * execution_state : ('busy', 'idle', 'starting')
	     */
	    WidgetModel.prototype._handle_status = function (msg, callbacks) {
	        if (this.comm !== undefined) {
	            if (msg.content.execution_state === 'idle') {
	                this.pending_msgs--;
	                // Send buffer if one is waiting and we are below the throttle.
	                if (this.msg_buffer !== null
	                    && this.pending_msgs < (this.get('msg_throttle') || 1)) {
	                    this.send_sync_message(this.msg_buffer, this.msg_buffer_callbacks);
	                    this.msg_buffer = null;
	                    this.msg_buffer_callbacks = null;
	                }
	            }
	        }
	    };
	    /**
	     * Create msg callbacks for a comm msg.
	     */
	    WidgetModel.prototype.callbacks = function (view) {
	        var _this = this;
	        var callbacks = this.widget_manager.callbacks(view);
	        if (callbacks.iopub === undefined) {
	            callbacks.iopub = {};
	        }
	        callbacks.iopub.status = function (msg) {
	            _this._handle_status(msg, callbacks);
	        };
	        return callbacks;
	    };
	    /**
	     * Set a value.
	     *
	     * We just call the super method, in which val and options are optional
	     */
	    WidgetModel.prototype.set = function (key, val, options) {
	        var return_value = _super.prototype.set.call(this, key, val, options);
	        // Backbone only remembers the diff of the most recent set()
	        // operation.  Calling set multiple times in a row results in a
	        // loss of change information.  Here we keep our own running diff.
	        //
	        // We don't buffer the state set in the constructor (including
	        // defaults), so we first check to see if we've initialized _buffered_state_diff.
	        // which happens after the constructor sets attributes at creation.
	        if (this._buffered_state_diff !== void 0) {
	            var attrs = this.changedAttributes() || {};
	            // The state_lock lists attributes that are currently being changed
	            // right now from a kernel message. We don't want to send these
	            // non-changes back to the kernel, so we delete them out of attrs if
	            // they haven't changed from their state_lock value
	            if (this.state_lock !== null) {
	                for (var _i = 0, _a = Object.keys(this.state_lock); _i < _a.length; _i++) {
	                    var key_1 = _a[_i];
	                    if (attrs[key_1] === this.state_lock[key_1]) {
	                        delete attrs[key_1];
	                    }
	                }
	            }
	            this._buffered_state_diff = _.extend(this._buffered_state_diff, attrs);
	        }
	        return return_value;
	    };
	    /**
	     * Handle sync to the back-end.  Called when a model.save() is called.
	     *
	     * Make sure a comm exists.
	     *
	     * Parameters
	     * ----------
	     * method : create, update, patch, delete, read
	     *   create/update always send the full attribute set
	     *   patch - only send attributes listed in options.attrs, and if we
	     *   are queuing up messages, combine with previous messages that have
	     *   not been sent yet
	     * model : the model we are syncing
	     *   will normally be the same as `this`
	     * options : dict
	     *   the `attrs` key, if it exists, gives an {attr: value} dict that
	     *   should be synced, otherwise, sync all attributes.
	     *
	     */
	    WidgetModel.prototype.sync = function (method, model, options) {
	        if (options === void 0) { options = {}; }
	        // the typing is to return `any` since the super.sync method returns a JqXHR, but we just return false if there is an error.
	        if (this.comm === undefined) {
	            throw 'Syncing error: no comm channel defined';
	        }
	        var attrs = (method === 'patch') ? options.attrs : model.get_state(options.drop_defaults);
	        // The state_lock lists attributes that are currently being changed
	        // right now from a kernel message. We don't want to send these
	        // non-changes back to the kernel, so we delete them out of attrs if
	        // they haven't changed from their state_lock value
	        if (this.state_lock !== null) {
	            for (var _i = 0, _a = Object.keys(this.state_lock); _i < _a.length; _i++) {
	                var key = _a[_i];
	                if (attrs[key] === this.state_lock[key]) {
	                    delete attrs[key];
	                }
	            }
	        }
	        var msgState = this.serialize(attrs);
	        if (Object.keys(msgState).length > 0) {
	            // If this message was sent via backbone itself, it will not
	            // have any callbacks.  It's important that we create callbacks
	            // so we can listen for status messages, etc...
	            var callbacks = options.callbacks || this.callbacks();
	            // Check throttle.
	            if (this.pending_msgs >= (this.get('msg_throttle') || 1)) {
	                // The throttle has been exceeded, buffer the current msg so
	                // it can be sent once the kernel has finished processing
	                // some of the existing messages.
	                // Combine updates if it is a 'patch' sync, otherwise replace updates
	                switch (method) {
	                    case 'patch':
	                        this.msg_buffer = _.extend(this.msg_buffer || {}, msgState);
	                        break;
	                    case 'update':
	                    case 'create':
	                        this.msg_buffer = msgState;
	                        break;
	                    default:
	                        throw 'unrecognized syncing method';
	                }
	                this.msg_buffer_callbacks = callbacks;
	            }
	            else {
	                // We haven't exceeded the throttle, send the message like
	                // normal.
	                this.send_sync_message(attrs, callbacks);
	                // Since the comm is a one-way communication, assume the message
	                // arrived and was processed successfully.
	                // Don't call options.success since we don't have a model back from
	                // the server. Note that this means we don't have the Backbone
	                // 'sync' event.
	            }
	        }
	    };
	    /**
	     * Serialize widget state.
	     *
	     * A serializer is a function which takes in a state attribute and a widget,
	     * and synchronously returns a JSONable object. The returned object will
	     * have toJSON called if possible, and the final result should be a
	     * primitive object that is a snapshot of the widget state that may have
	     * binary array buffers.
	     */
	    WidgetModel.prototype.serialize = function (state) {
	        var serializers = this.constructor.serializers || {};
	        for (var _i = 0, state_1 = state; _i < state_1.length; _i++) {
	            var k = state_1[_i];
	            try {
	                if (serializers[k] && serializers[k].serialize) {
	                    state[k] = (serializers[k].serialize)(state[k], this);
	                }
	                else {
	                    // the default serializer just deep-copies the object
	                    state[k] = JSON.parse(JSON.stringify(state[k]));
	                }
	                if (state[k].toJSON) {
	                    state[k] = state[k].toJSON();
	                }
	            }
	            catch (e) {
	                console.error("Error serializing widget state attribute: ", k);
	                throw e;
	            }
	        }
	        return state;
	    };
	    WidgetModel.prototype.send_sync_message = function (state, callbacks) {
	        try {
	            // split out the binary buffers
	            var split = utils.remove_buffers(state);
	            this.comm.send({
	                method: 'update',
	                state: split.state,
	                buffer_paths: split.buffer_paths
	            }, callbacks, {}, split.buffers);
	            this.pending_msgs++;
	        }
	        catch (e) {
	            console.error('Could not send widget sync message', e);
	        }
	    };
	    /**
	     * Push this model's state to the back-end
	     *
	     * This invokes a Backbone.Sync.
	     */
	    WidgetModel.prototype.save_changes = function (callbacks) {
	        if (this.comm_live) {
	            var options = { patch: true };
	            if (callbacks) {
	                options.callbacks = callbacks;
	            }
	            this.save(this._buffered_state_diff, options);
	            this._buffered_state_diff = {};
	        }
	    };
	    /**
	     * on_some_change(['key1', 'key2'], foo, context) differs from
	     * on('change:key1 change:key2', foo, context).
	     * If the widget attributes key1 and key2 are both modified,
	     * the second form will result in foo being called twice
	     * while the first will call foo only once.
	     */
	    WidgetModel.prototype.on_some_change = function (keys, callback, context) {
	        this.on('change', function () {
	            if (keys.some(this.hasChanged, this)) {
	                callback.apply(context, arguments);
	            }
	        }, this);
	    };
	    /**
	     * Serialize the model.  See the deserialization function at the top of this file
	     * and the kernel-side serializer/deserializer.
	     */
	    WidgetModel.prototype.toJSON = function (options) {
	        return 'IPY_MODEL_' + this.id;
	    };
	    /**
	     * Returns a promise for the deserialized state. The second argument
	     * is an instance of widget manager, which is required for the
	     * deserialization of widget models.
	     */
	    WidgetModel._deserialize_state = function (state, manager) {
	        var serializers = this.serializers;
	        var deserialized;
	        if (serializers) {
	            deserialized = {};
	            for (var k in state) {
	                if (serializers[k] && serializers[k].deserialize) {
	                    deserialized[k] = (serializers[k].deserialize)(state[k], manager);
	                }
	                else {
	                    deserialized[k] = state[k];
	                }
	            }
	        }
	        else {
	            deserialized = state;
	        }
	        return utils.resolvePromisesDict(deserialized);
	    };
	    /**
	     * Returns a promise for the serialized state. The second argument
	     * is an instance of widget manager.
	     */
	    WidgetModel._serialize_state = function (state, manager) {
	        var serializers = this.serializers;
	        var serialized;
	        if (serializers) {
	            serialized = {};
	            for (var k in state) {
	                if (serializers[k] && serializers[k].serialize) {
	                    serialized[k] = (serializers[k].serialize)(state[k], manager);
	                }
	                else {
	                    serialized[k] = state[k];
	                }
	            }
	        }
	        else {
	            serialized = state;
	        }
	        return utils.resolvePromisesDict(serialized);
	    };
	    return WidgetModel;
	}(Backbone.Model));
	exports.WidgetModel = WidgetModel;
	var DOMWidgetModel = (function (_super) {
	    __extends(DOMWidgetModel, _super);
	    function DOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            layout: void 0,
	            _dom_classes: []
	        });
	    };
	    return DOMWidgetModel;
	}(WidgetModel));
	DOMWidgetModel.serializers = _.extend({
	    layout: { deserialize: unpack_models },
	    style: { deserialize: unpack_models },
	}, WidgetModel.serializers);
	exports.DOMWidgetModel = DOMWidgetModel;
	/**
	 * - create_view and remove_view are default functions called when adding or removing views
	 * - create_view takes a model and an index and returns a view or a promise for a view for that model
	 * - remove_view takes a view and destroys it (including calling `view.remove()`)
	 * - each time the update() function is called with a new list, the create and remove
	 *   callbacks will be called in an order so that if you append the views created in the
	 *   create callback and remove the views in the remove callback, you will duplicate
	 *   the order of the list.
	 * - the remove callback defaults to just removing the view (e.g., pass in null for the second parameter)
	 * - the context defaults to the created ViewList.  If you pass another context, the create and remove
	 *   will be called in that context.
	 */
	var ViewList = (function () {
	    function ViewList(create_view, remove_view, context) {
	        this.initialize(create_view, remove_view, context);
	    }
	    ViewList.prototype.initialize = function (create_view, remove_view, context) {
	        this._handler_context = context || this;
	        this._models = [];
	        this.views = []; // list of promises for views
	        this._create_view = create_view;
	        this._remove_view = remove_view || function (view) { view.remove(); };
	    };
	    /**
	     * the create_view, remove_view, and context arguments override the defaults
	     * specified when the list is created.
	     * after this function, the .views attribute is a list of promises for views
	     * if you want to perform some action on the list of views, do something like
	     * `Promise.all(myviewlist.views).then(function(views) {...});`
	     */
	    ViewList.prototype.update = function (new_models, create_view, remove_view, context) {
	        var remove = remove_view || this._remove_view;
	        var create = create_view || this._create_view;
	        context = context || this._handler_context;
	        var i = 0;
	        // first, skip past the beginning of the lists if they are identical
	        for (; i < new_models.length; i++) {
	            if (i >= this._models.length || new_models[i] !== this._models[i]) {
	                break;
	            }
	        }
	        var first_removed = i;
	        // Remove the non-matching items from the old list.
	        var removed = this.views.splice(first_removed, this.views.length - first_removed);
	        for (var j = 0; j < removed.length; j++) {
	            removed[j].then(function (view) {
	                remove.call(context, view);
	            });
	        }
	        // Add the rest of the new list items.
	        for (; i < new_models.length; i++) {
	            this.views.push(Promise.resolve(create.call(context, new_models[i], i)));
	        }
	        // make a copy of the input array
	        this._models = new_models.slice();
	        // return a promise that resolves to all of the resolved views
	        return Promise.all(this.views);
	    };
	    /**
	     * removes every view in the list; convenience function for `.update([])`
	     * that should be faster
	     * returns a promise that resolves after this removal is done
	     */
	    ViewList.prototype.remove = function () {
	        var _this = this;
	        return Promise.all(this.views).then(function (views) {
	            views.forEach(function (value) { return _this._remove_view.call(_this._handler_context, value); });
	            _this.views = [];
	            _this._models = [];
	        });
	    };
	    /**
	     * Dispose this viewlist.
	     *
	     * A synchronous function which just deletes references to child views. This
	     * function does not call .remove() on child views because that is
	     * asynchronous. Use this in cases where child views will be removed in
	     * another way.
	     */
	    ViewList.prototype.dispose = function () {
	        this.views = null;
	        this._models = null;
	    };
	    return ViewList;
	}());
	exports.ViewList = ViewList;
	var WidgetView = (function (_super) {
	    __extends(WidgetView, _super);
	    function WidgetView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor.
	     */
	    WidgetView.prototype.initialize = function (parameters) {
	        var _this = this;
	        this.listenTo(this.model, 'change', this.update);
	        this.options = parameters.options;
	        this.once('remove', function () {
	            _this.model.set('_view_count', _this.model.get('_view_count') - 1);
	            _this.model.save_changes();
	        });
	        this.once('displayed', function () {
	            _this.model.set('_view_count', _this.model.get('_view_count') + 1);
	            _this.model.save_changes();
	        });
	        this.displayed = new Promise(function (resolve, reject) {
	            _this.once('displayed', resolve);
	        });
	    };
	    /**
	     * Triggered on model change.
	     *
	     * Update view to be consistent with this.model
	     */
	    WidgetView.prototype.update = function (options) {
	    };
	    ;
	    /**
	     * Render a view
	     *
	     * @returns the view or a promise to the view.
	     */
	    WidgetView.prototype.render = function () {
	    };
	    /**
	     * Create and promise that resolves to a child view of a given model
	     */
	    WidgetView.prototype.create_child_view = function (child_model, options) {
	        var that = this;
	        options = _.extend({ parent: this }, options || {});
	        return this.model.widget_manager.create_view(child_model, options)
	            .catch(utils.reject('Could not create child view', true));
	    };
	    /**
	     * Create msg callbacks for a comm msg.
	     */
	    WidgetView.prototype.callbacks = function () {
	        return this.model.callbacks(this);
	    };
	    /**
	     * Send a custom msg associated with this view.
	     */
	    WidgetView.prototype.send = function (content, buffers) {
	        this.model.send(content, this.callbacks(), buffers);
	    };
	    WidgetView.prototype.touch = function () {
	        this.model.save_changes(this.callbacks());
	    };
	    WidgetView.prototype.remove = function () {
	        // Raise a remove event when the view is removed.
	        _super.prototype.remove.call(this);
	        this.trigger('remove');
	        return this;
	    };
	    return WidgetView;
	}(nativeview_1.NativeView));
	exports.WidgetView = WidgetView;
	var JupyterPhosphorWidget = (function (_super) {
	    __extends(JupyterPhosphorWidget, _super);
	    function JupyterPhosphorWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        return _this;
	    }
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    /**
	     * Process the phosphor message.
	     *
	     * Any custom phosphor widget used inside a Jupyter widget should override
	     * the processMessage function like this.
	     */
	    JupyterPhosphorWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        this._view.processPhosphorMessage(msg);
	    };
	    return JupyterPhosphorWidget;
	}(widgets_1.Widget));
	exports.JupyterPhosphorWidget = JupyterPhosphorWidget;
	var DOMWidgetView = (function (_super) {
	    __extends(DOMWidgetView, _super);
	    function DOMWidgetView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    DOMWidgetView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.id = utils.uuid();
	        this.listenTo(this.model, 'change:_dom_classes', function (model, new_classes) {
	            var old_classes = model.previous('_dom_classes');
	            _this.update_classes(old_classes, new_classes);
	        });
	        this.layoutPromise = Promise.resolve();
	        this.listenTo(this.model, 'change:layout', function (model, value) {
	            _this.setLayout(value, model.previous('layout'));
	        });
	        this.stylePromise = Promise.resolve();
	        this.listenTo(this.model, 'change:style', function (model, value) {
	            _this.setStyle(value, model.previous('style'));
	        });
	        this.displayed.then(function () {
	            _this.update_classes([], _this.model.get('_dom_classes'));
	            _this.setLayout(_this.model.get('layout'));
	            _this.setStyle(_this.model.get('style'));
	        });
	    };
	    DOMWidgetView.prototype.setLayout = function (layout, oldLayout) {
	        var _this = this;
	        if (layout) {
	            this.layoutPromise = this.layoutPromise.then(function (oldLayoutView) {
	                if (oldLayoutView) {
	                    oldLayoutView.unlayout();
	                    _this.stopListening(oldLayoutView.model);
	                    oldLayoutView.remove();
	                }
	                return _this.create_child_view(layout).then(function (view) {
	                    // Trigger the displayed event of the child view.
	                    return _this.displayed.then(function () {
	                        view.trigger('displayed');
	                        _this.listenTo(view.model, 'change', function () {
	                            // Post (asynchronous) so layout changes can take
	                            // effect first.
	                            messaging_1.MessageLoop.postMessage(_this.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	                        });
	                        messaging_1.MessageLoop.postMessage(_this.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	                        return view;
	                    });
	                }).catch(utils.reject('Could not add LayoutView to DOMWidgetView', true));
	            });
	        }
	    };
	    DOMWidgetView.prototype.setStyle = function (style, oldStyle) {
	        var _this = this;
	        if (style) {
	            this.stylePromise = this.stylePromise.then(function (oldStyleView) {
	                if (oldStyleView) {
	                    oldStyleView.unstyle();
	                    _this.stopListening(oldStyleView.model);
	                    oldStyleView.remove();
	                }
	                return _this.create_child_view(style).then(function (view) {
	                    // Trigger the displayed event of the child view.
	                    return _this.displayed.then(function () {
	                        view.trigger('displayed');
	                        // Unlike for the layout attribute, style changes don't
	                        // trigger phosphor resize messages.
	                        return view;
	                    });
	                }).catch(utils.reject('Could not add styleView to DOMWidgetView', true));
	            });
	        }
	    };
	    /**
	     * Update the DOM classes applied to an element, default to this.el.
	     */
	    DOMWidgetView.prototype.update_classes = function (old_classes, new_classes, el) {
	        if (el === undefined) {
	            el = this.el;
	        }
	        _.difference(old_classes, new_classes).map(function (c) {
	            if (el.classList) {
	                el.classList.remove(c);
	            }
	            else {
	                el.setAttribute('class', el.getAttribute('class').replace(c, ''));
	            }
	        });
	        _.difference(new_classes, old_classes).map(function (c) {
	            if (el.classList) {
	                el.classList.add(c);
	            }
	            else {
	                el.setAttribute('class', el.getAttribute('class').concat(' ', c));
	            }
	        });
	    };
	    /**
	     * Update the DOM classes applied to the widget based on a single
	     * trait's value.
	     *
	     * Given a trait value classes map, this function automatically
	     * handles applying the appropriate classes to the widget element
	     * and removing classes that are no longer valid.
	     *
	     * Parameters
	     * ----------
	     * class_map: dictionary
	     *  Dictionary of trait values to class lists.
	     *  Example:
	     *      {
	     *          success: ['alert', 'alert-success'],
	     *          info: ['alert', 'alert-info'],
	     *          warning: ['alert', 'alert-warning'],
	     *          danger: ['alert', 'alert-danger']
	     *      };
	     * trait_name: string
	     *  Name of the trait to check the value of.
	     * el: optional DOM element handle, defaults to this.el
	     *  Element that the classes are applied to.
	     */
	    DOMWidgetView.prototype.update_mapped_classes = function (class_map, trait_name, el) {
	        var key = this.model.previous(trait_name);
	        var old_classes = class_map[key] ? class_map[key] : [];
	        key = this.model.get(trait_name);
	        var new_classes = class_map[key] ? class_map[key] : [];
	        this.update_classes(old_classes, new_classes, el || this.el);
	    };
	    DOMWidgetView.prototype.set_mapped_classes = function (class_map, trait_name, el) {
	        var key = this.model.get(trait_name);
	        var new_classes = class_map[key] ? class_map[key] : [];
	        this.update_classes([], new_classes, el || this.el);
	    };
	    DOMWidgetView.prototype.typeset = function (element, text) {
	        this.displayed.then(function () { utils.typeset(element, text); });
	    };
	    DOMWidgetView.prototype._setElement = function (el) {
	        if (this.pWidget) {
	            this.pWidget.dispose();
	        }
	        this.$el = el instanceof $ ? el : $(el);
	        this.el = this.$el[0];
	        this.pWidget = new JupyterPhosphorWidget({
	            node: el,
	            view: this
	        });
	    };
	    DOMWidgetView.prototype.remove = function () {
	        if (this.pWidget) {
	            this.pWidget.dispose();
	        }
	        return _super.prototype.remove.call(this);
	    };
	    DOMWidgetView.prototype.processPhosphorMessage = function (msg) {
	        switch (msg.type) {
	            case 'after-attach':
	                this.trigger('displayed');
	                break;
	        }
	    };
	    return DOMWidgetView;
	}(WidgetView));
	exports.DOMWidgetView = DOMWidgetView;
	var LabeledDOMWidgetModel = (function (_super) {
	    __extends(LabeledDOMWidgetModel, _super);
	    function LabeledDOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LabeledDOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            description: '',
	        });
	    };
	    return LabeledDOMWidgetModel;
	}(DOMWidgetModel));
	exports.LabeledDOMWidgetModel = LabeledDOMWidgetModel;
	var LabeledDOMWidgetView = (function (_super) {
	    __extends(LabeledDOMWidgetView, _super);
	    function LabeledDOMWidgetView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LabeledDOMWidgetView.prototype.render = function () {
	        this.label = document.createElement('div');
	        this.el.appendChild(this.label);
	        this.label.className = 'widget-label';
	        this.label.style.display = 'none';
	        this.listenTo(this.model, 'change:description', this.updateDescription);
	        this.updateDescription();
	    };
	    LabeledDOMWidgetView.prototype.updateDescription = function () {
	        var description = this.model.get('description');
	        if (description.length === 0) {
	            this.label.style.display = 'none';
	        }
	        else {
	            this.label.innerHTML = description;
	            this.typeset(this.label);
	            this.label.style.display = '';
	        }
	        this.label.title = description;
	    };
	    return LabeledDOMWidgetView;
	}(DOMWidgetView));
	exports.LabeledDOMWidgetView = LabeledDOMWidgetView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js **/


/** START DEFINE BLOCK for jquery@3.2.1/dist/jquery.js **/
jupyter.define('jquery@3.2.1/dist/jquery.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * jQuery JavaScript Library v3.2.1
	 * https://jquery.com/
	 *
	 * Includes Sizzle.js
	 * https://sizzlejs.com/
	 *
	 * Copyright JS Foundation and other contributors
	 * Released under the MIT license
	 * https://jquery.org/license
	 *
	 * Date: 2017-03-20T18:59Z
	 */
	( function( global, factory ) {
	
		"use strict";
	
		if ( typeof module === "object" && typeof module.exports === "object" ) {
	
			// For CommonJS and CommonJS-like environments where a proper `window`
			// is present, execute the factory and get jQuery.
			// For environments that do not have a `window` with a `document`
			// (such as Node.js), expose a factory as module.exports.
			// This accentuates the need for the creation of a real `window`.
			// e.g. var jQuery = require("jquery")(window);
			// See ticket #14549 for more info.
			module.exports = global.document ?
				factory( global, true ) :
				function( w ) {
					if ( !w.document ) {
						throw new Error( "jQuery requires a window with a document" );
					}
					return factory( w );
				};
		} else {
			factory( global );
		}
	
	// Pass this if window is not defined yet
	} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
	
	// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
	// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
	// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
	// enough that all such attempts are guarded in a try block.
	"use strict";
	
	var arr = [];
	
	var document = window.document;
	
	var getProto = Object.getPrototypeOf;
	
	var slice = arr.slice;
	
	var concat = arr.concat;
	
	var push = arr.push;
	
	var indexOf = arr.indexOf;
	
	var class2type = {};
	
	var toString = class2type.toString;
	
	var hasOwn = class2type.hasOwnProperty;
	
	var fnToString = hasOwn.toString;
	
	var ObjectFunctionString = fnToString.call( Object );
	
	var support = {};
	
	
	
		function DOMEval( code, doc ) {
			doc = doc || document;
	
			var script = doc.createElement( "script" );
	
			script.text = code;
			doc.head.appendChild( script ).parentNode.removeChild( script );
		}
	/* global Symbol */
	// Defining this global in .eslintrc.json would create a danger of using the global
	// unguarded in another place, it seems safer to define global only for this module
	
	
	
	var
		version = "3.2.1",
	
		// Define a local copy of jQuery
		jQuery = function( selector, context ) {
	
			// The jQuery object is actually just the init constructor 'enhanced'
			// Need init if jQuery is called (just allow error to be thrown if not included)
			return new jQuery.fn.init( selector, context );
		},
	
		// Support: Android <=4.0 only
		// Make sure we trim BOM and NBSP
		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
	
		// Matches dashed string for camelizing
		rmsPrefix = /^-ms-/,
		rdashAlpha = /-([a-z])/g,
	
		// Used by jQuery.camelCase as callback to replace()
		fcamelCase = function( all, letter ) {
			return letter.toUpperCase();
		};
	
	jQuery.fn = jQuery.prototype = {
	
		// The current version of jQuery being used
		jquery: version,
	
		constructor: jQuery,
	
		// The default length of a jQuery object is 0
		length: 0,
	
		toArray: function() {
			return slice.call( this );
		},
	
		// Get the Nth element in the matched element set OR
		// Get the whole matched element set as a clean array
		get: function( num ) {
	
			// Return all the elements in a clean array
			if ( num == null ) {
				return slice.call( this );
			}
	
			// Return just the one element from the set
			return num < 0 ? this[ num + this.length ] : this[ num ];
		},
	
		// Take an array of elements and push it onto the stack
		// (returning the new matched element set)
		pushStack: function( elems ) {
	
			// Build a new jQuery matched element set
			var ret = jQuery.merge( this.constructor(), elems );
	
			// Add the old object onto the stack (as a reference)
			ret.prevObject = this;
	
			// Return the newly-formed element set
			return ret;
		},
	
		// Execute a callback for every element in the matched set.
		each: function( callback ) {
			return jQuery.each( this, callback );
		},
	
		map: function( callback ) {
			return this.pushStack( jQuery.map( this, function( elem, i ) {
				return callback.call( elem, i, elem );
			} ) );
		},
	
		slice: function() {
			return this.pushStack( slice.apply( this, arguments ) );
		},
	
		first: function() {
			return this.eq( 0 );
		},
	
		last: function() {
			return this.eq( -1 );
		},
	
		eq: function( i ) {
			var len = this.length,
				j = +i + ( i < 0 ? len : 0 );
			return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
		},
	
		end: function() {
			return this.prevObject || this.constructor();
		},
	
		// For internal use only.
		// Behaves like an Array's method, not like a jQuery method.
		push: push,
		sort: arr.sort,
		splice: arr.splice
	};
	
	jQuery.extend = jQuery.fn.extend = function() {
		var options, name, src, copy, copyIsArray, clone,
			target = arguments[ 0 ] || {},
			i = 1,
			length = arguments.length,
			deep = false;
	
		// Handle a deep copy situation
		if ( typeof target === "boolean" ) {
			deep = target;
	
			// Skip the boolean and the target
			target = arguments[ i ] || {};
			i++;
		}
	
		// Handle case when target is a string or something (possible in deep copy)
		if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
			target = {};
		}
	
		// Extend jQuery itself if only one argument is passed
		if ( i === length ) {
			target = this;
			i--;
		}
	
		for ( ; i < length; i++ ) {
	
			// Only deal with non-null/undefined values
			if ( ( options = arguments[ i ] ) != null ) {
	
				// Extend the base object
				for ( name in options ) {
					src = target[ name ];
					copy = options[ name ];
	
					// Prevent never-ending loop
					if ( target === copy ) {
						continue;
					}
	
					// Recurse if we're merging plain objects or arrays
					if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
						( copyIsArray = Array.isArray( copy ) ) ) ) {
	
						if ( copyIsArray ) {
							copyIsArray = false;
							clone = src && Array.isArray( src ) ? src : [];
	
						} else {
							clone = src && jQuery.isPlainObject( src ) ? src : {};
						}
	
						// Never move original objects, clone them
						target[ name ] = jQuery.extend( deep, clone, copy );
	
					// Don't bring in undefined values
					} else if ( copy !== undefined ) {
						target[ name ] = copy;
					}
				}
			}
		}
	
		// Return the modified object
		return target;
	};
	
	jQuery.extend( {
	
		// Unique for each copy of jQuery on the page
		expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
	
		// Assume jQuery is ready without the ready module
		isReady: true,
	
		error: function( msg ) {
			throw new Error( msg );
		},
	
		noop: function() {},
	
		isFunction: function( obj ) {
			return jQuery.type( obj ) === "function";
		},
	
		isWindow: function( obj ) {
			return obj != null && obj === obj.window;
		},
	
		isNumeric: function( obj ) {
	
			// As of jQuery 3.0, isNumeric is limited to
			// strings and numbers (primitives or objects)
			// that can be coerced to finite numbers (gh-2662)
			var type = jQuery.type( obj );
			return ( type === "number" || type === "string" ) &&
	
				// parseFloat NaNs numeric-cast false positives ("")
				// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
				// subtraction forces infinities to NaN
				!isNaN( obj - parseFloat( obj ) );
		},
	
		isPlainObject: function( obj ) {
			var proto, Ctor;
	
			// Detect obvious negatives
			// Use toString instead of jQuery.type to catch host objects
			if ( !obj || toString.call( obj ) !== "[object Object]" ) {
				return false;
			}
	
			proto = getProto( obj );
	
			// Objects with no prototype (e.g., `Object.create( null )`) are plain
			if ( !proto ) {
				return true;
			}
	
			// Objects with prototype are plain iff they were constructed by a global Object function
			Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
			return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
		},
	
		isEmptyObject: function( obj ) {
	
			/* eslint-disable no-unused-vars */
			// See https://github.com/eslint/eslint/issues/6125
			var name;
	
			for ( name in obj ) {
				return false;
			}
			return true;
		},
	
		type: function( obj ) {
			if ( obj == null ) {
				return obj + "";
			}
	
			// Support: Android <=2.3 only (functionish RegExp)
			return typeof obj === "object" || typeof obj === "function" ?
				class2type[ toString.call( obj ) ] || "object" :
				typeof obj;
		},
	
		// Evaluates a script in a global context
		globalEval: function( code ) {
			DOMEval( code );
		},
	
		// Convert dashed to camelCase; used by the css and data modules
		// Support: IE <=9 - 11, Edge 12 - 13
		// Microsoft forgot to hump their vendor prefix (#9572)
		camelCase: function( string ) {
			return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
		},
	
		each: function( obj, callback ) {
			var length, i = 0;
	
			if ( isArrayLike( obj ) ) {
				length = obj.length;
				for ( ; i < length; i++ ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			} else {
				for ( i in obj ) {
					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
						break;
					}
				}
			}
	
			return obj;
		},
	
		// Support: Android <=4.0 only
		trim: function( text ) {
			return text == null ?
				"" :
				( text + "" ).replace( rtrim, "" );
		},
	
		// results is for internal usage only
		makeArray: function( arr, results ) {
			var ret = results || [];
	
			if ( arr != null ) {
				if ( isArrayLike( Object( arr ) ) ) {
					jQuery.merge( ret,
						typeof arr === "string" ?
						[ arr ] : arr
					);
				} else {
					push.call( ret, arr );
				}
			}
	
			return ret;
		},
	
		inArray: function( elem, arr, i ) {
			return arr == null ? -1 : indexOf.call( arr, elem, i );
		},
	
		// Support: Android <=4.0 only, PhantomJS 1 only
		// push.apply(_, arraylike) throws on ancient WebKit
		merge: function( first, second ) {
			var len = +second.length,
				j = 0,
				i = first.length;
	
			for ( ; j < len; j++ ) {
				first[ i++ ] = second[ j ];
			}
	
			first.length = i;
	
			return first;
		},
	
		grep: function( elems, callback, invert ) {
			var callbackInverse,
				matches = [],
				i = 0,
				length = elems.length,
				callbackExpect = !invert;
	
			// Go through the array, only saving the items
			// that pass the validator function
			for ( ; i < length; i++ ) {
				callbackInverse = !callback( elems[ i ], i );
				if ( callbackInverse !== callbackExpect ) {
					matches.push( elems[ i ] );
				}
			}
	
			return matches;
		},
	
		// arg is for internal usage only
		map: function( elems, callback, arg ) {
			var length, value,
				i = 0,
				ret = [];
	
			// Go through the array, translating each of the items to their new values
			if ( isArrayLike( elems ) ) {
				length = elems.length;
				for ( ; i < length; i++ ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
	
			// Go through every key on the object,
			} else {
				for ( i in elems ) {
					value = callback( elems[ i ], i, arg );
	
					if ( value != null ) {
						ret.push( value );
					}
				}
			}
	
			// Flatten any nested arrays
			return concat.apply( [], ret );
		},
	
		// A global GUID counter for objects
		guid: 1,
	
		// Bind a function to a context, optionally partially applying any
		// arguments.
		proxy: function( fn, context ) {
			var tmp, args, proxy;
	
			if ( typeof context === "string" ) {
				tmp = fn[ context ];
				context = fn;
				fn = tmp;
			}
	
			// Quick check to determine if target is callable, in the spec
			// this throws a TypeError, but we will just return undefined.
			if ( !jQuery.isFunction( fn ) ) {
				return undefined;
			}
	
			// Simulated bind
			args = slice.call( arguments, 2 );
			proxy = function() {
				return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
			};
	
			// Set the guid of unique handler to the same of original handler, so it can be removed
			proxy.guid = fn.guid = fn.guid || jQuery.guid++;
	
			return proxy;
		},
	
		now: Date.now,
	
		// jQuery.support is not used in Core but other projects attach their
		// properties to it so it needs to exist.
		support: support
	} );
	
	if ( typeof Symbol === "function" ) {
		jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
	}
	
	// Populate the class2type map
	jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
	function( i, name ) {
		class2type[ "[object " + name + "]" ] = name.toLowerCase();
	} );
	
	function isArrayLike( obj ) {
	
		// Support: real iOS 8.2 only (not reproducible in simulator)
		// `in` check used to prevent JIT error (gh-2145)
		// hasOwn isn't used here due to false negatives
		// regarding Nodelist length in IE
		var length = !!obj && "length" in obj && obj.length,
			type = jQuery.type( obj );
	
		if ( type === "function" || jQuery.isWindow( obj ) ) {
			return false;
		}
	
		return type === "array" || length === 0 ||
			typeof length === "number" && length > 0 && ( length - 1 ) in obj;
	}
	var Sizzle =
	/*!
	 * Sizzle CSS Selector Engine v2.3.3
	 * https://sizzlejs.com/
	 *
	 * Copyright jQuery Foundation and other contributors
	 * Released under the MIT license
	 * http://jquery.org/license
	 *
	 * Date: 2016-08-08
	 */
	(function( window ) {
	
	var i,
		support,
		Expr,
		getText,
		isXML,
		tokenize,
		compile,
		select,
		outermostContext,
		sortInput,
		hasDuplicate,
	
		// Local document vars
		setDocument,
		document,
		docElem,
		documentIsHTML,
		rbuggyQSA,
		rbuggyMatches,
		matches,
		contains,
	
		// Instance-specific data
		expando = "sizzle" + 1 * new Date(),
		preferredDoc = window.document,
		dirruns = 0,
		done = 0,
		classCache = createCache(),
		tokenCache = createCache(),
		compilerCache = createCache(),
		sortOrder = function( a, b ) {
			if ( a === b ) {
				hasDuplicate = true;
			}
			return 0;
		},
	
		// Instance methods
		hasOwn = ({}).hasOwnProperty,
		arr = [],
		pop = arr.pop,
		push_native = arr.push,
		push = arr.push,
		slice = arr.slice,
		// Use a stripped-down indexOf as it's faster than native
		// https://jsperf.com/thor-indexof-vs-for/5
		indexOf = function( list, elem ) {
			var i = 0,
				len = list.length;
			for ( ; i < len; i++ ) {
				if ( list[i] === elem ) {
					return i;
				}
			}
			return -1;
		},
	
		booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
	
		// Regular expressions
	
		// http://www.w3.org/TR/css3-selectors/#whitespace
		whitespace = "[\\x20\\t\\r\\n\\f]",
	
		// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
		identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
	
		// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
		attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
			// Operator (capture 2)
			"*([*^$|!~]?=)" + whitespace +
			// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
			"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
			"*\\]",
	
		pseudos = ":(" + identifier + ")(?:\\((" +
			// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
			// 1. quoted (capture 3; capture 4 or capture 5)
			"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
			// 2. simple (capture 6)
			"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
			// 3. anything else (capture 2)
			".*" +
			")\\)|)",
	
		// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
		rwhitespace = new RegExp( whitespace + "+", "g" ),
		rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
	
		rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
		rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
	
		rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
	
		rpseudo = new RegExp( pseudos ),
		ridentifier = new RegExp( "^" + identifier + "$" ),
	
		matchExpr = {
			"ID": new RegExp( "^#(" + identifier + ")" ),
			"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
			"TAG": new RegExp( "^(" + identifier + "|[*])" ),
			"ATTR": new RegExp( "^" + attributes ),
			"PSEUDO": new RegExp( "^" + pseudos ),
			"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
				"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
				"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
			"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
			// For use in libraries implementing .is()
			// We use this for POS matching in `select`
			"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
				whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
		},
	
		rinputs = /^(?:input|select|textarea|button)$/i,
		rheader = /^h\d$/i,
	
		rnative = /^[^{]+\{\s*\[native \w/,
	
		// Easily-parseable/retrievable ID or TAG or CLASS selectors
		rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
	
		rsibling = /[+~]/,
	
		// CSS escapes
		// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
		runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
		funescape = function( _, escaped, escapedWhitespace ) {
			var high = "0x" + escaped - 0x10000;
			// NaN means non-codepoint
			// Support: Firefox<24
			// Workaround erroneous numeric interpretation of +"0x"
			return high !== high || escapedWhitespace ?
				escaped :
				high < 0 ?
					// BMP codepoint
					String.fromCharCode( high + 0x10000 ) :
					// Supplemental Plane codepoint (surrogate pair)
					String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
		},
	
		// CSS string/identifier serialization
		// https://drafts.csswg.org/cssom/#common-serializing-idioms
		rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
		fcssescape = function( ch, asCodePoint ) {
			if ( asCodePoint ) {
	
				// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
				if ( ch === "\0" ) {
					return "\uFFFD";
				}
	
				// Control characters and (dependent upon position) numbers get escaped as code points
				return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
			}
	
			// Other potentially-special ASCII characters get backslash-escaped
			return "\\" + ch;
		},
	
		// Used for iframes
		// See setDocument()
		// Removing the function wrapper causes a "Permission Denied"
		// error in IE
		unloadHandler = function() {
			setDocument();
		},
	
		disabledAncestor = addCombinator(
			function( elem ) {
				return elem.disabled === true && ("form" in elem || "label" in elem);
			},
			{ dir: "parentNode", next: "legend" }
		);
	
	// Optimize for push.apply( _, NodeList )
	try {
		push.apply(
			(arr = slice.call( preferredDoc.childNodes )),
			preferredDoc.childNodes
		);
		// Support: Android<4.0
		// Detect silently failing push.apply
		arr[ preferredDoc.childNodes.length ].nodeType;
	} catch ( e ) {
		push = { apply: arr.length ?
	
			// Leverage slice if possible
			function( target, els ) {
				push_native.apply( target, slice.call(els) );
			} :
	
			// Support: IE<9
			// Otherwise append directly
			function( target, els ) {
				var j = target.length,
					i = 0;
				// Can't trust NodeList.length
				while ( (target[j++] = els[i++]) ) {}
				target.length = j - 1;
			}
		};
	}
	
	function Sizzle( selector, context, results, seed ) {
		var m, i, elem, nid, match, groups, newSelector,
			newContext = context && context.ownerDocument,
	
			// nodeType defaults to 9, since context defaults to document
			nodeType = context ? context.nodeType : 9;
	
		results = results || [];
	
		// Return early from calls with invalid selector or context
		if ( typeof selector !== "string" || !selector ||
			nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
	
			return results;
		}
	
		// Try to shortcut find operations (as opposed to filters) in HTML documents
		if ( !seed ) {
	
			if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
				setDocument( context );
			}
			context = context || document;
	
			if ( documentIsHTML ) {
	
				// If the selector is sufficiently simple, try using a "get*By*" DOM method
				// (excepting DocumentFragment context, where the methods don't exist)
				if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
	
					// ID selector
					if ( (m = match[1]) ) {
	
						// Document context
						if ( nodeType === 9 ) {
							if ( (elem = context.getElementById( m )) ) {
	
								// Support: IE, Opera, Webkit
								// TODO: identify versions
								// getElementById can match elements by name instead of ID
								if ( elem.id === m ) {
									results.push( elem );
									return results;
								}
							} else {
								return results;
							}
	
						// Element context
						} else {
	
							// Support: IE, Opera, Webkit
							// TODO: identify versions
							// getElementById can match elements by name instead of ID
							if ( newContext && (elem = newContext.getElementById( m )) &&
								contains( context, elem ) &&
								elem.id === m ) {
	
								results.push( elem );
								return results;
							}
						}
	
					// Type selector
					} else if ( match[2] ) {
						push.apply( results, context.getElementsByTagName( selector ) );
						return results;
	
					// Class selector
					} else if ( (m = match[3]) && support.getElementsByClassName &&
						context.getElementsByClassName ) {
	
						push.apply( results, context.getElementsByClassName( m ) );
						return results;
					}
				}
	
				// Take advantage of querySelectorAll
				if ( support.qsa &&
					!compilerCache[ selector + " " ] &&
					(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
	
					if ( nodeType !== 1 ) {
						newContext = context;
						newSelector = selector;
	
					// qSA looks outside Element context, which is not what we want
					// Thanks to Andrew Dupont for this workaround technique
					// Support: IE <=8
					// Exclude object elements
					} else if ( context.nodeName.toLowerCase() !== "object" ) {
	
						// Capture the context ID, setting it first if necessary
						if ( (nid = context.getAttribute( "id" )) ) {
							nid = nid.replace( rcssescape, fcssescape );
						} else {
							context.setAttribute( "id", (nid = expando) );
						}
	
						// Prefix every selector in the list
						groups = tokenize( selector );
						i = groups.length;
						while ( i-- ) {
							groups[i] = "#" + nid + " " + toSelector( groups[i] );
						}
						newSelector = groups.join( "," );
	
						// Expand context for sibling selectors
						newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
							context;
					}
	
					if ( newSelector ) {
						try {
							push.apply( results,
								newContext.querySelectorAll( newSelector )
							);
							return results;
						} catch ( qsaError ) {
						} finally {
							if ( nid === expando ) {
								context.removeAttribute( "id" );
							}
						}
					}
				}
			}
		}
	
		// All others
		return select( selector.replace( rtrim, "$1" ), context, results, seed );
	}
	
	/**
	 * Create key-value caches of limited size
	 * @returns {function(string, object)} Returns the Object data after storing it on itself with
	 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
	 *	deleting the oldest entry
	 */
	function createCache() {
		var keys = [];
	
		function cache( key, value ) {
			// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
			if ( keys.push( key + " " ) > Expr.cacheLength ) {
				// Only keep the most recent entries
				delete cache[ keys.shift() ];
			}
			return (cache[ key + " " ] = value);
		}
		return cache;
	}
	
	/**
	 * Mark a function for special use by Sizzle
	 * @param {Function} fn The function to mark
	 */
	function markFunction( fn ) {
		fn[ expando ] = true;
		return fn;
	}
	
	/**
	 * Support testing using an element
	 * @param {Function} fn Passed the created element and returns a boolean result
	 */
	function assert( fn ) {
		var el = document.createElement("fieldset");
	
		try {
			return !!fn( el );
		} catch (e) {
			return false;
		} finally {
			// Remove from its parent by default
			if ( el.parentNode ) {
				el.parentNode.removeChild( el );
			}
			// release memory in IE
			el = null;
		}
	}
	
	/**
	 * Adds the same handler for all of the specified attrs
	 * @param {String} attrs Pipe-separated list of attributes
	 * @param {Function} handler The method that will be applied
	 */
	function addHandle( attrs, handler ) {
		var arr = attrs.split("|"),
			i = arr.length;
	
		while ( i-- ) {
			Expr.attrHandle[ arr[i] ] = handler;
		}
	}
	
	/**
	 * Checks document order of two siblings
	 * @param {Element} a
	 * @param {Element} b
	 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
	 */
	function siblingCheck( a, b ) {
		var cur = b && a,
			diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
				a.sourceIndex - b.sourceIndex;
	
		// Use IE sourceIndex if available on both nodes
		if ( diff ) {
			return diff;
		}
	
		// Check if b follows a
		if ( cur ) {
			while ( (cur = cur.nextSibling) ) {
				if ( cur === b ) {
					return -1;
				}
			}
		}
	
		return a ? 1 : -1;
	}
	
	/**
	 * Returns a function to use in pseudos for input types
	 * @param {String} type
	 */
	function createInputPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return name === "input" && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for buttons
	 * @param {String} type
	 */
	function createButtonPseudo( type ) {
		return function( elem ) {
			var name = elem.nodeName.toLowerCase();
			return (name === "input" || name === "button") && elem.type === type;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for :enabled/:disabled
	 * @param {Boolean} disabled true for :disabled; false for :enabled
	 */
	function createDisabledPseudo( disabled ) {
	
		// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
		return function( elem ) {
	
			// Only certain elements can match :enabled or :disabled
			// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
			// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
			if ( "form" in elem ) {
	
				// Check for inherited disabledness on relevant non-disabled elements:
				// * listed form-associated elements in a disabled fieldset
				//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
				//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
				// * option elements in a disabled optgroup
				//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
				// All such elements have a "form" property.
				if ( elem.parentNode && elem.disabled === false ) {
	
					// Option elements defer to a parent optgroup if present
					if ( "label" in elem ) {
						if ( "label" in elem.parentNode ) {
							return elem.parentNode.disabled === disabled;
						} else {
							return elem.disabled === disabled;
						}
					}
	
					// Support: IE 6 - 11
					// Use the isDisabled shortcut property to check for disabled fieldset ancestors
					return elem.isDisabled === disabled ||
	
						// Where there is no isDisabled, check manually
						/* jshint -W018 */
						elem.isDisabled !== !disabled &&
							disabledAncestor( elem ) === disabled;
				}
	
				return elem.disabled === disabled;
	
			// Try to winnow out elements that can't be disabled before trusting the disabled property.
			// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
			// even exist on them, let alone have a boolean value.
			} else if ( "label" in elem ) {
				return elem.disabled === disabled;
			}
	
			// Remaining elements are neither :enabled nor :disabled
			return false;
		};
	}
	
	/**
	 * Returns a function to use in pseudos for positionals
	 * @param {Function} fn
	 */
	function createPositionalPseudo( fn ) {
		return markFunction(function( argument ) {
			argument = +argument;
			return markFunction(function( seed, matches ) {
				var j,
					matchIndexes = fn( [], seed.length, argument ),
					i = matchIndexes.length;
	
				// Match elements found at the specified indexes
				while ( i-- ) {
					if ( seed[ (j = matchIndexes[i]) ] ) {
						seed[j] = !(matches[j] = seed[j]);
					}
				}
			});
		});
	}
	
	/**
	 * Checks a node for validity as a Sizzle context
	 * @param {Element|Object=} context
	 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
	 */
	function testContext( context ) {
		return context && typeof context.getElementsByTagName !== "undefined" && context;
	}
	
	// Expose support vars for convenience
	support = Sizzle.support = {};
	
	/**
	 * Detects XML nodes
	 * @param {Element|Object} elem An element or a document
	 * @returns {Boolean} True iff elem is a non-HTML XML node
	 */
	isXML = Sizzle.isXML = function( elem ) {
		// documentElement is verified for cases where it doesn't yet exist
		// (such as loading iframes in IE - #4833)
		var documentElement = elem && (elem.ownerDocument || elem).documentElement;
		return documentElement ? documentElement.nodeName !== "HTML" : false;
	};
	
	/**
	 * Sets document-related variables once based on the current document
	 * @param {Element|Object} [doc] An element or document object to use to set the document
	 * @returns {Object} Returns the current document
	 */
	setDocument = Sizzle.setDocument = function( node ) {
		var hasCompare, subWindow,
			doc = node ? node.ownerDocument || node : preferredDoc;
	
		// Return early if doc is invalid or already selected
		if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
			return document;
		}
	
		// Update global variables
		document = doc;
		docElem = document.documentElement;
		documentIsHTML = !isXML( document );
	
		// Support: IE 9-11, Edge
		// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
		if ( preferredDoc !== document &&
			(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
	
			// Support: IE 11, Edge
			if ( subWindow.addEventListener ) {
				subWindow.addEventListener( "unload", unloadHandler, false );
	
			// Support: IE 9 - 10 only
			} else if ( subWindow.attachEvent ) {
				subWindow.attachEvent( "onunload", unloadHandler );
			}
		}
	
		/* Attributes
		---------------------------------------------------------------------- */
	
		// Support: IE<8
		// Verify that getAttribute really returns attributes and not properties
		// (excepting IE8 booleans)
		support.attributes = assert(function( el ) {
			el.className = "i";
			return !el.getAttribute("className");
		});
	
		/* getElement(s)By*
		---------------------------------------------------------------------- */
	
		// Check if getElementsByTagName("*") returns only elements
		support.getElementsByTagName = assert(function( el ) {
			el.appendChild( document.createComment("") );
			return !el.getElementsByTagName("*").length;
		});
	
		// Support: IE<9
		support.getElementsByClassName = rnative.test( document.getElementsByClassName );
	
		// Support: IE<10
		// Check if getElementById returns elements by name
		// The broken getElementById methods don't pick up programmatically-set names,
		// so use a roundabout getElementsByName test
		support.getById = assert(function( el ) {
			docElem.appendChild( el ).id = expando;
			return !document.getElementsByName || !document.getElementsByName( expando ).length;
		});
	
		// ID filter and find
		if ( support.getById ) {
			Expr.filter["ID"] = function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					return elem.getAttribute("id") === attrId;
				};
			};
			Expr.find["ID"] = function( id, context ) {
				if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
					var elem = context.getElementById( id );
					return elem ? [ elem ] : [];
				}
			};
		} else {
			Expr.filter["ID"] =  function( id ) {
				var attrId = id.replace( runescape, funescape );
				return function( elem ) {
					var node = typeof elem.getAttributeNode !== "undefined" &&
						elem.getAttributeNode("id");
					return node && node.value === attrId;
				};
			};
	
			// Support: IE 6 - 7 only
			// getElementById is not reliable as a find shortcut
			Expr.find["ID"] = function( id, context ) {
				if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
					var node, i, elems,
						elem = context.getElementById( id );
	
					if ( elem ) {
	
						// Verify the id attribute
						node = elem.getAttributeNode("id");
						if ( node && node.value === id ) {
							return [ elem ];
						}
	
						// Fall back on getElementsByName
						elems = context.getElementsByName( id );
						i = 0;
						while ( (elem = elems[i++]) ) {
							node = elem.getAttributeNode("id");
							if ( node && node.value === id ) {
								return [ elem ];
							}
						}
					}
	
					return [];
				}
			};
		}
	
		// Tag
		Expr.find["TAG"] = support.getElementsByTagName ?
			function( tag, context ) {
				if ( typeof context.getElementsByTagName !== "undefined" ) {
					return context.getElementsByTagName( tag );
	
				// DocumentFragment nodes don't have gEBTN
				} else if ( support.qsa ) {
					return context.querySelectorAll( tag );
				}
			} :
	
			function( tag, context ) {
				var elem,
					tmp = [],
					i = 0,
					// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
					results = context.getElementsByTagName( tag );
	
				// Filter out possible comments
				if ( tag === "*" ) {
					while ( (elem = results[i++]) ) {
						if ( elem.nodeType === 1 ) {
							tmp.push( elem );
						}
					}
	
					return tmp;
				}
				return results;
			};
	
		// Class
		Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
			if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
				return context.getElementsByClassName( className );
			}
		};
	
		/* QSA/matchesSelector
		---------------------------------------------------------------------- */
	
		// QSA and matchesSelector support
	
		// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
		rbuggyMatches = [];
	
		// qSa(:focus) reports false when true (Chrome 21)
		// We allow this because of a bug in IE8/9 that throws an error
		// whenever `document.activeElement` is accessed on an iframe
		// So, we allow :focus to pass through QSA all the time to avoid the IE error
		// See https://bugs.jquery.com/ticket/13378
		rbuggyQSA = [];
	
		if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
			// Build QSA regex
			// Regex strategy adopted from Diego Perini
			assert(function( el ) {
				// Select is set to empty string on purpose
				// This is to test IE's treatment of not explicitly
				// setting a boolean content attribute,
				// since its presence should be enough
				// https://bugs.jquery.com/ticket/12359
				docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
					"<select id='" + expando + "-\r\\' msallowcapture=''>" +
					"<option selected=''></option></select>";
	
				// Support: IE8, Opera 11-12.16
				// Nothing should be selected when empty strings follow ^= or $= or *=
				// The test attribute must be unknown in Opera but "safe" for WinRT
				// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
				if ( el.querySelectorAll("[msallowcapture^='']").length ) {
					rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
				}
	
				// Support: IE8
				// Boolean attributes and "value" are not treated correctly
				if ( !el.querySelectorAll("[selected]").length ) {
					rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
				}
	
				// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
				if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
					rbuggyQSA.push("~=");
				}
	
				// Webkit/Opera - :checked should return selected option elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				// IE8 throws error here and will not see later tests
				if ( !el.querySelectorAll(":checked").length ) {
					rbuggyQSA.push(":checked");
				}
	
				// Support: Safari 8+, iOS 8+
				// https://bugs.webkit.org/show_bug.cgi?id=136851
				// In-page `selector#id sibling-combinator selector` fails
				if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
					rbuggyQSA.push(".#.+[+~]");
				}
			});
	
			assert(function( el ) {
				el.innerHTML = "<a href='' disabled='disabled'></a>" +
					"<select disabled='disabled'><option/></select>";
	
				// Support: Windows 8 Native Apps
				// The type and name attributes are restricted during .innerHTML assignment
				var input = document.createElement("input");
				input.setAttribute( "type", "hidden" );
				el.appendChild( input ).setAttribute( "name", "D" );
	
				// Support: IE8
				// Enforce case-sensitivity of name attribute
				if ( el.querySelectorAll("[name=d]").length ) {
					rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
				}
	
				// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
				// IE8 throws error here and will not see later tests
				if ( el.querySelectorAll(":enabled").length !== 2 ) {
					rbuggyQSA.push( ":enabled", ":disabled" );
				}
	
				// Support: IE9-11+
				// IE's :disabled selector does not pick up the children of disabled fieldsets
				docElem.appendChild( el ).disabled = true;
				if ( el.querySelectorAll(":disabled").length !== 2 ) {
					rbuggyQSA.push( ":enabled", ":disabled" );
				}
	
				// Opera 10-11 does not throw on post-comma invalid pseudos
				el.querySelectorAll("*,:x");
				rbuggyQSA.push(",.*:");
			});
		}
	
		if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
			docElem.webkitMatchesSelector ||
			docElem.mozMatchesSelector ||
			docElem.oMatchesSelector ||
			docElem.msMatchesSelector) )) ) {
	
			assert(function( el ) {
				// Check to see if it's possible to do matchesSelector
				// on a disconnected node (IE 9)
				support.disconnectedMatch = matches.call( el, "*" );
	
				// This should fail with an exception
				// Gecko does not error, returns false instead
				matches.call( el, "[s!='']:x" );
				rbuggyMatches.push( "!=", pseudos );
			});
		}
	
		rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
		rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
	
		/* Contains
		---------------------------------------------------------------------- */
		hasCompare = rnative.test( docElem.compareDocumentPosition );
	
		// Element contains another
		// Purposefully self-exclusive
		// As in, an element does not contain itself
		contains = hasCompare || rnative.test( docElem.contains ) ?
			function( a, b ) {
				var adown = a.nodeType === 9 ? a.documentElement : a,
					bup = b && b.parentNode;
				return a === bup || !!( bup && bup.nodeType === 1 && (
					adown.contains ?
						adown.contains( bup ) :
						a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
				));
			} :
			function( a, b ) {
				if ( b ) {
					while ( (b = b.parentNode) ) {
						if ( b === a ) {
							return true;
						}
					}
				}
				return false;
			};
	
		/* Sorting
		---------------------------------------------------------------------- */
	
		// Document order sorting
		sortOrder = hasCompare ?
		function( a, b ) {
	
			// Flag for duplicate removal
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			// Sort on method existence if only one input has compareDocumentPosition
			var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
			if ( compare ) {
				return compare;
			}
	
			// Calculate position if both inputs belong to the same document
			compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
				a.compareDocumentPosition( b ) :
	
				// Otherwise we know they are disconnected
				1;
	
			// Disconnected nodes
			if ( compare & 1 ||
				(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
	
				// Choose the first element that is related to our preferred document
				if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
					return -1;
				}
				if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
					return 1;
				}
	
				// Maintain original order
				return sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
			}
	
			return compare & 4 ? -1 : 1;
		} :
		function( a, b ) {
			// Exit early if the nodes are identical
			if ( a === b ) {
				hasDuplicate = true;
				return 0;
			}
	
			var cur,
				i = 0,
				aup = a.parentNode,
				bup = b.parentNode,
				ap = [ a ],
				bp = [ b ];
	
			// Parentless nodes are either documents or disconnected
			if ( !aup || !bup ) {
				return a === document ? -1 :
					b === document ? 1 :
					aup ? -1 :
					bup ? 1 :
					sortInput ?
					( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
					0;
	
			// If the nodes are siblings, we can do a quick check
			} else if ( aup === bup ) {
				return siblingCheck( a, b );
			}
	
			// Otherwise we need full lists of their ancestors for comparison
			cur = a;
			while ( (cur = cur.parentNode) ) {
				ap.unshift( cur );
			}
			cur = b;
			while ( (cur = cur.parentNode) ) {
				bp.unshift( cur );
			}
	
			// Walk down the tree looking for a discrepancy
			while ( ap[i] === bp[i] ) {
				i++;
			}
	
			return i ?
				// Do a sibling check if the nodes have a common ancestor
				siblingCheck( ap[i], bp[i] ) :
	
				// Otherwise nodes in our document sort first
				ap[i] === preferredDoc ? -1 :
				bp[i] === preferredDoc ? 1 :
				0;
		};
	
		return document;
	};
	
	Sizzle.matches = function( expr, elements ) {
		return Sizzle( expr, null, null, elements );
	};
	
	Sizzle.matchesSelector = function( elem, expr ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		// Make sure that attribute selectors are quoted
		expr = expr.replace( rattributeQuotes, "='$1']" );
	
		if ( support.matchesSelector && documentIsHTML &&
			!compilerCache[ expr + " " ] &&
			( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
			( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
	
			try {
				var ret = matches.call( elem, expr );
	
				// IE 9's matchesSelector returns false on disconnected nodes
				if ( ret || support.disconnectedMatch ||
						// As well, disconnected nodes are said to be in a document
						// fragment in IE 9
						elem.document && elem.document.nodeType !== 11 ) {
					return ret;
				}
			} catch (e) {}
		}
	
		return Sizzle( expr, document, null, [ elem ] ).length > 0;
	};
	
	Sizzle.contains = function( context, elem ) {
		// Set document vars if needed
		if ( ( context.ownerDocument || context ) !== document ) {
			setDocument( context );
		}
		return contains( context, elem );
	};
	
	Sizzle.attr = function( elem, name ) {
		// Set document vars if needed
		if ( ( elem.ownerDocument || elem ) !== document ) {
			setDocument( elem );
		}
	
		var fn = Expr.attrHandle[ name.toLowerCase() ],
			// Don't get fooled by Object.prototype properties (jQuery #13807)
			val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
				fn( elem, name, !documentIsHTML ) :
				undefined;
	
		return val !== undefined ?
			val :
			support.attributes || !documentIsHTML ?
				elem.getAttribute( name ) :
				(val = elem.getAttributeNode(name)) && val.specified ?
					val.value :
					null;
	};
	
	Sizzle.escape = function( sel ) {
		return (sel + "").replace( rcssescape, fcssescape );
	};
	
	Sizzle.error = function( msg ) {
		throw new Error( "Syntax error, unrecognized expression: " + msg );
	};
	
	/**
	 * Document sorting and removing duplicates
	 * @param {ArrayLike} results
	 */
	Sizzle.uniqueSort = function( results ) {
		var elem,
			duplicates = [],
			j = 0,
			i = 0;
	
		// Unless we *know* we can detect duplicates, assume their presence
		hasDuplicate = !support.detectDuplicates;
		sortInput = !support.sortStable && results.slice( 0 );
		results.sort( sortOrder );
	
		if ( hasDuplicate ) {
			while ( (elem = results[i++]) ) {
				if ( elem === results[ i ] ) {
					j = duplicates.push( i );
				}
			}
			while ( j-- ) {
				results.splice( duplicates[ j ], 1 );
			}
		}
	
		// Clear input after sorting to release objects
		// See https://github.com/jquery/sizzle/pull/225
		sortInput = null;
	
		return results;
	};
	
	/**
	 * Utility function for retrieving the text value of an array of DOM nodes
	 * @param {Array|Element} elem
	 */
	getText = Sizzle.getText = function( elem ) {
		var node,
			ret = "",
			i = 0,
			nodeType = elem.nodeType;
	
		if ( !nodeType ) {
			// If no nodeType, this is expected to be an array
			while ( (node = elem[i++]) ) {
				// Do not traverse comment nodes
				ret += getText( node );
			}
		} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
			// Use textContent for elements
			// innerText usage removed for consistency of new lines (jQuery #11153)
			if ( typeof elem.textContent === "string" ) {
				return elem.textContent;
			} else {
				// Traverse its children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					ret += getText( elem );
				}
			}
		} else if ( nodeType === 3 || nodeType === 4 ) {
			return elem.nodeValue;
		}
		// Do not include comment or processing instruction nodes
	
		return ret;
	};
	
	Expr = Sizzle.selectors = {
	
		// Can be adjusted by the user
		cacheLength: 50,
	
		createPseudo: markFunction,
	
		match: matchExpr,
	
		attrHandle: {},
	
		find: {},
	
		relative: {
			">": { dir: "parentNode", first: true },
			" ": { dir: "parentNode" },
			"+": { dir: "previousSibling", first: true },
			"~": { dir: "previousSibling" }
		},
	
		preFilter: {
			"ATTR": function( match ) {
				match[1] = match[1].replace( runescape, funescape );
	
				// Move the given value to match[3] whether quoted or unquoted
				match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
	
				if ( match[2] === "~=" ) {
					match[3] = " " + match[3] + " ";
				}
	
				return match.slice( 0, 4 );
			},
	
			"CHILD": function( match ) {
				/* matches from matchExpr["CHILD"]
					1 type (only|nth|...)
					2 what (child|of-type)
					3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
					4 xn-component of xn+y argument ([+-]?\d*n|)
					5 sign of xn-component
					6 x of xn-component
					7 sign of y-component
					8 y of y-component
				*/
				match[1] = match[1].toLowerCase();
	
				if ( match[1].slice( 0, 3 ) === "nth" ) {
					// nth-* requires argument
					if ( !match[3] ) {
						Sizzle.error( match[0] );
					}
	
					// numeric x and y parameters for Expr.filter.CHILD
					// remember that false/true cast respectively to 0/1
					match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
					match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
	
				// other types prohibit arguments
				} else if ( match[3] ) {
					Sizzle.error( match[0] );
				}
	
				return match;
			},
	
			"PSEUDO": function( match ) {
				var excess,
					unquoted = !match[6] && match[2];
	
				if ( matchExpr["CHILD"].test( match[0] ) ) {
					return null;
				}
	
				// Accept quoted arguments as-is
				if ( match[3] ) {
					match[2] = match[4] || match[5] || "";
	
				// Strip excess characters from unquoted arguments
				} else if ( unquoted && rpseudo.test( unquoted ) &&
					// Get excess from tokenize (recursively)
					(excess = tokenize( unquoted, true )) &&
					// advance to the next closing parenthesis
					(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
	
					// excess is a negative index
					match[0] = match[0].slice( 0, excess );
					match[2] = unquoted.slice( 0, excess );
				}
	
				// Return only captures needed by the pseudo filter method (type and argument)
				return match.slice( 0, 3 );
			}
		},
	
		filter: {
	
			"TAG": function( nodeNameSelector ) {
				var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
				return nodeNameSelector === "*" ?
					function() { return true; } :
					function( elem ) {
						return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
					};
			},
	
			"CLASS": function( className ) {
				var pattern = classCache[ className + " " ];
	
				return pattern ||
					(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
					classCache( className, function( elem ) {
						return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
					});
			},
	
			"ATTR": function( name, operator, check ) {
				return function( elem ) {
					var result = Sizzle.attr( elem, name );
	
					if ( result == null ) {
						return operator === "!=";
					}
					if ( !operator ) {
						return true;
					}
	
					result += "";
	
					return operator === "=" ? result === check :
						operator === "!=" ? result !== check :
						operator === "^=" ? check && result.indexOf( check ) === 0 :
						operator === "*=" ? check && result.indexOf( check ) > -1 :
						operator === "$=" ? check && result.slice( -check.length ) === check :
						operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
						operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
						false;
				};
			},
	
			"CHILD": function( type, what, argument, first, last ) {
				var simple = type.slice( 0, 3 ) !== "nth",
					forward = type.slice( -4 ) !== "last",
					ofType = what === "of-type";
	
				return first === 1 && last === 0 ?
	
					// Shortcut for :nth-*(n)
					function( elem ) {
						return !!elem.parentNode;
					} :
	
					function( elem, context, xml ) {
						var cache, uniqueCache, outerCache, node, nodeIndex, start,
							dir = simple !== forward ? "nextSibling" : "previousSibling",
							parent = elem.parentNode,
							name = ofType && elem.nodeName.toLowerCase(),
							useCache = !xml && !ofType,
							diff = false;
	
						if ( parent ) {
	
							// :(first|last|only)-(child|of-type)
							if ( simple ) {
								while ( dir ) {
									node = elem;
									while ( (node = node[ dir ]) ) {
										if ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) {
	
											return false;
										}
									}
									// Reverse direction for :only-* (if we haven't yet done so)
									start = dir = type === "only" && !start && "nextSibling";
								}
								return true;
							}
	
							start = [ forward ? parent.firstChild : parent.lastChild ];
	
							// non-xml :nth-child(...) stores cache data on `parent`
							if ( forward && useCache ) {
	
								// Seek `elem` from a previously-cached index
	
								// ...in a gzip-friendly way
								node = parent;
								outerCache = node[ expando ] || (node[ expando ] = {});
	
								// Support: IE <9 only
								// Defend against cloned attroperties (jQuery gh-1709)
								uniqueCache = outerCache[ node.uniqueID ] ||
									(outerCache[ node.uniqueID ] = {});
	
								cache = uniqueCache[ type ] || [];
								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
								diff = nodeIndex && cache[ 2 ];
								node = nodeIndex && parent.childNodes[ nodeIndex ];
	
								while ( (node = ++nodeIndex && node && node[ dir ] ||
	
									// Fallback to seeking `elem` from the start
									(diff = nodeIndex = 0) || start.pop()) ) {
	
									// When found, cache indexes on `parent` and break
									if ( node.nodeType === 1 && ++diff && node === elem ) {
										uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
										break;
									}
								}
	
							} else {
								// Use previously-cached element index if available
								if ( useCache ) {
									// ...in a gzip-friendly way
									node = elem;
									outerCache = node[ expando ] || (node[ expando ] = {});
	
									// Support: IE <9 only
									// Defend against cloned attroperties (jQuery gh-1709)
									uniqueCache = outerCache[ node.uniqueID ] ||
										(outerCache[ node.uniqueID ] = {});
	
									cache = uniqueCache[ type ] || [];
									nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
									diff = nodeIndex;
								}
	
								// xml :nth-child(...)
								// or :nth-last-child(...) or :nth(-last)?-of-type(...)
								if ( diff === false ) {
									// Use the same loop as above to seek `elem` from the start
									while ( (node = ++nodeIndex && node && node[ dir ] ||
										(diff = nodeIndex = 0) || start.pop()) ) {
	
										if ( ( ofType ?
											node.nodeName.toLowerCase() === name :
											node.nodeType === 1 ) &&
											++diff ) {
	
											// Cache the index of each encountered element
											if ( useCache ) {
												outerCache = node[ expando ] || (node[ expando ] = {});
	
												// Support: IE <9 only
												// Defend against cloned attroperties (jQuery gh-1709)
												uniqueCache = outerCache[ node.uniqueID ] ||
													(outerCache[ node.uniqueID ] = {});
	
												uniqueCache[ type ] = [ dirruns, diff ];
											}
	
											if ( node === elem ) {
												break;
											}
										}
									}
								}
							}
	
							// Incorporate the offset, then check against cycle size
							diff -= last;
							return diff === first || ( diff % first === 0 && diff / first >= 0 );
						}
					};
			},
	
			"PSEUDO": function( pseudo, argument ) {
				// pseudo-class names are case-insensitive
				// http://www.w3.org/TR/selectors/#pseudo-classes
				// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
				// Remember that setFilters inherits from pseudos
				var args,
					fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
						Sizzle.error( "unsupported pseudo: " + pseudo );
	
				// The user may use createPseudo to indicate that
				// arguments are needed to create the filter function
				// just as Sizzle does
				if ( fn[ expando ] ) {
					return fn( argument );
				}
	
				// But maintain support for old signatures
				if ( fn.length > 1 ) {
					args = [ pseudo, pseudo, "", argument ];
					return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
						markFunction(function( seed, matches ) {
							var idx,
								matched = fn( seed, argument ),
								i = matched.length;
							while ( i-- ) {
								idx = indexOf( seed, matched[i] );
								seed[ idx ] = !( matches[ idx ] = matched[i] );
							}
						}) :
						function( elem ) {
							return fn( elem, 0, args );
						};
				}
	
				return fn;
			}
		},
	
		pseudos: {
			// Potentially complex pseudos
			"not": markFunction(function( selector ) {
				// Trim the selector passed to compile
				// to avoid treating leading and trailing
				// spaces as combinators
				var input = [],
					results = [],
					matcher = compile( selector.replace( rtrim, "$1" ) );
	
				return matcher[ expando ] ?
					markFunction(function( seed, matches, context, xml ) {
						var elem,
							unmatched = matcher( seed, null, xml, [] ),
							i = seed.length;
	
						// Match elements unmatched by `matcher`
						while ( i-- ) {
							if ( (elem = unmatched[i]) ) {
								seed[i] = !(matches[i] = elem);
							}
						}
					}) :
					function( elem, context, xml ) {
						input[0] = elem;
						matcher( input, null, xml, results );
						// Don't keep the element (issue #299)
						input[0] = null;
						return !results.pop();
					};
			}),
	
			"has": markFunction(function( selector ) {
				return function( elem ) {
					return Sizzle( selector, elem ).length > 0;
				};
			}),
	
			"contains": markFunction(function( text ) {
				text = text.replace( runescape, funescape );
				return function( elem ) {
					return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
				};
			}),
	
			// "Whether an element is represented by a :lang() selector
			// is based solely on the element's language value
			// being equal to the identifier C,
			// or beginning with the identifier C immediately followed by "-".
			// The matching of C against the element's language value is performed case-insensitively.
			// The identifier C does not have to be a valid language name."
			// http://www.w3.org/TR/selectors/#lang-pseudo
			"lang": markFunction( function( lang ) {
				// lang value must be a valid identifier
				if ( !ridentifier.test(lang || "") ) {
					Sizzle.error( "unsupported lang: " + lang );
				}
				lang = lang.replace( runescape, funescape ).toLowerCase();
				return function( elem ) {
					var elemLang;
					do {
						if ( (elemLang = documentIsHTML ?
							elem.lang :
							elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
	
							elemLang = elemLang.toLowerCase();
							return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
						}
					} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
					return false;
				};
			}),
	
			// Miscellaneous
			"target": function( elem ) {
				var hash = window.location && window.location.hash;
				return hash && hash.slice( 1 ) === elem.id;
			},
	
			"root": function( elem ) {
				return elem === docElem;
			},
	
			"focus": function( elem ) {
				return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
			},
	
			// Boolean properties
			"enabled": createDisabledPseudo( false ),
			"disabled": createDisabledPseudo( true ),
	
			"checked": function( elem ) {
				// In CSS3, :checked should return both checked and selected elements
				// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
				var nodeName = elem.nodeName.toLowerCase();
				return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
			},
	
			"selected": function( elem ) {
				// Accessing this property makes selected-by-default
				// options in Safari work properly
				if ( elem.parentNode ) {
					elem.parentNode.selectedIndex;
				}
	
				return elem.selected === true;
			},
	
			// Contents
			"empty": function( elem ) {
				// http://www.w3.org/TR/selectors/#empty-pseudo
				// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
				//   but not by others (comment: 8; processing instruction: 7; etc.)
				// nodeType < 6 works because attributes (2) do not appear as children
				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
					if ( elem.nodeType < 6 ) {
						return false;
					}
				}
				return true;
			},
	
			"parent": function( elem ) {
				return !Expr.pseudos["empty"]( elem );
			},
	
			// Element/input types
			"header": function( elem ) {
				return rheader.test( elem.nodeName );
			},
	
			"input": function( elem ) {
				return rinputs.test( elem.nodeName );
			},
	
			"button": function( elem ) {
				var name = elem.nodeName.toLowerCase();
				return name === "input" && elem.type === "button" || name === "button";
			},
	
			"text": function( elem ) {
				var attr;
				return elem.nodeName.toLowerCase() === "input" &&
					elem.type === "text" &&
	
					// Support: IE<8
					// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
					( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
			},
	
			// Position-in-collection
			"first": createPositionalPseudo(function() {
				return [ 0 ];
			}),
	
			"last": createPositionalPseudo(function( matchIndexes, length ) {
				return [ length - 1 ];
			}),
	
			"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
				return [ argument < 0 ? argument + length : argument ];
			}),
	
			"even": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 0;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"odd": createPositionalPseudo(function( matchIndexes, length ) {
				var i = 1;
				for ( ; i < length; i += 2 ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; --i >= 0; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			}),
	
			"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
				var i = argument < 0 ? argument + length : argument;
				for ( ; ++i < length; ) {
					matchIndexes.push( i );
				}
				return matchIndexes;
			})
		}
	};
	
	Expr.pseudos["nth"] = Expr.pseudos["eq"];
	
	// Add button/input type pseudos
	for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
		Expr.pseudos[ i ] = createInputPseudo( i );
	}
	for ( i in { submit: true, reset: true } ) {
		Expr.pseudos[ i ] = createButtonPseudo( i );
	}
	
	// Easy API for creating new setFilters
	function setFilters() {}
	setFilters.prototype = Expr.filters = Expr.pseudos;
	Expr.setFilters = new setFilters();
	
	tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
		var matched, match, tokens, type,
			soFar, groups, preFilters,
			cached = tokenCache[ selector + " " ];
	
		if ( cached ) {
			return parseOnly ? 0 : cached.slice( 0 );
		}
	
		soFar = selector;
		groups = [];
		preFilters = Expr.preFilter;
	
		while ( soFar ) {
	
			// Comma and first run
			if ( !matched || (match = rcomma.exec( soFar )) ) {
				if ( match ) {
					// Don't consume trailing commas as valid
					soFar = soFar.slice( match[0].length ) || soFar;
				}
				groups.push( (tokens = []) );
			}
	
			matched = false;
	
			// Combinators
			if ( (match = rcombinators.exec( soFar )) ) {
				matched = match.shift();
				tokens.push({
					value: matched,
					// Cast descendant combinators to space
					type: match[0].replace( rtrim, " " )
				});
				soFar = soFar.slice( matched.length );
			}
	
			// Filters
			for ( type in Expr.filter ) {
				if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
					(match = preFilters[ type ]( match ))) ) {
					matched = match.shift();
					tokens.push({
						value: matched,
						type: type,
						matches: match
					});
					soFar = soFar.slice( matched.length );
				}
			}
	
			if ( !matched ) {
				break;
			}
		}
	
		// Return the length of the invalid excess
		// if we're just parsing
		// Otherwise, throw an error or return tokens
		return parseOnly ?
			soFar.length :
			soFar ?
				Sizzle.error( selector ) :
				// Cache the tokens
				tokenCache( selector, groups ).slice( 0 );
	};
	
	function toSelector( tokens ) {
		var i = 0,
			len = tokens.length,
			selector = "";
		for ( ; i < len; i++ ) {
			selector += tokens[i].value;
		}
		return selector;
	}
	
	function addCombinator( matcher, combinator, base ) {
		var dir = combinator.dir,
			skip = combinator.next,
			key = skip || dir,
			checkNonElements = base && key === "parentNode",
			doneName = done++;
	
		return combinator.first ?
			// Check against closest ancestor/preceding element
			function( elem, context, xml ) {
				while ( (elem = elem[ dir ]) ) {
					if ( elem.nodeType === 1 || checkNonElements ) {
						return matcher( elem, context, xml );
					}
				}
				return false;
			} :
	
			// Check against all ancestor/preceding elements
			function( elem, context, xml ) {
				var oldCache, uniqueCache, outerCache,
					newCache = [ dirruns, doneName ];
	
				// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
				if ( xml ) {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							if ( matcher( elem, context, xml ) ) {
								return true;
							}
						}
					}
				} else {
					while ( (elem = elem[ dir ]) ) {
						if ( elem.nodeType === 1 || checkNonElements ) {
							outerCache = elem[ expando ] || (elem[ expando ] = {});
	
							// Support: IE <9 only
							// Defend against cloned attroperties (jQuery gh-1709)
							uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
	
							if ( skip && skip === elem.nodeName.toLowerCase() ) {
								elem = elem[ dir ] || elem;
							} else if ( (oldCache = uniqueCache[ key ]) &&
								oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
	
								// Assign to newCache so results back-propagate to previous elements
								return (newCache[ 2 ] = oldCache[ 2 ]);
							} else {
								// Reuse newcache so results back-propagate to previous elements
								uniqueCache[ key ] = newCache;
	
								// A match means we're done; a fail means we have to keep checking
								if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
									return true;
								}
							}
						}
					}
				}
				return false;
			};
	}
	
	function elementMatcher( matchers ) {
		return matchers.length > 1 ?
			function( elem, context, xml ) {
				var i = matchers.length;
				while ( i-- ) {
					if ( !matchers[i]( elem, context, xml ) ) {
						return false;
					}
				}
				return true;
			} :
			matchers[0];
	}
	
	function multipleContexts( selector, contexts, results ) {
		var i = 0,
			len = contexts.length;
		for ( ; i < len; i++ ) {
			Sizzle( selector, contexts[i], results );
		}
		return results;
	}
	
	function condense( unmatched, map, filter, context, xml ) {
		var elem,
			newUnmatched = [],
			i = 0,
			len = unmatched.length,
			mapped = map != null;
	
		for ( ; i < len; i++ ) {
			if ( (elem = unmatched[i]) ) {
				if ( !filter || filter( elem, context, xml ) ) {
					newUnmatched.push( elem );
					if ( mapped ) {
						map.push( i );
					}
				}
			}
		}
	
		return newUnmatched;
	}
	
	function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
		if ( postFilter && !postFilter[ expando ] ) {
			postFilter = setMatcher( postFilter );
		}
		if ( postFinder && !postFinder[ expando ] ) {
			postFinder = setMatcher( postFinder, postSelector );
		}
		return markFunction(function( seed, results, context, xml ) {
			var temp, i, elem,
				preMap = [],
				postMap = [],
				preexisting = results.length,
	
				// Get initial elements from seed or context
				elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
	
				// Prefilter to get matcher input, preserving a map for seed-results synchronization
				matcherIn = preFilter && ( seed || !selector ) ?
					condense( elems, preMap, preFilter, context, xml ) :
					elems,
	
				matcherOut = matcher ?
					// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
					postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
	
						// ...intermediate processing is necessary
						[] :
	
						// ...otherwise use results directly
						results :
					matcherIn;
	
			// Find primary matches
			if ( matcher ) {
				matcher( matcherIn, matcherOut, context, xml );
			}
	
			// Apply postFilter
			if ( postFilter ) {
				temp = condense( matcherOut, postMap );
				postFilter( temp, [], context, xml );
	
				// Un-match failing elements by moving them back to matcherIn
				i = temp.length;
				while ( i-- ) {
					if ( (elem = temp[i]) ) {
						matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
					}
				}
			}
	
			if ( seed ) {
				if ( postFinder || preFilter ) {
					if ( postFinder ) {
						// Get the final matcherOut by condensing this intermediate into postFinder contexts
						temp = [];
						i = matcherOut.length;
						while ( i-- ) {
							if ( (elem = matcherOut[i]) ) {
								// Restore matcherIn since elem is not yet a final match
								temp.push( (matcherIn[i] = elem) );
							}
						}
						postFinder( null, (matcherOut = []), temp, xml );
					}
	
					// Move matched elements from seed to results to keep them synchronized
					i = matcherOut.length;
					while ( i-- ) {
						if ( (elem = matcherOut[i]) &&
							(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
	
							seed[temp] = !(results[temp] = elem);
						}
					}
				}
	
			// Add elements to results, through postFinder if defined
			} else {
				matcherOut = condense(
					matcherOut === results ?
						matcherOut.splice( preexisting, matcherOut.length ) :
						matcherOut
				);
				if ( postFinder ) {
					postFinder( null, results, matcherOut, xml );
				} else {
					push.apply( results, matcherOut );
				}
			}
		});
	}
	
	function matcherFromTokens( tokens ) {
		var checkContext, matcher, j,
			len = tokens.length,
			leadingRelative = Expr.relative[ tokens[0].type ],
			implicitRelative = leadingRelative || Expr.relative[" "],
			i = leadingRelative ? 1 : 0,
	
			// The foundational matcher ensures that elements are reachable from top-level context(s)
			matchContext = addCombinator( function( elem ) {
				return elem === checkContext;
			}, implicitRelative, true ),
			matchAnyContext = addCombinator( function( elem ) {
				return indexOf( checkContext, elem ) > -1;
			}, implicitRelative, true ),
			matchers = [ function( elem, context, xml ) {
				var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
					(checkContext = context).nodeType ?
						matchContext( elem, context, xml ) :
						matchAnyContext( elem, context, xml ) );
				// Avoid hanging onto element (issue #299)
				checkContext = null;
				return ret;
			} ];
	
		for ( ; i < len; i++ ) {
			if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
				matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
			} else {
				matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
	
				// Return special upon seeing a positional matcher
				if ( matcher[ expando ] ) {
					// Find the next relative operator (if any) for proper handling
					j = ++i;
					for ( ; j < len; j++ ) {
						if ( Expr.relative[ tokens[j].type ] ) {
							break;
						}
					}
					return setMatcher(
						i > 1 && elementMatcher( matchers ),
						i > 1 && toSelector(
							// If the preceding token was a descendant combinator, insert an implicit any-element `*`
							tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
						).replace( rtrim, "$1" ),
						matcher,
						i < j && matcherFromTokens( tokens.slice( i, j ) ),
						j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
						j < len && toSelector( tokens )
					);
				}
				matchers.push( matcher );
			}
		}
	
		return elementMatcher( matchers );
	}
	
	function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
		var bySet = setMatchers.length > 0,
			byElement = elementMatchers.length > 0,
			superMatcher = function( seed, context, xml, results, outermost ) {
				var elem, j, matcher,
					matchedCount = 0,
					i = "0",
					unmatched = seed && [],
					setMatched = [],
					contextBackup = outermostContext,
					// We must always have either seed elements or outermost context
					elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
					// Use integer dirruns iff this is the outermost matcher
					dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
					len = elems.length;
	
				if ( outermost ) {
					outermostContext = context === document || context || outermost;
				}
	
				// Add elements passing elementMatchers directly to results
				// Support: IE<9, Safari
				// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
				for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
					if ( byElement && elem ) {
						j = 0;
						if ( !context && elem.ownerDocument !== document ) {
							setDocument( elem );
							xml = !documentIsHTML;
						}
						while ( (matcher = elementMatchers[j++]) ) {
							if ( matcher( elem, context || document, xml) ) {
								results.push( elem );
								break;
							}
						}
						if ( outermost ) {
							dirruns = dirrunsUnique;
						}
					}
	
					// Track unmatched elements for set filters
					if ( bySet ) {
						// They will have gone through all possible matchers
						if ( (elem = !matcher && elem) ) {
							matchedCount--;
						}
	
						// Lengthen the array for every element, matched or not
						if ( seed ) {
							unmatched.push( elem );
						}
					}
				}
	
				// `i` is now the count of elements visited above, and adding it to `matchedCount`
				// makes the latter nonnegative.
				matchedCount += i;
	
				// Apply set filters to unmatched elements
				// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
				// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
				// no element matchers and no seed.
				// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
				// case, which will result in a "00" `matchedCount` that differs from `i` but is also
				// numerically zero.
				if ( bySet && i !== matchedCount ) {
					j = 0;
					while ( (matcher = setMatchers[j++]) ) {
						matcher( unmatched, setMatched, context, xml );
					}
	
					if ( seed ) {
						// Reintegrate element matches to eliminate the need for sorting
						if ( matchedCount > 0 ) {
							while ( i-- ) {
								if ( !(unmatched[i] || setMatched[i]) ) {
									setMatched[i] = pop.call( results );
								}
							}
						}
	
						// Discard index placeholder values to get only actual matches
						setMatched = condense( setMatched );
					}
	
					// Add matches to results
					push.apply( results, setMatched );
	
					// Seedless set matches succeeding multiple successful matchers stipulate sorting
					if ( outermost && !seed && setMatched.length > 0 &&
						( matchedCount + setMatchers.length ) > 1 ) {
	
						Sizzle.uniqueSort( results );
					}
				}
	
				// Override manipulation of globals by nested matchers
				if ( outermost ) {
					dirruns = dirrunsUnique;
					outermostContext = contextBackup;
				}
	
				return unmatched;
			};
	
		return bySet ?
			markFunction( superMatcher ) :
			superMatcher;
	}
	
	compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
		var i,
			setMatchers = [],
			elementMatchers = [],
			cached = compilerCache[ selector + " " ];
	
		if ( !cached ) {
			// Generate a function of recursive functions that can be used to check each element
			if ( !match ) {
				match = tokenize( selector );
			}
			i = match.length;
			while ( i-- ) {
				cached = matcherFromTokens( match[i] );
				if ( cached[ expando ] ) {
					setMatchers.push( cached );
				} else {
					elementMatchers.push( cached );
				}
			}
	
			// Cache the compiled function
			cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
	
			// Save selector and tokenization
			cached.selector = selector;
		}
		return cached;
	};
	
	/**
	 * A low-level selection function that works with Sizzle's compiled
	 *  selector functions
	 * @param {String|Function} selector A selector or a pre-compiled
	 *  selector function built with Sizzle.compile
	 * @param {Element} context
	 * @param {Array} [results]
	 * @param {Array} [seed] A set of elements to match against
	 */
	select = Sizzle.select = function( selector, context, results, seed ) {
		var i, tokens, token, type, find,
			compiled = typeof selector === "function" && selector,
			match = !seed && tokenize( (selector = compiled.selector || selector) );
	
		results = results || [];
	
		// Try to minimize operations if there is only one selector in the list and no seed
		// (the latter of which guarantees us context)
		if ( match.length === 1 ) {
	
			// Reduce context if the leading compound selector is an ID
			tokens = match[0] = match[0].slice( 0 );
			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
					context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
	
				context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
				if ( !context ) {
					return results;
	
				// Precompiled matchers will still verify ancestry, so step up a level
				} else if ( compiled ) {
					context = context.parentNode;
				}
	
				selector = selector.slice( tokens.shift().value.length );
			}
	
			// Fetch a seed set for right-to-left matching
			i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
			while ( i-- ) {
				token = tokens[i];
	
				// Abort if we hit a combinator
				if ( Expr.relative[ (type = token.type) ] ) {
					break;
				}
				if ( (find = Expr.find[ type ]) ) {
					// Search, expanding context for leading sibling combinators
					if ( (seed = find(
						token.matches[0].replace( runescape, funescape ),
						rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
					)) ) {
	
						// If seed is empty or no tokens remain, we can return early
						tokens.splice( i, 1 );
						selector = seed.length && toSelector( tokens );
						if ( !selector ) {
							push.apply( results, seed );
							return results;
						}
	
						break;
					}
				}
			}
		}
	
		// Compile and execute a filtering function if one is not provided
		// Provide `match` to avoid retokenization if we modified the selector above
		( compiled || compile( selector, match ) )(
			seed,
			context,
			!documentIsHTML,
			results,
			!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
		);
		return results;
	};
	
	// One-time assignments
	
	// Sort stability
	support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
	
	// Support: Chrome 14-35+
	// Always assume duplicates if they aren't passed to the comparison function
	support.detectDuplicates = !!hasDuplicate;
	
	// Initialize against the default document
	setDocument();
	
	// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
	// Detached nodes confoundingly follow *each other*
	support.sortDetached = assert(function( el ) {
		// Should return 1, but returns 4 (following)
		return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
	});
	
	// Support: IE<8
	// Prevent attribute/property "interpolation"
	// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
	if ( !assert(function( el ) {
		el.innerHTML = "<a href='#'></a>";
		return el.firstChild.getAttribute("href") === "#" ;
	}) ) {
		addHandle( "type|href|height|width", function( elem, name, isXML ) {
			if ( !isXML ) {
				return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
			}
		});
	}
	
	// Support: IE<9
	// Use defaultValue in place of getAttribute("value")
	if ( !support.attributes || !assert(function( el ) {
		el.innerHTML = "<input/>";
		el.firstChild.setAttribute( "value", "" );
		return el.firstChild.getAttribute( "value" ) === "";
	}) ) {
		addHandle( "value", function( elem, name, isXML ) {
			if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
				return elem.defaultValue;
			}
		});
	}
	
	// Support: IE<9
	// Use getAttributeNode to fetch booleans when getAttribute lies
	if ( !assert(function( el ) {
		return el.getAttribute("disabled") == null;
	}) ) {
		addHandle( booleans, function( elem, name, isXML ) {
			var val;
			if ( !isXML ) {
				return elem[ name ] === true ? name.toLowerCase() :
						(val = elem.getAttributeNode( name )) && val.specified ?
						val.value :
					null;
			}
		});
	}
	
	return Sizzle;
	
	})( window );
	
	
	
	jQuery.find = Sizzle;
	jQuery.expr = Sizzle.selectors;
	
	// Deprecated
	jQuery.expr[ ":" ] = jQuery.expr.pseudos;
	jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
	jQuery.text = Sizzle.getText;
	jQuery.isXMLDoc = Sizzle.isXML;
	jQuery.contains = Sizzle.contains;
	jQuery.escapeSelector = Sizzle.escape;
	
	
	
	
	var dir = function( elem, dir, until ) {
		var matched = [],
			truncate = until !== undefined;
	
		while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
			if ( elem.nodeType === 1 ) {
				if ( truncate && jQuery( elem ).is( until ) ) {
					break;
				}
				matched.push( elem );
			}
		}
		return matched;
	};
	
	
	var siblings = function( n, elem ) {
		var matched = [];
	
		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				matched.push( n );
			}
		}
	
		return matched;
	};
	
	
	var rneedsContext = jQuery.expr.match.needsContext;
	
	
	
	function nodeName( elem, name ) {
	
	  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
	
	};
	var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
	
	
	
	var risSimple = /^.[^:#\[\.,]*$/;
	
	// Implement the identical functionality for filter and not
	function winnow( elements, qualifier, not ) {
		if ( jQuery.isFunction( qualifier ) ) {
			return jQuery.grep( elements, function( elem, i ) {
				return !!qualifier.call( elem, i, elem ) !== not;
			} );
		}
	
		// Single element
		if ( qualifier.nodeType ) {
			return jQuery.grep( elements, function( elem ) {
				return ( elem === qualifier ) !== not;
			} );
		}
	
		// Arraylike of elements (jQuery, arguments, Array)
		if ( typeof qualifier !== "string" ) {
			return jQuery.grep( elements, function( elem ) {
				return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
			} );
		}
	
		// Simple selector that can be filtered directly, removing non-Elements
		if ( risSimple.test( qualifier ) ) {
			return jQuery.filter( qualifier, elements, not );
		}
	
		// Complex selector, compare the two sets, removing non-Elements
		qualifier = jQuery.filter( qualifier, elements );
		return jQuery.grep( elements, function( elem ) {
			return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
		} );
	}
	
	jQuery.filter = function( expr, elems, not ) {
		var elem = elems[ 0 ];
	
		if ( not ) {
			expr = ":not(" + expr + ")";
		}
	
		if ( elems.length === 1 && elem.nodeType === 1 ) {
			return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
		}
	
		return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
			return elem.nodeType === 1;
		} ) );
	};
	
	jQuery.fn.extend( {
		find: function( selector ) {
			var i, ret,
				len = this.length,
				self = this;
	
			if ( typeof selector !== "string" ) {
				return this.pushStack( jQuery( selector ).filter( function() {
					for ( i = 0; i < len; i++ ) {
						if ( jQuery.contains( self[ i ], this ) ) {
							return true;
						}
					}
				} ) );
			}
	
			ret = this.pushStack( [] );
	
			for ( i = 0; i < len; i++ ) {
				jQuery.find( selector, self[ i ], ret );
			}
	
			return len > 1 ? jQuery.uniqueSort( ret ) : ret;
		},
		filter: function( selector ) {
			return this.pushStack( winnow( this, selector || [], false ) );
		},
		not: function( selector ) {
			return this.pushStack( winnow( this, selector || [], true ) );
		},
		is: function( selector ) {
			return !!winnow(
				this,
	
				// If this is a positional/relative selector, check membership in the returned set
				// so $("p:first").is("p:last") won't return true for a doc with two "p".
				typeof selector === "string" && rneedsContext.test( selector ) ?
					jQuery( selector ) :
					selector || [],
				false
			).length;
		}
	} );
	
	
	// Initialize a jQuery object
	
	
	// A central reference to the root jQuery(document)
	var rootjQuery,
	
		// A simple way to check for HTML strings
		// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
		// Strict HTML recognition (#11290: must start with <)
		// Shortcut simple #id case for speed
		rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
	
		init = jQuery.fn.init = function( selector, context, root ) {
			var match, elem;
	
			// HANDLE: $(""), $(null), $(undefined), $(false)
			if ( !selector ) {
				return this;
			}
	
			// Method init() accepts an alternate rootjQuery
			// so migrate can support jQuery.sub (gh-2101)
			root = root || rootjQuery;
	
			// Handle HTML strings
			if ( typeof selector === "string" ) {
				if ( selector[ 0 ] === "<" &&
					selector[ selector.length - 1 ] === ">" &&
					selector.length >= 3 ) {
	
					// Assume that strings that start and end with <> are HTML and skip the regex check
					match = [ null, selector, null ];
	
				} else {
					match = rquickExpr.exec( selector );
				}
	
				// Match html or make sure no context is specified for #id
				if ( match && ( match[ 1 ] || !context ) ) {
	
					// HANDLE: $(html) -> $(array)
					if ( match[ 1 ] ) {
						context = context instanceof jQuery ? context[ 0 ] : context;
	
						// Option to run scripts is true for back-compat
						// Intentionally let the error be thrown if parseHTML is not present
						jQuery.merge( this, jQuery.parseHTML(
							match[ 1 ],
							context && context.nodeType ? context.ownerDocument || context : document,
							true
						) );
	
						// HANDLE: $(html, props)
						if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
							for ( match in context ) {
	
								// Properties of context are called as methods if possible
								if ( jQuery.isFunction( this[ match ] ) ) {
									this[ match ]( context[ match ] );
	
								// ...and otherwise set as attributes
								} else {
									this.attr( match, context[ match ] );
								}
							}
						}
	
						return this;
	
					// HANDLE: $(#id)
					} else {
						elem = document.getElementById( match[ 2 ] );
	
						if ( elem ) {
	
							// Inject the element directly into the jQuery object
							this[ 0 ] = elem;
							this.length = 1;
						}
						return this;
					}
	
				// HANDLE: $(expr, $(...))
				} else if ( !context || context.jquery ) {
					return ( context || root ).find( selector );
	
				// HANDLE: $(expr, context)
				// (which is just equivalent to: $(context).find(expr)
				} else {
					return this.constructor( context ).find( selector );
				}
	
			// HANDLE: $(DOMElement)
			} else if ( selector.nodeType ) {
				this[ 0 ] = selector;
				this.length = 1;
				return this;
	
			// HANDLE: $(function)
			// Shortcut for document ready
			} else if ( jQuery.isFunction( selector ) ) {
				return root.ready !== undefined ?
					root.ready( selector ) :
	
					// Execute immediately if ready is not present
					selector( jQuery );
			}
	
			return jQuery.makeArray( selector, this );
		};
	
	// Give the init function the jQuery prototype for later instantiation
	init.prototype = jQuery.fn;
	
	// Initialize central reference
	rootjQuery = jQuery( document );
	
	
	var rparentsprev = /^(?:parents|prev(?:Until|All))/,
	
		// Methods guaranteed to produce a unique set when starting from a unique set
		guaranteedUnique = {
			children: true,
			contents: true,
			next: true,
			prev: true
		};
	
	jQuery.fn.extend( {
		has: function( target ) {
			var targets = jQuery( target, this ),
				l = targets.length;
	
			return this.filter( function() {
				var i = 0;
				for ( ; i < l; i++ ) {
					if ( jQuery.contains( this, targets[ i ] ) ) {
						return true;
					}
				}
			} );
		},
	
		closest: function( selectors, context ) {
			var cur,
				i = 0,
				l = this.length,
				matched = [],
				targets = typeof selectors !== "string" && jQuery( selectors );
	
			// Positional selectors never match, since there's no _selection_ context
			if ( !rneedsContext.test( selectors ) ) {
				for ( ; i < l; i++ ) {
					for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
	
						// Always skip document fragments
						if ( cur.nodeType < 11 && ( targets ?
							targets.index( cur ) > -1 :
	
							// Don't pass non-elements to Sizzle
							cur.nodeType === 1 &&
								jQuery.find.matchesSelector( cur, selectors ) ) ) {
	
							matched.push( cur );
							break;
						}
					}
				}
			}
	
			return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
		},
	
		// Determine the position of an element within the set
		index: function( elem ) {
	
			// No argument, return index in parent
			if ( !elem ) {
				return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
			}
	
			// Index in selector
			if ( typeof elem === "string" ) {
				return indexOf.call( jQuery( elem ), this[ 0 ] );
			}
	
			// Locate the position of the desired element
			return indexOf.call( this,
	
				// If it receives a jQuery object, the first element is used
				elem.jquery ? elem[ 0 ] : elem
			);
		},
	
		add: function( selector, context ) {
			return this.pushStack(
				jQuery.uniqueSort(
					jQuery.merge( this.get(), jQuery( selector, context ) )
				)
			);
		},
	
		addBack: function( selector ) {
			return this.add( selector == null ?
				this.prevObject : this.prevObject.filter( selector )
			);
		}
	} );
	
	function sibling( cur, dir ) {
		while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
		return cur;
	}
	
	jQuery.each( {
		parent: function( elem ) {
			var parent = elem.parentNode;
			return parent && parent.nodeType !== 11 ? parent : null;
		},
		parents: function( elem ) {
			return dir( elem, "parentNode" );
		},
		parentsUntil: function( elem, i, until ) {
			return dir( elem, "parentNode", until );
		},
		next: function( elem ) {
			return sibling( elem, "nextSibling" );
		},
		prev: function( elem ) {
			return sibling( elem, "previousSibling" );
		},
		nextAll: function( elem ) {
			return dir( elem, "nextSibling" );
		},
		prevAll: function( elem ) {
			return dir( elem, "previousSibling" );
		},
		nextUntil: function( elem, i, until ) {
			return dir( elem, "nextSibling", until );
		},
		prevUntil: function( elem, i, until ) {
			return dir( elem, "previousSibling", until );
		},
		siblings: function( elem ) {
			return siblings( ( elem.parentNode || {} ).firstChild, elem );
		},
		children: function( elem ) {
			return siblings( elem.firstChild );
		},
		contents: function( elem ) {
	        if ( nodeName( elem, "iframe" ) ) {
	            return elem.contentDocument;
	        }
	
	        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
	        // Treat the template element as a regular one in browsers that
	        // don't support it.
	        if ( nodeName( elem, "template" ) ) {
	            elem = elem.content || elem;
	        }
	
	        return jQuery.merge( [], elem.childNodes );
		}
	}, function( name, fn ) {
		jQuery.fn[ name ] = function( until, selector ) {
			var matched = jQuery.map( this, fn, until );
	
			if ( name.slice( -5 ) !== "Until" ) {
				selector = until;
			}
	
			if ( selector && typeof selector === "string" ) {
				matched = jQuery.filter( selector, matched );
			}
	
			if ( this.length > 1 ) {
	
				// Remove duplicates
				if ( !guaranteedUnique[ name ] ) {
					jQuery.uniqueSort( matched );
				}
	
				// Reverse order for parents* and prev-derivatives
				if ( rparentsprev.test( name ) ) {
					matched.reverse();
				}
			}
	
			return this.pushStack( matched );
		};
	} );
	var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
	
	
	
	// Convert String-formatted options into Object-formatted ones
	function createOptions( options ) {
		var object = {};
		jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
			object[ flag ] = true;
		} );
		return object;
	}
	
	/*
	 * Create a callback list using the following parameters:
	 *
	 *	options: an optional list of space-separated options that will change how
	 *			the callback list behaves or a more traditional option object
	 *
	 * By default a callback list will act like an event callback list and can be
	 * "fired" multiple times.
	 *
	 * Possible options:
	 *
	 *	once:			will ensure the callback list can only be fired once (like a Deferred)
	 *
	 *	memory:			will keep track of previous values and will call any callback added
	 *					after the list has been fired right away with the latest "memorized"
	 *					values (like a Deferred)
	 *
	 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
	 *
	 *	stopOnFalse:	interrupt callings when a callback returns false
	 *
	 */
	jQuery.Callbacks = function( options ) {
	
		// Convert options from String-formatted to Object-formatted if needed
		// (we check in cache first)
		options = typeof options === "string" ?
			createOptions( options ) :
			jQuery.extend( {}, options );
	
		var // Flag to know if list is currently firing
			firing,
	
			// Last fire value for non-forgettable lists
			memory,
	
			// Flag to know if list was already fired
			fired,
	
			// Flag to prevent firing
			locked,
	
			// Actual callback list
			list = [],
	
			// Queue of execution data for repeatable lists
			queue = [],
	
			// Index of currently firing callback (modified by add/remove as needed)
			firingIndex = -1,
	
			// Fire callbacks
			fire = function() {
	
				// Enforce single-firing
				locked = locked || options.once;
	
				// Execute callbacks for all pending executions,
				// respecting firingIndex overrides and runtime changes
				fired = firing = true;
				for ( ; queue.length; firingIndex = -1 ) {
					memory = queue.shift();
					while ( ++firingIndex < list.length ) {
	
						// Run callback and check for early termination
						if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
							options.stopOnFalse ) {
	
							// Jump to end and forget the data so .add doesn't re-fire
							firingIndex = list.length;
							memory = false;
						}
					}
				}
	
				// Forget the data if we're done with it
				if ( !options.memory ) {
					memory = false;
				}
	
				firing = false;
	
				// Clean up if we're done firing for good
				if ( locked ) {
	
					// Keep an empty list if we have data for future add calls
					if ( memory ) {
						list = [];
	
					// Otherwise, this object is spent
					} else {
						list = "";
					}
				}
			},
	
			// Actual Callbacks object
			self = {
	
				// Add a callback or a collection of callbacks to the list
				add: function() {
					if ( list ) {
	
						// If we have memory from a past run, we should fire after adding
						if ( memory && !firing ) {
							firingIndex = list.length - 1;
							queue.push( memory );
						}
	
						( function add( args ) {
							jQuery.each( args, function( _, arg ) {
								if ( jQuery.isFunction( arg ) ) {
									if ( !options.unique || !self.has( arg ) ) {
										list.push( arg );
									}
								} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
	
									// Inspect recursively
									add( arg );
								}
							} );
						} )( arguments );
	
						if ( memory && !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Remove a callback from the list
				remove: function() {
					jQuery.each( arguments, function( _, arg ) {
						var index;
						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
							list.splice( index, 1 );
	
							// Handle firing indexes
							if ( index <= firingIndex ) {
								firingIndex--;
							}
						}
					} );
					return this;
				},
	
				// Check if a given callback is in the list.
				// If no argument is given, return whether or not list has callbacks attached.
				has: function( fn ) {
					return fn ?
						jQuery.inArray( fn, list ) > -1 :
						list.length > 0;
				},
	
				// Remove all callbacks from the list
				empty: function() {
					if ( list ) {
						list = [];
					}
					return this;
				},
	
				// Disable .fire and .add
				// Abort any current/pending executions
				// Clear all callbacks and values
				disable: function() {
					locked = queue = [];
					list = memory = "";
					return this;
				},
				disabled: function() {
					return !list;
				},
	
				// Disable .fire
				// Also disable .add unless we have memory (since it would have no effect)
				// Abort any pending executions
				lock: function() {
					locked = queue = [];
					if ( !memory && !firing ) {
						list = memory = "";
					}
					return this;
				},
				locked: function() {
					return !!locked;
				},
	
				// Call all callbacks with the given context and arguments
				fireWith: function( context, args ) {
					if ( !locked ) {
						args = args || [];
						args = [ context, args.slice ? args.slice() : args ];
						queue.push( args );
						if ( !firing ) {
							fire();
						}
					}
					return this;
				},
	
				// Call all the callbacks with the given arguments
				fire: function() {
					self.fireWith( this, arguments );
					return this;
				},
	
				// To know if the callbacks have already been called at least once
				fired: function() {
					return !!fired;
				}
			};
	
		return self;
	};
	
	
	function Identity( v ) {
		return v;
	}
	function Thrower( ex ) {
		throw ex;
	}
	
	function adoptValue( value, resolve, reject, noValue ) {
		var method;
	
		try {
	
			// Check for promise aspect first to privilege synchronous behavior
			if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
				method.call( value ).done( resolve ).fail( reject );
	
			// Other thenables
			} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
				method.call( value, resolve, reject );
	
			// Other non-thenables
			} else {
	
				// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
				// * false: [ value ].slice( 0 ) => resolve( value )
				// * true: [ value ].slice( 1 ) => resolve()
				resolve.apply( undefined, [ value ].slice( noValue ) );
			}
	
		// For Promises/A+, convert exceptions into rejections
		// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
		// Deferred#then to conditionally suppress rejection.
		} catch ( value ) {
	
			// Support: Android 4.0 only
			// Strict mode functions invoked without .call/.apply get global-object context
			reject.apply( undefined, [ value ] );
		}
	}
	
	jQuery.extend( {
	
		Deferred: function( func ) {
			var tuples = [
	
					// action, add listener, callbacks,
					// ... .then handlers, argument index, [final state]
					[ "notify", "progress", jQuery.Callbacks( "memory" ),
						jQuery.Callbacks( "memory" ), 2 ],
					[ "resolve", "done", jQuery.Callbacks( "once memory" ),
						jQuery.Callbacks( "once memory" ), 0, "resolved" ],
					[ "reject", "fail", jQuery.Callbacks( "once memory" ),
						jQuery.Callbacks( "once memory" ), 1, "rejected" ]
				],
				state = "pending",
				promise = {
					state: function() {
						return state;
					},
					always: function() {
						deferred.done( arguments ).fail( arguments );
						return this;
					},
					"catch": function( fn ) {
						return promise.then( null, fn );
					},
	
					// Keep pipe for back-compat
					pipe: function( /* fnDone, fnFail, fnProgress */ ) {
						var fns = arguments;
	
						return jQuery.Deferred( function( newDefer ) {
							jQuery.each( tuples, function( i, tuple ) {
	
								// Map tuples (progress, done, fail) to arguments (done, fail, progress)
								var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
	
								// deferred.progress(function() { bind to newDefer or newDefer.notify })
								// deferred.done(function() { bind to newDefer or newDefer.resolve })
								// deferred.fail(function() { bind to newDefer or newDefer.reject })
								deferred[ tuple[ 1 ] ]( function() {
									var returned = fn && fn.apply( this, arguments );
									if ( returned && jQuery.isFunction( returned.promise ) ) {
										returned.promise()
											.progress( newDefer.notify )
											.done( newDefer.resolve )
											.fail( newDefer.reject );
									} else {
										newDefer[ tuple[ 0 ] + "With" ](
											this,
											fn ? [ returned ] : arguments
										);
									}
								} );
							} );
							fns = null;
						} ).promise();
					},
					then: function( onFulfilled, onRejected, onProgress ) {
						var maxDepth = 0;
						function resolve( depth, deferred, handler, special ) {
							return function() {
								var that = this,
									args = arguments,
									mightThrow = function() {
										var returned, then;
	
										// Support: Promises/A+ section 2.3.3.3.3
										// https://promisesaplus.com/#point-59
										// Ignore double-resolution attempts
										if ( depth < maxDepth ) {
											return;
										}
	
										returned = handler.apply( that, args );
	
										// Support: Promises/A+ section 2.3.1
										// https://promisesaplus.com/#point-48
										if ( returned === deferred.promise() ) {
											throw new TypeError( "Thenable self-resolution" );
										}
	
										// Support: Promises/A+ sections 2.3.3.1, 3.5
										// https://promisesaplus.com/#point-54
										// https://promisesaplus.com/#point-75
										// Retrieve `then` only once
										then = returned &&
	
											// Support: Promises/A+ section 2.3.4
											// https://promisesaplus.com/#point-64
											// Only check objects and functions for thenability
											( typeof returned === "object" ||
												typeof returned === "function" ) &&
											returned.then;
	
										// Handle a returned thenable
										if ( jQuery.isFunction( then ) ) {
	
											// Special processors (notify) just wait for resolution
											if ( special ) {
												then.call(
													returned,
													resolve( maxDepth, deferred, Identity, special ),
													resolve( maxDepth, deferred, Thrower, special )
												);
	
											// Normal processors (resolve) also hook into progress
											} else {
	
												// ...and disregard older resolution values
												maxDepth++;
	
												then.call(
													returned,
													resolve( maxDepth, deferred, Identity, special ),
													resolve( maxDepth, deferred, Thrower, special ),
													resolve( maxDepth, deferred, Identity,
														deferred.notifyWith )
												);
											}
	
										// Handle all other returned values
										} else {
	
											// Only substitute handlers pass on context
											// and multiple values (non-spec behavior)
											if ( handler !== Identity ) {
												that = undefined;
												args = [ returned ];
											}
	
											// Process the value(s)
											// Default process is resolve
											( special || deferred.resolveWith )( that, args );
										}
									},
	
									// Only normal processors (resolve) catch and reject exceptions
									process = special ?
										mightThrow :
										function() {
											try {
												mightThrow();
											} catch ( e ) {
	
												if ( jQuery.Deferred.exceptionHook ) {
													jQuery.Deferred.exceptionHook( e,
														process.stackTrace );
												}
	
												// Support: Promises/A+ section 2.3.3.3.4.1
												// https://promisesaplus.com/#point-61
												// Ignore post-resolution exceptions
												if ( depth + 1 >= maxDepth ) {
	
													// Only substitute handlers pass on context
													// and multiple values (non-spec behavior)
													if ( handler !== Thrower ) {
														that = undefined;
														args = [ e ];
													}
	
													deferred.rejectWith( that, args );
												}
											}
										};
	
								// Support: Promises/A+ section 2.3.3.3.1
								// https://promisesaplus.com/#point-57
								// Re-resolve promises immediately to dodge false rejection from
								// subsequent errors
								if ( depth ) {
									process();
								} else {
	
									// Call an optional hook to record the stack, in case of exception
									// since it's otherwise lost when execution goes async
									if ( jQuery.Deferred.getStackHook ) {
										process.stackTrace = jQuery.Deferred.getStackHook();
									}
									window.setTimeout( process );
								}
							};
						}
	
						return jQuery.Deferred( function( newDefer ) {
	
							// progress_handlers.add( ... )
							tuples[ 0 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onProgress ) ?
										onProgress :
										Identity,
									newDefer.notifyWith
								)
							);
	
							// fulfilled_handlers.add( ... )
							tuples[ 1 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onFulfilled ) ?
										onFulfilled :
										Identity
								)
							);
	
							// rejected_handlers.add( ... )
							tuples[ 2 ][ 3 ].add(
								resolve(
									0,
									newDefer,
									jQuery.isFunction( onRejected ) ?
										onRejected :
										Thrower
								)
							);
						} ).promise();
					},
	
					// Get a promise for this deferred
					// If obj is provided, the promise aspect is added to the object
					promise: function( obj ) {
						return obj != null ? jQuery.extend( obj, promise ) : promise;
					}
				},
				deferred = {};
	
			// Add list-specific methods
			jQuery.each( tuples, function( i, tuple ) {
				var list = tuple[ 2 ],
					stateString = tuple[ 5 ];
	
				// promise.progress = list.add
				// promise.done = list.add
				// promise.fail = list.add
				promise[ tuple[ 1 ] ] = list.add;
	
				// Handle state
				if ( stateString ) {
					list.add(
						function() {
	
							// state = "resolved" (i.e., fulfilled)
							// state = "rejected"
							state = stateString;
						},
	
						// rejected_callbacks.disable
						// fulfilled_callbacks.disable
						tuples[ 3 - i ][ 2 ].disable,
	
						// progress_callbacks.lock
						tuples[ 0 ][ 2 ].lock
					);
				}
	
				// progress_handlers.fire
				// fulfilled_handlers.fire
				// rejected_handlers.fire
				list.add( tuple[ 3 ].fire );
	
				// deferred.notify = function() { deferred.notifyWith(...) }
				// deferred.resolve = function() { deferred.resolveWith(...) }
				// deferred.reject = function() { deferred.rejectWith(...) }
				deferred[ tuple[ 0 ] ] = function() {
					deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
					return this;
				};
	
				// deferred.notifyWith = list.fireWith
				// deferred.resolveWith = list.fireWith
				// deferred.rejectWith = list.fireWith
				deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
			} );
	
			// Make the deferred a promise
			promise.promise( deferred );
	
			// Call given func if any
			if ( func ) {
				func.call( deferred, deferred );
			}
	
			// All done!
			return deferred;
		},
	
		// Deferred helper
		when: function( singleValue ) {
			var
	
				// count of uncompleted subordinates
				remaining = arguments.length,
	
				// count of unprocessed arguments
				i = remaining,
	
				// subordinate fulfillment data
				resolveContexts = Array( i ),
				resolveValues = slice.call( arguments ),
	
				// the master Deferred
				master = jQuery.Deferred(),
	
				// subordinate callback factory
				updateFunc = function( i ) {
					return function( value ) {
						resolveContexts[ i ] = this;
						resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
						if ( !( --remaining ) ) {
							master.resolveWith( resolveContexts, resolveValues );
						}
					};
				};
	
			// Single- and empty arguments are adopted like Promise.resolve
			if ( remaining <= 1 ) {
				adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
					!remaining );
	
				// Use .then() to unwrap secondary thenables (cf. gh-3000)
				if ( master.state() === "pending" ||
					jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
	
					return master.then();
				}
			}
	
			// Multiple arguments are aggregated like Promise.all array elements
			while ( i-- ) {
				adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
			}
	
			return master.promise();
		}
	} );
	
	
	// These usually indicate a programmer mistake during development,
	// warn about them ASAP rather than swallowing them by default.
	var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
	
	jQuery.Deferred.exceptionHook = function( error, stack ) {
	
		// Support: IE 8 - 9 only
		// Console exists when dev tools are open, which can happen at any time
		if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
			window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
		}
	};
	
	
	
	
	jQuery.readyException = function( error ) {
		window.setTimeout( function() {
			throw error;
		} );
	};
	
	
	
	
	// The deferred used on DOM ready
	var readyList = jQuery.Deferred();
	
	jQuery.fn.ready = function( fn ) {
	
		readyList
			.then( fn )
	
			// Wrap jQuery.readyException in a function so that the lookup
			// happens at the time of error handling instead of callback
			// registration.
			.catch( function( error ) {
				jQuery.readyException( error );
			} );
	
		return this;
	};
	
	jQuery.extend( {
	
		// Is the DOM ready to be used? Set to true once it occurs.
		isReady: false,
	
		// A counter to track how many items to wait for before
		// the ready event fires. See #6781
		readyWait: 1,
	
		// Handle when the DOM is ready
		ready: function( wait ) {
	
			// Abort if there are pending holds or we're already ready
			if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
				return;
			}
	
			// Remember that the DOM is ready
			jQuery.isReady = true;
	
			// If a normal DOM Ready event fired, decrement, and wait if need be
			if ( wait !== true && --jQuery.readyWait > 0 ) {
				return;
			}
	
			// If there are functions bound, to execute
			readyList.resolveWith( document, [ jQuery ] );
		}
	} );
	
	jQuery.ready.then = readyList.then;
	
	// The ready event handler and self cleanup method
	function completed() {
		document.removeEventListener( "DOMContentLoaded", completed );
		window.removeEventListener( "load", completed );
		jQuery.ready();
	}
	
	// Catch cases where $(document).ready() is called
	// after the browser event has already occurred.
	// Support: IE <=9 - 10 only
	// Older IE sometimes signals "interactive" too soon
	if ( document.readyState === "complete" ||
		( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
	
		// Handle it asynchronously to allow scripts the opportunity to delay ready
		window.setTimeout( jQuery.ready );
	
	} else {
	
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", completed );
	
		// A fallback to window.onload, that will always work
		window.addEventListener( "load", completed );
	}
	
	
	
	
	// Multifunctional method to get and set values of a collection
	// The value/s can optionally be executed if it's a function
	var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
		var i = 0,
			len = elems.length,
			bulk = key == null;
	
		// Sets many values
		if ( jQuery.type( key ) === "object" ) {
			chainable = true;
			for ( i in key ) {
				access( elems, fn, i, key[ i ], true, emptyGet, raw );
			}
	
		// Sets one value
		} else if ( value !== undefined ) {
			chainable = true;
	
			if ( !jQuery.isFunction( value ) ) {
				raw = true;
			}
	
			if ( bulk ) {
	
				// Bulk operations run against the entire set
				if ( raw ) {
					fn.call( elems, value );
					fn = null;
	
				// ...except when executing function values
				} else {
					bulk = fn;
					fn = function( elem, key, value ) {
						return bulk.call( jQuery( elem ), value );
					};
				}
			}
	
			if ( fn ) {
				for ( ; i < len; i++ ) {
					fn(
						elems[ i ], key, raw ?
						value :
						value.call( elems[ i ], i, fn( elems[ i ], key ) )
					);
				}
			}
		}
	
		if ( chainable ) {
			return elems;
		}
	
		// Gets
		if ( bulk ) {
			return fn.call( elems );
		}
	
		return len ? fn( elems[ 0 ], key ) : emptyGet;
	};
	var acceptData = function( owner ) {
	
		// Accepts only:
		//  - Node
		//    - Node.ELEMENT_NODE
		//    - Node.DOCUMENT_NODE
		//  - Object
		//    - Any
		return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
	};
	
	
	
	
	function Data() {
		this.expando = jQuery.expando + Data.uid++;
	}
	
	Data.uid = 1;
	
	Data.prototype = {
	
		cache: function( owner ) {
	
			// Check if the owner object already has a cache
			var value = owner[ this.expando ];
	
			// If not, create one
			if ( !value ) {
				value = {};
	
				// We can accept data for non-element nodes in modern browsers,
				// but we should not, see #8335.
				// Always return an empty object.
				if ( acceptData( owner ) ) {
	
					// If it is a node unlikely to be stringify-ed or looped over
					// use plain assignment
					if ( owner.nodeType ) {
						owner[ this.expando ] = value;
	
					// Otherwise secure it in a non-enumerable property
					// configurable must be true to allow the property to be
					// deleted when data is removed
					} else {
						Object.defineProperty( owner, this.expando, {
							value: value,
							configurable: true
						} );
					}
				}
			}
	
			return value;
		},
		set: function( owner, data, value ) {
			var prop,
				cache = this.cache( owner );
	
			// Handle: [ owner, key, value ] args
			// Always use camelCase key (gh-2257)
			if ( typeof data === "string" ) {
				cache[ jQuery.camelCase( data ) ] = value;
	
			// Handle: [ owner, { properties } ] args
			} else {
	
				// Copy the properties one-by-one to the cache object
				for ( prop in data ) {
					cache[ jQuery.camelCase( prop ) ] = data[ prop ];
				}
			}
			return cache;
		},
		get: function( owner, key ) {
			return key === undefined ?
				this.cache( owner ) :
	
				// Always use camelCase key (gh-2257)
				owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
		},
		access: function( owner, key, value ) {
	
			// In cases where either:
			//
			//   1. No key was specified
			//   2. A string key was specified, but no value provided
			//
			// Take the "read" path and allow the get method to determine
			// which value to return, respectively either:
			//
			//   1. The entire cache object
			//   2. The data stored at the key
			//
			if ( key === undefined ||
					( ( key && typeof key === "string" ) && value === undefined ) ) {
	
				return this.get( owner, key );
			}
	
			// When the key is not a string, or both a key and value
			// are specified, set or extend (existing objects) with either:
			//
			//   1. An object of properties
			//   2. A key and value
			//
			this.set( owner, key, value );
	
			// Since the "set" path can have two possible entry points
			// return the expected data based on which path was taken[*]
			return value !== undefined ? value : key;
		},
		remove: function( owner, key ) {
			var i,
				cache = owner[ this.expando ];
	
			if ( cache === undefined ) {
				return;
			}
	
			if ( key !== undefined ) {
	
				// Support array or space separated string of keys
				if ( Array.isArray( key ) ) {
	
					// If key is an array of keys...
					// We always set camelCase keys, so remove that.
					key = key.map( jQuery.camelCase );
				} else {
					key = jQuery.camelCase( key );
	
					// If a key with the spaces exists, use it.
					// Otherwise, create an array by matching non-whitespace
					key = key in cache ?
						[ key ] :
						( key.match( rnothtmlwhite ) || [] );
				}
	
				i = key.length;
	
				while ( i-- ) {
					delete cache[ key[ i ] ];
				}
			}
	
			// Remove the expando if there's no more data
			if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
	
				// Support: Chrome <=35 - 45
				// Webkit & Blink performance suffers when deleting properties
				// from DOM nodes, so set to undefined instead
				// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
				if ( owner.nodeType ) {
					owner[ this.expando ] = undefined;
				} else {
					delete owner[ this.expando ];
				}
			}
		},
		hasData: function( owner ) {
			var cache = owner[ this.expando ];
			return cache !== undefined && !jQuery.isEmptyObject( cache );
		}
	};
	var dataPriv = new Data();
	
	var dataUser = new Data();
	
	
	
	//	Implementation Summary
	//
	//	1. Enforce API surface and semantic compatibility with 1.9.x branch
	//	2. Improve the module's maintainability by reducing the storage
	//		paths to a single mechanism.
	//	3. Use the same single mechanism to support "private" and "user" data.
	//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
	//	5. Avoid exposing implementation details on user objects (eg. expando properties)
	//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
	
	var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
		rmultiDash = /[A-Z]/g;
	
	function getData( data ) {
		if ( data === "true" ) {
			return true;
		}
	
		if ( data === "false" ) {
			return false;
		}
	
		if ( data === "null" ) {
			return null;
		}
	
		// Only convert to a number if it doesn't change the string
		if ( data === +data + "" ) {
			return +data;
		}
	
		if ( rbrace.test( data ) ) {
			return JSON.parse( data );
		}
	
		return data;
	}
	
	function dataAttr( elem, key, data ) {
		var name;
	
		// If nothing was found internally, try to fetch any
		// data from the HTML5 data-* attribute
		if ( data === undefined && elem.nodeType === 1 ) {
			name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
			data = elem.getAttribute( name );
	
			if ( typeof data === "string" ) {
				try {
					data = getData( data );
				} catch ( e ) {}
	
				// Make sure we set the data so it isn't changed later
				dataUser.set( elem, key, data );
			} else {
				data = undefined;
			}
		}
		return data;
	}
	
	jQuery.extend( {
		hasData: function( elem ) {
			return dataUser.hasData( elem ) || dataPriv.hasData( elem );
		},
	
		data: function( elem, name, data ) {
			return dataUser.access( elem, name, data );
		},
	
		removeData: function( elem, name ) {
			dataUser.remove( elem, name );
		},
	
		// TODO: Now that all calls to _data and _removeData have been replaced
		// with direct calls to dataPriv methods, these can be deprecated.
		_data: function( elem, name, data ) {
			return dataPriv.access( elem, name, data );
		},
	
		_removeData: function( elem, name ) {
			dataPriv.remove( elem, name );
		}
	} );
	
	jQuery.fn.extend( {
		data: function( key, value ) {
			var i, name, data,
				elem = this[ 0 ],
				attrs = elem && elem.attributes;
	
			// Gets all values
			if ( key === undefined ) {
				if ( this.length ) {
					data = dataUser.get( elem );
	
					if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
						i = attrs.length;
						while ( i-- ) {
	
							// Support: IE 11 only
							// The attrs elements can be null (#14894)
							if ( attrs[ i ] ) {
								name = attrs[ i ].name;
								if ( name.indexOf( "data-" ) === 0 ) {
									name = jQuery.camelCase( name.slice( 5 ) );
									dataAttr( elem, name, data[ name ] );
								}
							}
						}
						dataPriv.set( elem, "hasDataAttrs", true );
					}
				}
	
				return data;
			}
	
			// Sets multiple values
			if ( typeof key === "object" ) {
				return this.each( function() {
					dataUser.set( this, key );
				} );
			}
	
			return access( this, function( value ) {
				var data;
	
				// The calling jQuery object (element matches) is not empty
				// (and therefore has an element appears at this[ 0 ]) and the
				// `value` parameter was not undefined. An empty jQuery object
				// will result in `undefined` for elem = this[ 0 ] which will
				// throw an exception if an attempt to read a data cache is made.
				if ( elem && value === undefined ) {
	
					// Attempt to get data from the cache
					// The key will always be camelCased in Data
					data = dataUser.get( elem, key );
					if ( data !== undefined ) {
						return data;
					}
	
					// Attempt to "discover" the data in
					// HTML5 custom data-* attrs
					data = dataAttr( elem, key );
					if ( data !== undefined ) {
						return data;
					}
	
					// We tried really hard, but the data doesn't exist.
					return;
				}
	
				// Set the data...
				this.each( function() {
	
					// We always store the camelCased key
					dataUser.set( this, key, value );
				} );
			}, null, value, arguments.length > 1, null, true );
		},
	
		removeData: function( key ) {
			return this.each( function() {
				dataUser.remove( this, key );
			} );
		}
	} );
	
	
	jQuery.extend( {
		queue: function( elem, type, data ) {
			var queue;
	
			if ( elem ) {
				type = ( type || "fx" ) + "queue";
				queue = dataPriv.get( elem, type );
	
				// Speed up dequeue by getting out quickly if this is just a lookup
				if ( data ) {
					if ( !queue || Array.isArray( data ) ) {
						queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
					} else {
						queue.push( data );
					}
				}
				return queue || [];
			}
		},
	
		dequeue: function( elem, type ) {
			type = type || "fx";
	
			var queue = jQuery.queue( elem, type ),
				startLength = queue.length,
				fn = queue.shift(),
				hooks = jQuery._queueHooks( elem, type ),
				next = function() {
					jQuery.dequeue( elem, type );
				};
	
			// If the fx queue is dequeued, always remove the progress sentinel
			if ( fn === "inprogress" ) {
				fn = queue.shift();
				startLength--;
			}
	
			if ( fn ) {
	
				// Add a progress sentinel to prevent the fx queue from being
				// automatically dequeued
				if ( type === "fx" ) {
					queue.unshift( "inprogress" );
				}
	
				// Clear up the last queue stop function
				delete hooks.stop;
				fn.call( elem, next, hooks );
			}
	
			if ( !startLength && hooks ) {
				hooks.empty.fire();
			}
		},
	
		// Not public - generate a queueHooks object, or return the current one
		_queueHooks: function( elem, type ) {
			var key = type + "queueHooks";
			return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
				empty: jQuery.Callbacks( "once memory" ).add( function() {
					dataPriv.remove( elem, [ type + "queue", key ] );
				} )
			} );
		}
	} );
	
	jQuery.fn.extend( {
		queue: function( type, data ) {
			var setter = 2;
	
			if ( typeof type !== "string" ) {
				data = type;
				type = "fx";
				setter--;
			}
	
			if ( arguments.length < setter ) {
				return jQuery.queue( this[ 0 ], type );
			}
	
			return data === undefined ?
				this :
				this.each( function() {
					var queue = jQuery.queue( this, type, data );
	
					// Ensure a hooks for this queue
					jQuery._queueHooks( this, type );
	
					if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
						jQuery.dequeue( this, type );
					}
				} );
		},
		dequeue: function( type ) {
			return this.each( function() {
				jQuery.dequeue( this, type );
			} );
		},
		clearQueue: function( type ) {
			return this.queue( type || "fx", [] );
		},
	
		// Get a promise resolved when queues of a certain type
		// are emptied (fx is the type by default)
		promise: function( type, obj ) {
			var tmp,
				count = 1,
				defer = jQuery.Deferred(),
				elements = this,
				i = this.length,
				resolve = function() {
					if ( !( --count ) ) {
						defer.resolveWith( elements, [ elements ] );
					}
				};
	
			if ( typeof type !== "string" ) {
				obj = type;
				type = undefined;
			}
			type = type || "fx";
	
			while ( i-- ) {
				tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
				if ( tmp && tmp.empty ) {
					count++;
					tmp.empty.add( resolve );
				}
			}
			resolve();
			return defer.promise( obj );
		}
	} );
	var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
	
	var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
	
	
	var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
	
	var isHiddenWithinTree = function( elem, el ) {
	
			// isHiddenWithinTree might be called from jQuery#filter function;
			// in that case, element will be second argument
			elem = el || elem;
	
			// Inline style trumps all
			return elem.style.display === "none" ||
				elem.style.display === "" &&
	
				// Otherwise, check computed style
				// Support: Firefox <=43 - 45
				// Disconnected elements can have computed display: none, so first confirm that elem is
				// in the document.
				jQuery.contains( elem.ownerDocument, elem ) &&
	
				jQuery.css( elem, "display" ) === "none";
		};
	
	var swap = function( elem, options, callback, args ) {
		var ret, name,
			old = {};
	
		// Remember the old values, and insert the new ones
		for ( name in options ) {
			old[ name ] = elem.style[ name ];
			elem.style[ name ] = options[ name ];
		}
	
		ret = callback.apply( elem, args || [] );
	
		// Revert the old values
		for ( name in options ) {
			elem.style[ name ] = old[ name ];
		}
	
		return ret;
	};
	
	
	
	
	function adjustCSS( elem, prop, valueParts, tween ) {
		var adjusted,
			scale = 1,
			maxIterations = 20,
			currentValue = tween ?
				function() {
					return tween.cur();
				} :
				function() {
					return jQuery.css( elem, prop, "" );
				},
			initial = currentValue(),
			unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
	
			// Starting value computation is required for potential unit mismatches
			initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
				rcssNum.exec( jQuery.css( elem, prop ) );
	
		if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
	
			// Trust units reported by jQuery.css
			unit = unit || initialInUnit[ 3 ];
	
			// Make sure we update the tween properties later on
			valueParts = valueParts || [];
	
			// Iteratively approximate from a nonzero starting point
			initialInUnit = +initial || 1;
	
			do {
	
				// If previous iteration zeroed out, double until we get *something*.
				// Use string for doubling so we don't accidentally see scale as unchanged below
				scale = scale || ".5";
	
				// Adjust and apply
				initialInUnit = initialInUnit / scale;
				jQuery.style( elem, prop, initialInUnit + unit );
	
			// Update scale, tolerating zero or NaN from tween.cur()
			// Break the loop if scale is unchanged or perfect, or if we've just had enough.
			} while (
				scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
			);
		}
	
		if ( valueParts ) {
			initialInUnit = +initialInUnit || +initial || 0;
	
			// Apply relative offset (+=/-=) if specified
			adjusted = valueParts[ 1 ] ?
				initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
				+valueParts[ 2 ];
			if ( tween ) {
				tween.unit = unit;
				tween.start = initialInUnit;
				tween.end = adjusted;
			}
		}
		return adjusted;
	}
	
	
	var defaultDisplayMap = {};
	
	function getDefaultDisplay( elem ) {
		var temp,
			doc = elem.ownerDocument,
			nodeName = elem.nodeName,
			display = defaultDisplayMap[ nodeName ];
	
		if ( display ) {
			return display;
		}
	
		temp = doc.body.appendChild( doc.createElement( nodeName ) );
		display = jQuery.css( temp, "display" );
	
		temp.parentNode.removeChild( temp );
	
		if ( display === "none" ) {
			display = "block";
		}
		defaultDisplayMap[ nodeName ] = display;
	
		return display;
	}
	
	function showHide( elements, show ) {
		var display, elem,
			values = [],
			index = 0,
			length = elements.length;
	
		// Determine new display value for elements that need to change
		for ( ; index < length; index++ ) {
			elem = elements[ index ];
			if ( !elem.style ) {
				continue;
			}
	
			display = elem.style.display;
			if ( show ) {
	
				// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
				// check is required in this first loop unless we have a nonempty display value (either
				// inline or about-to-be-restored)
				if ( display === "none" ) {
					values[ index ] = dataPriv.get( elem, "display" ) || null;
					if ( !values[ index ] ) {
						elem.style.display = "";
					}
				}
				if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
					values[ index ] = getDefaultDisplay( elem );
				}
			} else {
				if ( display !== "none" ) {
					values[ index ] = "none";
	
					// Remember what we're overwriting
					dataPriv.set( elem, "display", display );
				}
			}
		}
	
		// Set the display of the elements in a second loop to avoid constant reflow
		for ( index = 0; index < length; index++ ) {
			if ( values[ index ] != null ) {
				elements[ index ].style.display = values[ index ];
			}
		}
	
		return elements;
	}
	
	jQuery.fn.extend( {
		show: function() {
			return showHide( this, true );
		},
		hide: function() {
			return showHide( this );
		},
		toggle: function( state ) {
			if ( typeof state === "boolean" ) {
				return state ? this.show() : this.hide();
			}
	
			return this.each( function() {
				if ( isHiddenWithinTree( this ) ) {
					jQuery( this ).show();
				} else {
					jQuery( this ).hide();
				}
			} );
		}
	} );
	var rcheckableType = ( /^(?:checkbox|radio)$/i );
	
	var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
	
	var rscriptType = ( /^$|\/(?:java|ecma)script/i );
	
	
	
	// We have to close these tags to support XHTML (#13200)
	var wrapMap = {
	
		// Support: IE <=9 only
		option: [ 1, "<select multiple='multiple'>", "</select>" ],
	
		// XHTML parsers do not magically insert elements in the
		// same way that tag soup parsers do. So we cannot shorten
		// this by omitting <tbody> or other required elements.
		thead: [ 1, "<table>", "</table>" ],
		col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
	
		_default: [ 0, "", "" ]
	};
	
	// Support: IE <=9 only
	wrapMap.optgroup = wrapMap.option;
	
	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
	wrapMap.th = wrapMap.td;
	
	
	function getAll( context, tag ) {
	
		// Support: IE <=9 - 11 only
		// Use typeof to avoid zero-argument method invocation on host objects (#15151)
		var ret;
	
		if ( typeof context.getElementsByTagName !== "undefined" ) {
			ret = context.getElementsByTagName( tag || "*" );
	
		} else if ( typeof context.querySelectorAll !== "undefined" ) {
			ret = context.querySelectorAll( tag || "*" );
	
		} else {
			ret = [];
		}
	
		if ( tag === undefined || tag && nodeName( context, tag ) ) {
			return jQuery.merge( [ context ], ret );
		}
	
		return ret;
	}
	
	
	// Mark scripts as having already been evaluated
	function setGlobalEval( elems, refElements ) {
		var i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			dataPriv.set(
				elems[ i ],
				"globalEval",
				!refElements || dataPriv.get( refElements[ i ], "globalEval" )
			);
		}
	}
	
	
	var rhtml = /<|&#?\w+;/;
	
	function buildFragment( elems, context, scripts, selection, ignored ) {
		var elem, tmp, tag, wrap, contains, j,
			fragment = context.createDocumentFragment(),
			nodes = [],
			i = 0,
			l = elems.length;
	
		for ( ; i < l; i++ ) {
			elem = elems[ i ];
	
			if ( elem || elem === 0 ) {
	
				// Add nodes directly
				if ( jQuery.type( elem ) === "object" ) {
	
					// Support: Android <=4.0 only, PhantomJS 1 only
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
	
				// Convert non-html into a text node
				} else if ( !rhtml.test( elem ) ) {
					nodes.push( context.createTextNode( elem ) );
	
				// Convert html into DOM nodes
				} else {
					tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
	
					// Deserialize a standard representation
					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
					wrap = wrapMap[ tag ] || wrapMap._default;
					tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
	
					// Descend through wrappers to the right content
					j = wrap[ 0 ];
					while ( j-- ) {
						tmp = tmp.lastChild;
					}
	
					// Support: Android <=4.0 only, PhantomJS 1 only
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge( nodes, tmp.childNodes );
	
					// Remember the top-level container
					tmp = fragment.firstChild;
	
					// Ensure the created nodes are orphaned (#12392)
					tmp.textContent = "";
				}
			}
		}
	
		// Remove wrapper from fragment
		fragment.textContent = "";
	
		i = 0;
		while ( ( elem = nodes[ i++ ] ) ) {
	
			// Skip elements already in the context collection (trac-4087)
			if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
				if ( ignored ) {
					ignored.push( elem );
				}
				continue;
			}
	
			contains = jQuery.contains( elem.ownerDocument, elem );
	
			// Append to fragment
			tmp = getAll( fragment.appendChild( elem ), "script" );
	
			// Preserve script evaluation history
			if ( contains ) {
				setGlobalEval( tmp );
			}
	
			// Capture executables
			if ( scripts ) {
				j = 0;
				while ( ( elem = tmp[ j++ ] ) ) {
					if ( rscriptType.test( elem.type || "" ) ) {
						scripts.push( elem );
					}
				}
			}
		}
	
		return fragment;
	}
	
	
	( function() {
		var fragment = document.createDocumentFragment(),
			div = fragment.appendChild( document.createElement( "div" ) ),
			input = document.createElement( "input" );
	
		// Support: Android 4.0 - 4.3 only
		// Check state lost if the name is set (#11217)
		// Support: Windows Web Apps (WWA)
		// `name` and `type` must use .setAttribute for WWA (#14901)
		input.setAttribute( "type", "radio" );
		input.setAttribute( "checked", "checked" );
		input.setAttribute( "name", "t" );
	
		div.appendChild( input );
	
		// Support: Android <=4.1 only
		// Older WebKit doesn't clone checked state correctly in fragments
		support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
	
		// Support: IE <=11 only
		// Make sure textarea (and checkbox) defaultValue is properly cloned
		div.innerHTML = "<textarea>x</textarea>";
		support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
	} )();
	var documentElement = document.documentElement;
	
	
	
	var
		rkeyEvent = /^key/,
		rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
		rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
	
	function returnTrue() {
		return true;
	}
	
	function returnFalse() {
		return false;
	}
	
	// Support: IE <=9 only
	// See #13393 for more info
	function safeActiveElement() {
		try {
			return document.activeElement;
		} catch ( err ) { }
	}
	
	function on( elem, types, selector, data, fn, one ) {
		var origFn, type;
	
		// Types can be a map of types/handlers
		if ( typeof types === "object" ) {
	
			// ( types-Object, selector, data )
			if ( typeof selector !== "string" ) {
	
				// ( types-Object, data )
				data = data || selector;
				selector = undefined;
			}
			for ( type in types ) {
				on( elem, type, selector, data, types[ type ], one );
			}
			return elem;
		}
	
		if ( data == null && fn == null ) {
	
			// ( types, fn )
			fn = selector;
			data = selector = undefined;
		} else if ( fn == null ) {
			if ( typeof selector === "string" ) {
	
				// ( types, selector, fn )
				fn = data;
				data = undefined;
			} else {
	
				// ( types, data, fn )
				fn = data;
				data = selector;
				selector = undefined;
			}
		}
		if ( fn === false ) {
			fn = returnFalse;
		} else if ( !fn ) {
			return elem;
		}
	
		if ( one === 1 ) {
			origFn = fn;
			fn = function( event ) {
	
				// Can use an empty set, since event contains the info
				jQuery().off( event );
				return origFn.apply( this, arguments );
			};
	
			// Use same guid so caller can remove using origFn
			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
		}
		return elem.each( function() {
			jQuery.event.add( this, types, fn, data, selector );
		} );
	}
	
	/*
	 * Helper functions for managing events -- not part of the public interface.
	 * Props to Dean Edwards' addEvent library for many of the ideas.
	 */
	jQuery.event = {
	
		global: {},
	
		add: function( elem, types, handler, data, selector ) {
	
			var handleObjIn, eventHandle, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.get( elem );
	
			// Don't attach events to noData or text/comment nodes (but allow plain objects)
			if ( !elemData ) {
				return;
			}
	
			// Caller can pass in an object of custom data in lieu of the handler
			if ( handler.handler ) {
				handleObjIn = handler;
				handler = handleObjIn.handler;
				selector = handleObjIn.selector;
			}
	
			// Ensure that invalid selectors throw exceptions at attach time
			// Evaluate against documentElement in case elem is a non-element node (e.g., document)
			if ( selector ) {
				jQuery.find.matchesSelector( documentElement, selector );
			}
	
			// Make sure that the handler has a unique ID, used to find/remove it later
			if ( !handler.guid ) {
				handler.guid = jQuery.guid++;
			}
	
			// Init the element's event structure and main handler, if this is the first
			if ( !( events = elemData.events ) ) {
				events = elemData.events = {};
			}
			if ( !( eventHandle = elemData.handle ) ) {
				eventHandle = elemData.handle = function( e ) {
	
					// Discard the second event of a jQuery.event.trigger() and
					// when an event is called after a page has unloaded
					return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
						jQuery.event.dispatch.apply( elem, arguments ) : undefined;
				};
			}
	
			// Handle multiple events separated by a space
			types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// There *must* be a type, no attaching namespace-only handlers
				if ( !type ) {
					continue;
				}
	
				// If event changes its type, use the special event handlers for the changed type
				special = jQuery.event.special[ type ] || {};
	
				// If selector defined, determine special event api type, otherwise given type
				type = ( selector ? special.delegateType : special.bindType ) || type;
	
				// Update special based on newly reset type
				special = jQuery.event.special[ type ] || {};
	
				// handleObj is passed to all event handlers
				handleObj = jQuery.extend( {
					type: type,
					origType: origType,
					data: data,
					handler: handler,
					guid: handler.guid,
					selector: selector,
					needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
					namespace: namespaces.join( "." )
				}, handleObjIn );
	
				// Init the event handler queue if we're the first
				if ( !( handlers = events[ type ] ) ) {
					handlers = events[ type ] = [];
					handlers.delegateCount = 0;
	
					// Only use addEventListener if the special events handler returns false
					if ( !special.setup ||
						special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
	
						if ( elem.addEventListener ) {
							elem.addEventListener( type, eventHandle );
						}
					}
				}
	
				if ( special.add ) {
					special.add.call( elem, handleObj );
	
					if ( !handleObj.handler.guid ) {
						handleObj.handler.guid = handler.guid;
					}
				}
	
				// Add to the element's handler list, delegates in front
				if ( selector ) {
					handlers.splice( handlers.delegateCount++, 0, handleObj );
				} else {
					handlers.push( handleObj );
				}
	
				// Keep track of which events have ever been used, for event optimization
				jQuery.event.global[ type ] = true;
			}
	
		},
	
		// Detach an event or set of events from an element
		remove: function( elem, types, handler, selector, mappedTypes ) {
	
			var j, origCount, tmp,
				events, t, handleObj,
				special, handlers, type, namespaces, origType,
				elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
	
			if ( !elemData || !( events = elemData.events ) ) {
				return;
			}
	
			// Once for each type.namespace in types; type may be omitted
			types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
			t = types.length;
			while ( t-- ) {
				tmp = rtypenamespace.exec( types[ t ] ) || [];
				type = origType = tmp[ 1 ];
				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
	
				// Unbind all events (on this namespace, if provided) for the element
				if ( !type ) {
					for ( type in events ) {
						jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
					}
					continue;
				}
	
				special = jQuery.event.special[ type ] || {};
				type = ( selector ? special.delegateType : special.bindType ) || type;
				handlers = events[ type ] || [];
				tmp = tmp[ 2 ] &&
					new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
	
				// Remove matching events
				origCount = j = handlers.length;
				while ( j-- ) {
					handleObj = handlers[ j ];
	
					if ( ( mappedTypes || origType === handleObj.origType ) &&
						( !handler || handler.guid === handleObj.guid ) &&
						( !tmp || tmp.test( handleObj.namespace ) ) &&
						( !selector || selector === handleObj.selector ||
							selector === "**" && handleObj.selector ) ) {
						handlers.splice( j, 1 );
	
						if ( handleObj.selector ) {
							handlers.delegateCount--;
						}
						if ( special.remove ) {
							special.remove.call( elem, handleObj );
						}
					}
				}
	
				// Remove generic event handler if we removed something and no more handlers exist
				// (avoids potential for endless recursion during removal of special event handlers)
				if ( origCount && !handlers.length ) {
					if ( !special.teardown ||
						special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
	
						jQuery.removeEvent( elem, type, elemData.handle );
					}
	
					delete events[ type ];
				}
			}
	
			// Remove data and the expando if it's no longer used
			if ( jQuery.isEmptyObject( events ) ) {
				dataPriv.remove( elem, "handle events" );
			}
		},
	
		dispatch: function( nativeEvent ) {
	
			// Make a writable jQuery.Event from the native event object
			var event = jQuery.event.fix( nativeEvent );
	
			var i, j, ret, matched, handleObj, handlerQueue,
				args = new Array( arguments.length ),
				handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
				special = jQuery.event.special[ event.type ] || {};
	
			// Use the fix-ed jQuery.Event rather than the (read-only) native event
			args[ 0 ] = event;
	
			for ( i = 1; i < arguments.length; i++ ) {
				args[ i ] = arguments[ i ];
			}
	
			event.delegateTarget = this;
	
			// Call the preDispatch hook for the mapped type, and let it bail if desired
			if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
				return;
			}
	
			// Determine handlers
			handlerQueue = jQuery.event.handlers.call( this, event, handlers );
	
			// Run delegates first; they may want to stop propagation beneath us
			i = 0;
			while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
				event.currentTarget = matched.elem;
	
				j = 0;
				while ( ( handleObj = matched.handlers[ j++ ] ) &&
					!event.isImmediatePropagationStopped() ) {
	
					// Triggered event must either 1) have no namespace, or 2) have namespace(s)
					// a subset or equal to those in the bound event (both can have no namespace).
					if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
	
						event.handleObj = handleObj;
						event.data = handleObj.data;
	
						ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
							handleObj.handler ).apply( matched.elem, args );
	
						if ( ret !== undefined ) {
							if ( ( event.result = ret ) === false ) {
								event.preventDefault();
								event.stopPropagation();
							}
						}
					}
				}
			}
	
			// Call the postDispatch hook for the mapped type
			if ( special.postDispatch ) {
				special.postDispatch.call( this, event );
			}
	
			return event.result;
		},
	
		handlers: function( event, handlers ) {
			var i, handleObj, sel, matchedHandlers, matchedSelectors,
				handlerQueue = [],
				delegateCount = handlers.delegateCount,
				cur = event.target;
	
			// Find delegate handlers
			if ( delegateCount &&
	
				// Support: IE <=9
				// Black-hole SVG <use> instance trees (trac-13180)
				cur.nodeType &&
	
				// Support: Firefox <=42
				// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
				// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
				// Support: IE 11 only
				// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
				!( event.type === "click" && event.button >= 1 ) ) {
	
				for ( ; cur !== this; cur = cur.parentNode || this ) {
	
					// Don't check non-elements (#13208)
					// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
					if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
						matchedHandlers = [];
						matchedSelectors = {};
						for ( i = 0; i < delegateCount; i++ ) {
							handleObj = handlers[ i ];
	
							// Don't conflict with Object.prototype properties (#13203)
							sel = handleObj.selector + " ";
	
							if ( matchedSelectors[ sel ] === undefined ) {
								matchedSelectors[ sel ] = handleObj.needsContext ?
									jQuery( sel, this ).index( cur ) > -1 :
									jQuery.find( sel, this, null, [ cur ] ).length;
							}
							if ( matchedSelectors[ sel ] ) {
								matchedHandlers.push( handleObj );
							}
						}
						if ( matchedHandlers.length ) {
							handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
						}
					}
				}
			}
	
			// Add the remaining (directly-bound) handlers
			cur = this;
			if ( delegateCount < handlers.length ) {
				handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
			}
	
			return handlerQueue;
		},
	
		addProp: function( name, hook ) {
			Object.defineProperty( jQuery.Event.prototype, name, {
				enumerable: true,
				configurable: true,
	
				get: jQuery.isFunction( hook ) ?
					function() {
						if ( this.originalEvent ) {
								return hook( this.originalEvent );
						}
					} :
					function() {
						if ( this.originalEvent ) {
								return this.originalEvent[ name ];
						}
					},
	
				set: function( value ) {
					Object.defineProperty( this, name, {
						enumerable: true,
						configurable: true,
						writable: true,
						value: value
					} );
				}
			} );
		},
	
		fix: function( originalEvent ) {
			return originalEvent[ jQuery.expando ] ?
				originalEvent :
				new jQuery.Event( originalEvent );
		},
	
		special: {
			load: {
	
				// Prevent triggered image.load events from bubbling to window.load
				noBubble: true
			},
			focus: {
	
				// Fire native event if possible so blur/focus sequence is correct
				trigger: function() {
					if ( this !== safeActiveElement() && this.focus ) {
						this.focus();
						return false;
					}
				},
				delegateType: "focusin"
			},
			blur: {
				trigger: function() {
					if ( this === safeActiveElement() && this.blur ) {
						this.blur();
						return false;
					}
				},
				delegateType: "focusout"
			},
			click: {
	
				// For checkbox, fire native event so checked state will be right
				trigger: function() {
					if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
						this.click();
						return false;
					}
				},
	
				// For cross-browser consistency, don't fire native .click() on links
				_default: function( event ) {
					return nodeName( event.target, "a" );
				}
			},
	
			beforeunload: {
				postDispatch: function( event ) {
	
					// Support: Firefox 20+
					// Firefox doesn't alert if the returnValue field is not set.
					if ( event.result !== undefined && event.originalEvent ) {
						event.originalEvent.returnValue = event.result;
					}
				}
			}
		}
	};
	
	jQuery.removeEvent = function( elem, type, handle ) {
	
		// This "if" is needed for plain objects
		if ( elem.removeEventListener ) {
			elem.removeEventListener( type, handle );
		}
	};
	
	jQuery.Event = function( src, props ) {
	
		// Allow instantiation without the 'new' keyword
		if ( !( this instanceof jQuery.Event ) ) {
			return new jQuery.Event( src, props );
		}
	
		// Event object
		if ( src && src.type ) {
			this.originalEvent = src;
			this.type = src.type;
	
			// Events bubbling up the document may have been marked as prevented
			// by a handler lower down the tree; reflect the correct value.
			this.isDefaultPrevented = src.defaultPrevented ||
					src.defaultPrevented === undefined &&
	
					// Support: Android <=2.3 only
					src.returnValue === false ?
				returnTrue :
				returnFalse;
	
			// Create target properties
			// Support: Safari <=6 - 7 only
			// Target should not be a text node (#504, #13143)
			this.target = ( src.target && src.target.nodeType === 3 ) ?
				src.target.parentNode :
				src.target;
	
			this.currentTarget = src.currentTarget;
			this.relatedTarget = src.relatedTarget;
	
		// Event type
		} else {
			this.type = src;
		}
	
		// Put explicitly provided properties onto the event object
		if ( props ) {
			jQuery.extend( this, props );
		}
	
		// Create a timestamp if incoming event doesn't have one
		this.timeStamp = src && src.timeStamp || jQuery.now();
	
		// Mark it as fixed
		this[ jQuery.expando ] = true;
	};
	
	// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
	// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
	jQuery.Event.prototype = {
		constructor: jQuery.Event,
		isDefaultPrevented: returnFalse,
		isPropagationStopped: returnFalse,
		isImmediatePropagationStopped: returnFalse,
		isSimulated: false,
	
		preventDefault: function() {
			var e = this.originalEvent;
	
			this.isDefaultPrevented = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.preventDefault();
			}
		},
		stopPropagation: function() {
			var e = this.originalEvent;
	
			this.isPropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopPropagation();
			}
		},
		stopImmediatePropagation: function() {
			var e = this.originalEvent;
	
			this.isImmediatePropagationStopped = returnTrue;
	
			if ( e && !this.isSimulated ) {
				e.stopImmediatePropagation();
			}
	
			this.stopPropagation();
		}
	};
	
	// Includes all common event props including KeyEvent and MouseEvent specific props
	jQuery.each( {
		altKey: true,
		bubbles: true,
		cancelable: true,
		changedTouches: true,
		ctrlKey: true,
		detail: true,
		eventPhase: true,
		metaKey: true,
		pageX: true,
		pageY: true,
		shiftKey: true,
		view: true,
		"char": true,
		charCode: true,
		key: true,
		keyCode: true,
		button: true,
		buttons: true,
		clientX: true,
		clientY: true,
		offsetX: true,
		offsetY: true,
		pointerId: true,
		pointerType: true,
		screenX: true,
		screenY: true,
		targetTouches: true,
		toElement: true,
		touches: true,
	
		which: function( event ) {
			var button = event.button;
	
			// Add which for key events
			if ( event.which == null && rkeyEvent.test( event.type ) ) {
				return event.charCode != null ? event.charCode : event.keyCode;
			}
	
			// Add which for click: 1 === left; 2 === middle; 3 === right
			if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
				if ( button & 1 ) {
					return 1;
				}
	
				if ( button & 2 ) {
					return 3;
				}
	
				if ( button & 4 ) {
					return 2;
				}
	
				return 0;
			}
	
			return event.which;
		}
	}, jQuery.event.addProp );
	
	// Create mouseenter/leave events using mouseover/out and event-time checks
	// so that event delegation works in jQuery.
	// Do the same for pointerenter/pointerleave and pointerover/pointerout
	//
	// Support: Safari 7 only
	// Safari sends mouseenter too often; see:
	// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
	// for the description of the bug (it existed in older Chrome versions as well).
	jQuery.each( {
		mouseenter: "mouseover",
		mouseleave: "mouseout",
		pointerenter: "pointerover",
		pointerleave: "pointerout"
	}, function( orig, fix ) {
		jQuery.event.special[ orig ] = {
			delegateType: fix,
			bindType: fix,
	
			handle: function( event ) {
				var ret,
					target = this,
					related = event.relatedTarget,
					handleObj = event.handleObj;
	
				// For mouseenter/leave call the handler if related is outside the target.
				// NB: No relatedTarget if the mouse left/entered the browser window
				if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
					event.type = handleObj.origType;
					ret = handleObj.handler.apply( this, arguments );
					event.type = fix;
				}
				return ret;
			}
		};
	} );
	
	jQuery.fn.extend( {
	
		on: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn );
		},
		one: function( types, selector, data, fn ) {
			return on( this, types, selector, data, fn, 1 );
		},
		off: function( types, selector, fn ) {
			var handleObj, type;
			if ( types && types.preventDefault && types.handleObj ) {
	
				// ( event )  dispatched jQuery.Event
				handleObj = types.handleObj;
				jQuery( types.delegateTarget ).off(
					handleObj.namespace ?
						handleObj.origType + "." + handleObj.namespace :
						handleObj.origType,
					handleObj.selector,
					handleObj.handler
				);
				return this;
			}
			if ( typeof types === "object" ) {
	
				// ( types-object [, selector] )
				for ( type in types ) {
					this.off( type, selector, types[ type ] );
				}
				return this;
			}
			if ( selector === false || typeof selector === "function" ) {
	
				// ( types [, fn] )
				fn = selector;
				selector = undefined;
			}
			if ( fn === false ) {
				fn = returnFalse;
			}
			return this.each( function() {
				jQuery.event.remove( this, types, fn, selector );
			} );
		}
	} );
	
	
	var
	
		/* eslint-disable max-len */
	
		// See https://github.com/eslint/eslint/issues/3229
		rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
	
		/* eslint-enable */
	
		// Support: IE <=10 - 11, Edge 12 - 13
		// In IE/Edge using regex groups here causes severe slowdowns.
		// See https://connect.microsoft.com/IE/feedback/details/1736512/
		rnoInnerhtml = /<script|<style|<link/i,
	
		// checked="checked" or checked
		rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
		rscriptTypeMasked = /^true\/(.*)/,
		rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
	
	// Prefer a tbody over its parent table for containing new rows
	function manipulationTarget( elem, content ) {
		if ( nodeName( elem, "table" ) &&
			nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
	
			return jQuery( ">tbody", elem )[ 0 ] || elem;
		}
	
		return elem;
	}
	
	// Replace/restore the type attribute of script elements for safe DOM manipulation
	function disableScript( elem ) {
		elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
		return elem;
	}
	function restoreScript( elem ) {
		var match = rscriptTypeMasked.exec( elem.type );
	
		if ( match ) {
			elem.type = match[ 1 ];
		} else {
			elem.removeAttribute( "type" );
		}
	
		return elem;
	}
	
	function cloneCopyEvent( src, dest ) {
		var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
	
		if ( dest.nodeType !== 1 ) {
			return;
		}
	
		// 1. Copy private data: events, handlers, etc.
		if ( dataPriv.hasData( src ) ) {
			pdataOld = dataPriv.access( src );
			pdataCur = dataPriv.set( dest, pdataOld );
			events = pdataOld.events;
	
			if ( events ) {
				delete pdataCur.handle;
				pdataCur.events = {};
	
				for ( type in events ) {
					for ( i = 0, l = events[ type ].length; i < l; i++ ) {
						jQuery.event.add( dest, type, events[ type ][ i ] );
					}
				}
			}
		}
	
		// 2. Copy user data
		if ( dataUser.hasData( src ) ) {
			udataOld = dataUser.access( src );
			udataCur = jQuery.extend( {}, udataOld );
	
			dataUser.set( dest, udataCur );
		}
	}
	
	// Fix IE bugs, see support tests
	function fixInput( src, dest ) {
		var nodeName = dest.nodeName.toLowerCase();
	
		// Fails to persist the checked state of a cloned checkbox or radio button.
		if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
			dest.checked = src.checked;
	
		// Fails to return the selected option to the default selected state when cloning options
		} else if ( nodeName === "input" || nodeName === "textarea" ) {
			dest.defaultValue = src.defaultValue;
		}
	}
	
	function domManip( collection, args, callback, ignored ) {
	
		// Flatten any nested arrays
		args = concat.apply( [], args );
	
		var fragment, first, scripts, hasScripts, node, doc,
			i = 0,
			l = collection.length,
			iNoClone = l - 1,
			value = args[ 0 ],
			isFunction = jQuery.isFunction( value );
	
		// We can't cloneNode fragments that contain checked, in WebKit
		if ( isFunction ||
				( l > 1 && typeof value === "string" &&
					!support.checkClone && rchecked.test( value ) ) ) {
			return collection.each( function( index ) {
				var self = collection.eq( index );
				if ( isFunction ) {
					args[ 0 ] = value.call( this, index, self.html() );
				}
				domManip( self, args, callback, ignored );
			} );
		}
	
		if ( l ) {
			fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
			first = fragment.firstChild;
	
			if ( fragment.childNodes.length === 1 ) {
				fragment = first;
			}
	
			// Require either new content or an interest in ignored elements to invoke the callback
			if ( first || ignored ) {
				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
				hasScripts = scripts.length;
	
				// Use the original fragment for the last item
				// instead of the first because it can end up
				// being emptied incorrectly in certain situations (#8070).
				for ( ; i < l; i++ ) {
					node = fragment;
	
					if ( i !== iNoClone ) {
						node = jQuery.clone( node, true, true );
	
						// Keep references to cloned scripts for later restoration
						if ( hasScripts ) {
	
							// Support: Android <=4.0 only, PhantomJS 1 only
							// push.apply(_, arraylike) throws on ancient WebKit
							jQuery.merge( scripts, getAll( node, "script" ) );
						}
					}
	
					callback.call( collection[ i ], node, i );
				}
	
				if ( hasScripts ) {
					doc = scripts[ scripts.length - 1 ].ownerDocument;
	
					// Reenable scripts
					jQuery.map( scripts, restoreScript );
	
					// Evaluate executable scripts on first document insertion
					for ( i = 0; i < hasScripts; i++ ) {
						node = scripts[ i ];
						if ( rscriptType.test( node.type || "" ) &&
							!dataPriv.access( node, "globalEval" ) &&
							jQuery.contains( doc, node ) ) {
	
							if ( node.src ) {
	
								// Optional AJAX dependency, but won't run scripts if not present
								if ( jQuery._evalUrl ) {
									jQuery._evalUrl( node.src );
								}
							} else {
								DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
							}
						}
					}
				}
			}
		}
	
		return collection;
	}
	
	function remove( elem, selector, keepData ) {
		var node,
			nodes = selector ? jQuery.filter( selector, elem ) : elem,
			i = 0;
	
		for ( ; ( node = nodes[ i ] ) != null; i++ ) {
			if ( !keepData && node.nodeType === 1 ) {
				jQuery.cleanData( getAll( node ) );
			}
	
			if ( node.parentNode ) {
				if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
					setGlobalEval( getAll( node, "script" ) );
				}
				node.parentNode.removeChild( node );
			}
		}
	
		return elem;
	}
	
	jQuery.extend( {
		htmlPrefilter: function( html ) {
			return html.replace( rxhtmlTag, "<$1></$2>" );
		},
	
		clone: function( elem, dataAndEvents, deepDataAndEvents ) {
			var i, l, srcElements, destElements,
				clone = elem.cloneNode( true ),
				inPage = jQuery.contains( elem.ownerDocument, elem );
	
			// Fix IE cloning issues
			if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
					!jQuery.isXMLDoc( elem ) ) {
	
				// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
				destElements = getAll( clone );
				srcElements = getAll( elem );
	
				for ( i = 0, l = srcElements.length; i < l; i++ ) {
					fixInput( srcElements[ i ], destElements[ i ] );
				}
			}
	
			// Copy the events from the original to the clone
			if ( dataAndEvents ) {
				if ( deepDataAndEvents ) {
					srcElements = srcElements || getAll( elem );
					destElements = destElements || getAll( clone );
	
					for ( i = 0, l = srcElements.length; i < l; i++ ) {
						cloneCopyEvent( srcElements[ i ], destElements[ i ] );
					}
				} else {
					cloneCopyEvent( elem, clone );
				}
			}
	
			// Preserve script evaluation history
			destElements = getAll( clone, "script" );
			if ( destElements.length > 0 ) {
				setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
			}
	
			// Return the cloned set
			return clone;
		},
	
		cleanData: function( elems ) {
			var data, elem, type,
				special = jQuery.event.special,
				i = 0;
	
			for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
				if ( acceptData( elem ) ) {
					if ( ( data = elem[ dataPriv.expando ] ) ) {
						if ( data.events ) {
							for ( type in data.events ) {
								if ( special[ type ] ) {
									jQuery.event.remove( elem, type );
	
								// This is a shortcut to avoid jQuery.event.remove's overhead
								} else {
									jQuery.removeEvent( elem, type, data.handle );
								}
							}
						}
	
						// Support: Chrome <=35 - 45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataPriv.expando ] = undefined;
					}
					if ( elem[ dataUser.expando ] ) {
	
						// Support: Chrome <=35 - 45+
						// Assign undefined instead of using delete, see Data#remove
						elem[ dataUser.expando ] = undefined;
					}
				}
			}
		}
	} );
	
	jQuery.fn.extend( {
		detach: function( selector ) {
			return remove( this, selector, true );
		},
	
		remove: function( selector ) {
			return remove( this, selector );
		},
	
		text: function( value ) {
			return access( this, function( value ) {
				return value === undefined ?
					jQuery.text( this ) :
					this.empty().each( function() {
						if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
							this.textContent = value;
						}
					} );
			}, null, value, arguments.length );
		},
	
		append: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.appendChild( elem );
				}
			} );
		},
	
		prepend: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
					var target = manipulationTarget( this, elem );
					target.insertBefore( elem, target.firstChild );
				}
			} );
		},
	
		before: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this );
				}
			} );
		},
	
		after: function() {
			return domManip( this, arguments, function( elem ) {
				if ( this.parentNode ) {
					this.parentNode.insertBefore( elem, this.nextSibling );
				}
			} );
		},
	
		empty: function() {
			var elem,
				i = 0;
	
			for ( ; ( elem = this[ i ] ) != null; i++ ) {
				if ( elem.nodeType === 1 ) {
	
					// Prevent memory leaks
					jQuery.cleanData( getAll( elem, false ) );
	
					// Remove any remaining nodes
					elem.textContent = "";
				}
			}
	
			return this;
		},
	
		clone: function( dataAndEvents, deepDataAndEvents ) {
			dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
			deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
	
			return this.map( function() {
				return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
			} );
		},
	
		html: function( value ) {
			return access( this, function( value ) {
				var elem = this[ 0 ] || {},
					i = 0,
					l = this.length;
	
				if ( value === undefined && elem.nodeType === 1 ) {
					return elem.innerHTML;
				}
	
				// See if we can take a shortcut and just use innerHTML
				if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
					!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
	
					value = jQuery.htmlPrefilter( value );
	
					try {
						for ( ; i < l; i++ ) {
							elem = this[ i ] || {};
	
							// Remove element nodes and prevent memory leaks
							if ( elem.nodeType === 1 ) {
								jQuery.cleanData( getAll( elem, false ) );
								elem.innerHTML = value;
							}
						}
	
						elem = 0;
	
					// If using innerHTML throws an exception, use the fallback method
					} catch ( e ) {}
				}
	
				if ( elem ) {
					this.empty().append( value );
				}
			}, null, value, arguments.length );
		},
	
		replaceWith: function() {
			var ignored = [];
	
			// Make the changes, replacing each non-ignored context element with the new content
			return domManip( this, arguments, function( elem ) {
				var parent = this.parentNode;
	
				if ( jQuery.inArray( this, ignored ) < 0 ) {
					jQuery.cleanData( getAll( this ) );
					if ( parent ) {
						parent.replaceChild( elem, this );
					}
				}
	
			// Force callback invocation
			}, ignored );
		}
	} );
	
	jQuery.each( {
		appendTo: "append",
		prependTo: "prepend",
		insertBefore: "before",
		insertAfter: "after",
		replaceAll: "replaceWith"
	}, function( name, original ) {
		jQuery.fn[ name ] = function( selector ) {
			var elems,
				ret = [],
				insert = jQuery( selector ),
				last = insert.length - 1,
				i = 0;
	
			for ( ; i <= last; i++ ) {
				elems = i === last ? this : this.clone( true );
				jQuery( insert[ i ] )[ original ]( elems );
	
				// Support: Android <=4.0 only, PhantomJS 1 only
				// .get() because push.apply(_, arraylike) throws on ancient WebKit
				push.apply( ret, elems.get() );
			}
	
			return this.pushStack( ret );
		};
	} );
	var rmargin = ( /^margin/ );
	
	var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
	
	var getStyles = function( elem ) {
	
			// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
			// IE throws on elements created in popups
			// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
			var view = elem.ownerDocument.defaultView;
	
			if ( !view || !view.opener ) {
				view = window;
			}
	
			return view.getComputedStyle( elem );
		};
	
	
	
	( function() {
	
		// Executing both pixelPosition & boxSizingReliable tests require only one layout
		// so they're executed at the same time to save the second computation.
		function computeStyleTests() {
	
			// This is a singleton, we need to execute it only once
			if ( !div ) {
				return;
			}
	
			div.style.cssText =
				"box-sizing:border-box;" +
				"position:relative;display:block;" +
				"margin:auto;border:1px;padding:1px;" +
				"top:1%;width:50%";
			div.innerHTML = "";
			documentElement.appendChild( container );
	
			var divStyle = window.getComputedStyle( div );
			pixelPositionVal = divStyle.top !== "1%";
	
			// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
			reliableMarginLeftVal = divStyle.marginLeft === "2px";
			boxSizingReliableVal = divStyle.width === "4px";
	
			// Support: Android 4.0 - 4.3 only
			// Some styles come back with percentage values, even though they shouldn't
			div.style.marginRight = "50%";
			pixelMarginRightVal = divStyle.marginRight === "4px";
	
			documentElement.removeChild( container );
	
			// Nullify the div so it wouldn't be stored in the memory and
			// it will also be a sign that checks already performed
			div = null;
		}
	
		var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
			container = document.createElement( "div" ),
			div = document.createElement( "div" );
	
		// Finish early in limited (non-browser) environments
		if ( !div.style ) {
			return;
		}
	
		// Support: IE <=9 - 11 only
		// Style of cloned element affects source element cloned (#8908)
		div.style.backgroundClip = "content-box";
		div.cloneNode( true ).style.backgroundClip = "";
		support.clearCloneStyle = div.style.backgroundClip === "content-box";
	
		container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
			"padding:0;margin-top:1px;position:absolute";
		container.appendChild( div );
	
		jQuery.extend( support, {
			pixelPosition: function() {
				computeStyleTests();
				return pixelPositionVal;
			},
			boxSizingReliable: function() {
				computeStyleTests();
				return boxSizingReliableVal;
			},
			pixelMarginRight: function() {
				computeStyleTests();
				return pixelMarginRightVal;
			},
			reliableMarginLeft: function() {
				computeStyleTests();
				return reliableMarginLeftVal;
			}
		} );
	} )();
	
	
	function curCSS( elem, name, computed ) {
		var width, minWidth, maxWidth, ret,
	
			// Support: Firefox 51+
			// Retrieving style before computed somehow
			// fixes an issue with getting wrong values
			// on detached elements
			style = elem.style;
	
		computed = computed || getStyles( elem );
	
		// getPropertyValue is needed for:
		//   .css('filter') (IE 9 only, #12537)
		//   .css('--customProperty) (#3144)
		if ( computed ) {
			ret = computed.getPropertyValue( name ) || computed[ name ];
	
			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
				ret = jQuery.style( elem, name );
			}
	
			// A tribute to the "awesome hack by Dean Edwards"
			// Android Browser returns percentage for some values,
			// but width seems to be reliably pixels.
			// This is against the CSSOM draft spec:
			// https://drafts.csswg.org/cssom/#resolved-values
			if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
	
				// Remember the original values
				width = style.width;
				minWidth = style.minWidth;
				maxWidth = style.maxWidth;
	
				// Put in the new values to get a computed value out
				style.minWidth = style.maxWidth = style.width = ret;
				ret = computed.width;
	
				// Revert the changed values
				style.width = width;
				style.minWidth = minWidth;
				style.maxWidth = maxWidth;
			}
		}
	
		return ret !== undefined ?
	
			// Support: IE <=9 - 11 only
			// IE returns zIndex value as an integer.
			ret + "" :
			ret;
	}
	
	
	function addGetHookIf( conditionFn, hookFn ) {
	
		// Define the hook, we'll check on the first run if it's really needed.
		return {
			get: function() {
				if ( conditionFn() ) {
	
					// Hook not needed (or it's not possible to use it due
					// to missing dependency), remove it.
					delete this.get;
					return;
				}
	
				// Hook needed; redefine it so that the support test is not executed again.
				return ( this.get = hookFn ).apply( this, arguments );
			}
		};
	}
	
	
	var
	
		// Swappable if display is none or starts with table
		// except "table", "table-cell", or "table-caption"
		// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
		rdisplayswap = /^(none|table(?!-c[ea]).+)/,
		rcustomProp = /^--/,
		cssShow = { position: "absolute", visibility: "hidden", display: "block" },
		cssNormalTransform = {
			letterSpacing: "0",
			fontWeight: "400"
		},
	
		cssPrefixes = [ "Webkit", "Moz", "ms" ],
		emptyStyle = document.createElement( "div" ).style;
	
	// Return a css property mapped to a potentially vendor prefixed property
	function vendorPropName( name ) {
	
		// Shortcut for names that are not vendor prefixed
		if ( name in emptyStyle ) {
			return name;
		}
	
		// Check for vendor prefixed names
		var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
			i = cssPrefixes.length;
	
		while ( i-- ) {
			name = cssPrefixes[ i ] + capName;
			if ( name in emptyStyle ) {
				return name;
			}
		}
	}
	
	// Return a property mapped along what jQuery.cssProps suggests or to
	// a vendor prefixed property.
	function finalPropName( name ) {
		var ret = jQuery.cssProps[ name ];
		if ( !ret ) {
			ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
		}
		return ret;
	}
	
	function setPositiveNumber( elem, value, subtract ) {
	
		// Any relative (+/-) values have already been
		// normalized at this point
		var matches = rcssNum.exec( value );
		return matches ?
	
			// Guard against undefined "subtract", e.g., when used as in cssHooks
			Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
			value;
	}
	
	function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
		var i,
			val = 0;
	
		// If we already have the right measurement, avoid augmentation
		if ( extra === ( isBorderBox ? "border" : "content" ) ) {
			i = 4;
	
		// Otherwise initialize for horizontal or vertical properties
		} else {
			i = name === "width" ? 1 : 0;
		}
	
		for ( ; i < 4; i += 2 ) {
	
			// Both box models exclude margin, so add it if we want it
			if ( extra === "margin" ) {
				val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
			}
	
			if ( isBorderBox ) {
	
				// border-box includes padding, so remove it if we want content
				if ( extra === "content" ) {
					val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
				}
	
				// At this point, extra isn't border nor margin, so remove border
				if ( extra !== "margin" ) {
					val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			} else {
	
				// At this point, extra isn't content, so add padding
				val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
	
				// At this point, extra isn't content nor padding, so add border
				if ( extra !== "padding" ) {
					val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
				}
			}
		}
	
		return val;
	}
	
	function getWidthOrHeight( elem, name, extra ) {
	
		// Start with computed style
		var valueIsBorderBox,
			styles = getStyles( elem ),
			val = curCSS( elem, name, styles ),
			isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
	
		// Computed unit is not pixels. Stop here and return.
		if ( rnumnonpx.test( val ) ) {
			return val;
		}
	
		// Check for style in case a browser which returns unreliable values
		// for getComputedStyle silently falls back to the reliable elem.style
		valueIsBorderBox = isBorderBox &&
			( support.boxSizingReliable() || val === elem.style[ name ] );
	
		// Fall back to offsetWidth/Height when value is "auto"
		// This happens for inline elements with no explicit setting (gh-3571)
		if ( val === "auto" ) {
			val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
		}
	
		// Normalize "", auto, and prepare for extra
		val = parseFloat( val ) || 0;
	
		// Use the active box-sizing model to add/subtract irrelevant styles
		return ( val +
			augmentWidthOrHeight(
				elem,
				name,
				extra || ( isBorderBox ? "border" : "content" ),
				valueIsBorderBox,
				styles
			)
		) + "px";
	}
	
	jQuery.extend( {
	
		// Add in style property hooks for overriding the default
		// behavior of getting and setting a style property
		cssHooks: {
			opacity: {
				get: function( elem, computed ) {
					if ( computed ) {
	
						// We should always get a number back from opacity
						var ret = curCSS( elem, "opacity" );
						return ret === "" ? "1" : ret;
					}
				}
			}
		},
	
		// Don't automatically add "px" to these possibly-unitless properties
		cssNumber: {
			"animationIterationCount": true,
			"columnCount": true,
			"fillOpacity": true,
			"flexGrow": true,
			"flexShrink": true,
			"fontWeight": true,
			"lineHeight": true,
			"opacity": true,
			"order": true,
			"orphans": true,
			"widows": true,
			"zIndex": true,
			"zoom": true
		},
	
		// Add in properties whose names you wish to fix before
		// setting or getting the value
		cssProps: {
			"float": "cssFloat"
		},
	
		// Get and set the style property on a DOM Node
		style: function( elem, name, value, extra ) {
	
			// Don't set styles on text and comment nodes
			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
				return;
			}
	
			// Make sure that we're working with the right name
			var ret, type, hooks,
				origName = jQuery.camelCase( name ),
				isCustomProp = rcustomProp.test( name ),
				style = elem.style;
	
			// Make sure that we're working with the right name. We don't
			// want to query the value if it is a CSS custom property
			// since they are user-defined.
			if ( !isCustomProp ) {
				name = finalPropName( origName );
			}
	
			// Gets hook for the prefixed version, then unprefixed version
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// Check if we're setting a value
			if ( value !== undefined ) {
				type = typeof value;
	
				// Convert "+=" or "-=" to relative numbers (#7345)
				if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
					value = adjustCSS( elem, name, ret );
	
					// Fixes bug #9237
					type = "number";
				}
	
				// Make sure that null and NaN values aren't set (#7116)
				if ( value == null || value !== value ) {
					return;
				}
	
				// If a number was passed in, add the unit (except for certain CSS properties)
				if ( type === "number" ) {
					value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
				}
	
				// background-* props affect original clone's values
				if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
					style[ name ] = "inherit";
				}
	
				// If a hook was provided, use that value, otherwise just set the specified value
				if ( !hooks || !( "set" in hooks ) ||
					( value = hooks.set( elem, value, extra ) ) !== undefined ) {
	
					if ( isCustomProp ) {
						style.setProperty( name, value );
					} else {
						style[ name ] = value;
					}
				}
	
			} else {
	
				// If a hook was provided get the non-computed value from there
				if ( hooks && "get" in hooks &&
					( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
	
					return ret;
				}
	
				// Otherwise just get the value from the style object
				return style[ name ];
			}
		},
	
		css: function( elem, name, extra, styles ) {
			var val, num, hooks,
				origName = jQuery.camelCase( name ),
				isCustomProp = rcustomProp.test( name );
	
			// Make sure that we're working with the right name. We don't
			// want to modify the value if it is a CSS custom property
			// since they are user-defined.
			if ( !isCustomProp ) {
				name = finalPropName( origName );
			}
	
			// Try prefixed name followed by the unprefixed name
			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
	
			// If a hook was provided get the computed value from there
			if ( hooks && "get" in hooks ) {
				val = hooks.get( elem, true, extra );
			}
	
			// Otherwise, if a way to get the computed value exists, use that
			if ( val === undefined ) {
				val = curCSS( elem, name, styles );
			}
	
			// Convert "normal" to computed value
			if ( val === "normal" && name in cssNormalTransform ) {
				val = cssNormalTransform[ name ];
			}
	
			// Make numeric if forced or a qualifier was provided and val looks numeric
			if ( extra === "" || extra ) {
				num = parseFloat( val );
				return extra === true || isFinite( num ) ? num || 0 : val;
			}
	
			return val;
		}
	} );
	
	jQuery.each( [ "height", "width" ], function( i, name ) {
		jQuery.cssHooks[ name ] = {
			get: function( elem, computed, extra ) {
				if ( computed ) {
	
					// Certain elements can have dimension info if we invisibly show them
					// but it must have a current display style that would benefit
					return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
	
						// Support: Safari 8+
						// Table columns in Safari have non-zero offsetWidth & zero
						// getBoundingClientRect().width unless display is changed.
						// Support: IE <=11 only
						// Running getBoundingClientRect on a disconnected node
						// in IE throws an error.
						( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
							swap( elem, cssShow, function() {
								return getWidthOrHeight( elem, name, extra );
							} ) :
							getWidthOrHeight( elem, name, extra );
				}
			},
	
			set: function( elem, value, extra ) {
				var matches,
					styles = extra && getStyles( elem ),
					subtract = extra && augmentWidthOrHeight(
						elem,
						name,
						extra,
						jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
						styles
					);
	
				// Convert to pixels if value adjustment is needed
				if ( subtract && ( matches = rcssNum.exec( value ) ) &&
					( matches[ 3 ] || "px" ) !== "px" ) {
	
					elem.style[ name ] = value;
					value = jQuery.css( elem, name );
				}
	
				return setPositiveNumber( elem, value, subtract );
			}
		};
	} );
	
	jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
		function( elem, computed ) {
			if ( computed ) {
				return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
					elem.getBoundingClientRect().left -
						swap( elem, { marginLeft: 0 }, function() {
							return elem.getBoundingClientRect().left;
						} )
					) + "px";
			}
		}
	);
	
	// These hooks are used by animate to expand properties
	jQuery.each( {
		margin: "",
		padding: "",
		border: "Width"
	}, function( prefix, suffix ) {
		jQuery.cssHooks[ prefix + suffix ] = {
			expand: function( value ) {
				var i = 0,
					expanded = {},
	
					// Assumes a single number if not a string
					parts = typeof value === "string" ? value.split( " " ) : [ value ];
	
				for ( ; i < 4; i++ ) {
					expanded[ prefix + cssExpand[ i ] + suffix ] =
						parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
				}
	
				return expanded;
			}
		};
	
		if ( !rmargin.test( prefix ) ) {
			jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
		}
	} );
	
	jQuery.fn.extend( {
		css: function( name, value ) {
			return access( this, function( elem, name, value ) {
				var styles, len,
					map = {},
					i = 0;
	
				if ( Array.isArray( name ) ) {
					styles = getStyles( elem );
					len = name.length;
	
					for ( ; i < len; i++ ) {
						map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
					}
	
					return map;
				}
	
				return value !== undefined ?
					jQuery.style( elem, name, value ) :
					jQuery.css( elem, name );
			}, name, value, arguments.length > 1 );
		}
	} );
	
	
	function Tween( elem, options, prop, end, easing ) {
		return new Tween.prototype.init( elem, options, prop, end, easing );
	}
	jQuery.Tween = Tween;
	
	Tween.prototype = {
		constructor: Tween,
		init: function( elem, options, prop, end, easing, unit ) {
			this.elem = elem;
			this.prop = prop;
			this.easing = easing || jQuery.easing._default;
			this.options = options;
			this.start = this.now = this.cur();
			this.end = end;
			this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
		},
		cur: function() {
			var hooks = Tween.propHooks[ this.prop ];
	
			return hooks && hooks.get ?
				hooks.get( this ) :
				Tween.propHooks._default.get( this );
		},
		run: function( percent ) {
			var eased,
				hooks = Tween.propHooks[ this.prop ];
	
			if ( this.options.duration ) {
				this.pos = eased = jQuery.easing[ this.easing ](
					percent, this.options.duration * percent, 0, 1, this.options.duration
				);
			} else {
				this.pos = eased = percent;
			}
			this.now = ( this.end - this.start ) * eased + this.start;
	
			if ( this.options.step ) {
				this.options.step.call( this.elem, this.now, this );
			}
	
			if ( hooks && hooks.set ) {
				hooks.set( this );
			} else {
				Tween.propHooks._default.set( this );
			}
			return this;
		}
	};
	
	Tween.prototype.init.prototype = Tween.prototype;
	
	Tween.propHooks = {
		_default: {
			get: function( tween ) {
				var result;
	
				// Use a property on the element directly when it is not a DOM element,
				// or when there is no matching style property that exists.
				if ( tween.elem.nodeType !== 1 ||
					tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
					return tween.elem[ tween.prop ];
				}
	
				// Passing an empty string as a 3rd parameter to .css will automatically
				// attempt a parseFloat and fallback to a string if the parse fails.
				// Simple values such as "10px" are parsed to Float;
				// complex values such as "rotate(1rad)" are returned as-is.
				result = jQuery.css( tween.elem, tween.prop, "" );
	
				// Empty strings, null, undefined and "auto" are converted to 0.
				return !result || result === "auto" ? 0 : result;
			},
			set: function( tween ) {
	
				// Use step hook for back compat.
				// Use cssHook if its there.
				// Use .style if available and use plain properties where available.
				if ( jQuery.fx.step[ tween.prop ] ) {
					jQuery.fx.step[ tween.prop ]( tween );
				} else if ( tween.elem.nodeType === 1 &&
					( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
						jQuery.cssHooks[ tween.prop ] ) ) {
					jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
				} else {
					tween.elem[ tween.prop ] = tween.now;
				}
			}
		}
	};
	
	// Support: IE <=9 only
	// Panic based approach to setting things on disconnected nodes
	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
		set: function( tween ) {
			if ( tween.elem.nodeType && tween.elem.parentNode ) {
				tween.elem[ tween.prop ] = tween.now;
			}
		}
	};
	
	jQuery.easing = {
		linear: function( p ) {
			return p;
		},
		swing: function( p ) {
			return 0.5 - Math.cos( p * Math.PI ) / 2;
		},
		_default: "swing"
	};
	
	jQuery.fx = Tween.prototype.init;
	
	// Back compat <1.8 extension point
	jQuery.fx.step = {};
	
	
	
	
	var
		fxNow, inProgress,
		rfxtypes = /^(?:toggle|show|hide)$/,
		rrun = /queueHooks$/;
	
	function schedule() {
		if ( inProgress ) {
			if ( document.hidden === false && window.requestAnimationFrame ) {
				window.requestAnimationFrame( schedule );
			} else {
				window.setTimeout( schedule, jQuery.fx.interval );
			}
	
			jQuery.fx.tick();
		}
	}
	
	// Animations created synchronously will run synchronously
	function createFxNow() {
		window.setTimeout( function() {
			fxNow = undefined;
		} );
		return ( fxNow = jQuery.now() );
	}
	
	// Generate parameters to create a standard animation
	function genFx( type, includeWidth ) {
		var which,
			i = 0,
			attrs = { height: type };
	
		// If we include width, step value is 1 to do all cssExpand values,
		// otherwise step value is 2 to skip over Left and Right
		includeWidth = includeWidth ? 1 : 0;
		for ( ; i < 4; i += 2 - includeWidth ) {
			which = cssExpand[ i ];
			attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
		}
	
		if ( includeWidth ) {
			attrs.opacity = attrs.width = type;
		}
	
		return attrs;
	}
	
	function createTween( value, prop, animation ) {
		var tween,
			collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
			index = 0,
			length = collection.length;
		for ( ; index < length; index++ ) {
			if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
	
				// We're done with this property
				return tween;
			}
		}
	}
	
	function defaultPrefilter( elem, props, opts ) {
		var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
			isBox = "width" in props || "height" in props,
			anim = this,
			orig = {},
			style = elem.style,
			hidden = elem.nodeType && isHiddenWithinTree( elem ),
			dataShow = dataPriv.get( elem, "fxshow" );
	
		// Queue-skipping animations hijack the fx hooks
		if ( !opts.queue ) {
			hooks = jQuery._queueHooks( elem, "fx" );
			if ( hooks.unqueued == null ) {
				hooks.unqueued = 0;
				oldfire = hooks.empty.fire;
				hooks.empty.fire = function() {
					if ( !hooks.unqueued ) {
						oldfire();
					}
				};
			}
			hooks.unqueued++;
	
			anim.always( function() {
	
				// Ensure the complete handler is called before this completes
				anim.always( function() {
					hooks.unqueued--;
					if ( !jQuery.queue( elem, "fx" ).length ) {
						hooks.empty.fire();
					}
				} );
			} );
		}
	
		// Detect show/hide animations
		for ( prop in props ) {
			value = props[ prop ];
			if ( rfxtypes.test( value ) ) {
				delete props[ prop ];
				toggle = toggle || value === "toggle";
				if ( value === ( hidden ? "hide" : "show" ) ) {
	
					// Pretend to be hidden if this is a "show" and
					// there is still data from a stopped show/hide
					if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
						hidden = true;
	
					// Ignore all other no-op show/hide data
					} else {
						continue;
					}
				}
				orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
			}
		}
	
		// Bail out if this is a no-op like .hide().hide()
		propTween = !jQuery.isEmptyObject( props );
		if ( !propTween && jQuery.isEmptyObject( orig ) ) {
			return;
		}
	
		// Restrict "overflow" and "display" styles during box animations
		if ( isBox && elem.nodeType === 1 ) {
	
			// Support: IE <=9 - 11, Edge 12 - 13
			// Record all 3 overflow attributes because IE does not infer the shorthand
			// from identically-valued overflowX and overflowY
			opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
	
			// Identify a display type, preferring old show/hide data over the CSS cascade
			restoreDisplay = dataShow && dataShow.display;
			if ( restoreDisplay == null ) {
				restoreDisplay = dataPriv.get( elem, "display" );
			}
			display = jQuery.css( elem, "display" );
			if ( display === "none" ) {
				if ( restoreDisplay ) {
					display = restoreDisplay;
				} else {
	
					// Get nonempty value(s) by temporarily forcing visibility
					showHide( [ elem ], true );
					restoreDisplay = elem.style.display || restoreDisplay;
					display = jQuery.css( elem, "display" );
					showHide( [ elem ] );
				}
			}
	
			// Animate inline elements as inline-block
			if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
				if ( jQuery.css( elem, "float" ) === "none" ) {
	
					// Restore the original display value at the end of pure show/hide animations
					if ( !propTween ) {
						anim.done( function() {
							style.display = restoreDisplay;
						} );
						if ( restoreDisplay == null ) {
							display = style.display;
							restoreDisplay = display === "none" ? "" : display;
						}
					}
					style.display = "inline-block";
				}
			}
		}
	
		if ( opts.overflow ) {
			style.overflow = "hidden";
			anim.always( function() {
				style.overflow = opts.overflow[ 0 ];
				style.overflowX = opts.overflow[ 1 ];
				style.overflowY = opts.overflow[ 2 ];
			} );
		}
	
		// Implement show/hide animations
		propTween = false;
		for ( prop in orig ) {
	
			// General show/hide setup for this element animation
			if ( !propTween ) {
				if ( dataShow ) {
					if ( "hidden" in dataShow ) {
						hidden = dataShow.hidden;
					}
				} else {
					dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
				}
	
				// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
				if ( toggle ) {
					dataShow.hidden = !hidden;
				}
	
				// Show elements before animating them
				if ( hidden ) {
					showHide( [ elem ], true );
				}
	
				/* eslint-disable no-loop-func */
	
				anim.done( function() {
	
				/* eslint-enable no-loop-func */
	
					// The final step of a "hide" animation is actually hiding the element
					if ( !hidden ) {
						showHide( [ elem ] );
					}
					dataPriv.remove( elem, "fxshow" );
					for ( prop in orig ) {
						jQuery.style( elem, prop, orig[ prop ] );
					}
				} );
			}
	
			// Per-property setup
			propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
			if ( !( prop in dataShow ) ) {
				dataShow[ prop ] = propTween.start;
				if ( hidden ) {
					propTween.end = propTween.start;
					propTween.start = 0;
				}
			}
		}
	}
	
	function propFilter( props, specialEasing ) {
		var index, name, easing, value, hooks;
	
		// camelCase, specialEasing and expand cssHook pass
		for ( index in props ) {
			name = jQuery.camelCase( index );
			easing = specialEasing[ name ];
			value = props[ index ];
			if ( Array.isArray( value ) ) {
				easing = value[ 1 ];
				value = props[ index ] = value[ 0 ];
			}
	
			if ( index !== name ) {
				props[ name ] = value;
				delete props[ index ];
			}
	
			hooks = jQuery.cssHooks[ name ];
			if ( hooks && "expand" in hooks ) {
				value = hooks.expand( value );
				delete props[ name ];
	
				// Not quite $.extend, this won't overwrite existing keys.
				// Reusing 'index' because we have the correct "name"
				for ( index in value ) {
					if ( !( index in props ) ) {
						props[ index ] = value[ index ];
						specialEasing[ index ] = easing;
					}
				}
			} else {
				specialEasing[ name ] = easing;
			}
		}
	}
	
	function Animation( elem, properties, options ) {
		var result,
			stopped,
			index = 0,
			length = Animation.prefilters.length,
			deferred = jQuery.Deferred().always( function() {
	
				// Don't match elem in the :animated selector
				delete tick.elem;
			} ),
			tick = function() {
				if ( stopped ) {
					return false;
				}
				var currentTime = fxNow || createFxNow(),
					remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
	
					// Support: Android 2.3 only
					// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
					temp = remaining / animation.duration || 0,
					percent = 1 - temp,
					index = 0,
					length = animation.tweens.length;
	
				for ( ; index < length; index++ ) {
					animation.tweens[ index ].run( percent );
				}
	
				deferred.notifyWith( elem, [ animation, percent, remaining ] );
	
				// If there's more to do, yield
				if ( percent < 1 && length ) {
					return remaining;
				}
	
				// If this was an empty animation, synthesize a final progress notification
				if ( !length ) {
					deferred.notifyWith( elem, [ animation, 1, 0 ] );
				}
	
				// Resolve the animation and report its conclusion
				deferred.resolveWith( elem, [ animation ] );
				return false;
			},
			animation = deferred.promise( {
				elem: elem,
				props: jQuery.extend( {}, properties ),
				opts: jQuery.extend( true, {
					specialEasing: {},
					easing: jQuery.easing._default
				}, options ),
				originalProperties: properties,
				originalOptions: options,
				startTime: fxNow || createFxNow(),
				duration: options.duration,
				tweens: [],
				createTween: function( prop, end ) {
					var tween = jQuery.Tween( elem, animation.opts, prop, end,
							animation.opts.specialEasing[ prop ] || animation.opts.easing );
					animation.tweens.push( tween );
					return tween;
				},
				stop: function( gotoEnd ) {
					var index = 0,
	
						// If we are going to the end, we want to run all the tweens
						// otherwise we skip this part
						length = gotoEnd ? animation.tweens.length : 0;
					if ( stopped ) {
						return this;
					}
					stopped = true;
					for ( ; index < length; index++ ) {
						animation.tweens[ index ].run( 1 );
					}
	
					// Resolve when we played the last frame; otherwise, reject
					if ( gotoEnd ) {
						deferred.notifyWith( elem, [ animation, 1, 0 ] );
						deferred.resolveWith( elem, [ animation, gotoEnd ] );
					} else {
						deferred.rejectWith( elem, [ animation, gotoEnd ] );
					}
					return this;
				}
			} ),
			props = animation.props;
	
		propFilter( props, animation.opts.specialEasing );
	
		for ( ; index < length; index++ ) {
			result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
			if ( result ) {
				if ( jQuery.isFunction( result.stop ) ) {
					jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
						jQuery.proxy( result.stop, result );
				}
				return result;
			}
		}
	
		jQuery.map( props, createTween, animation );
	
		if ( jQuery.isFunction( animation.opts.start ) ) {
			animation.opts.start.call( elem, animation );
		}
	
		// Attach callbacks from options
		animation
			.progress( animation.opts.progress )
			.done( animation.opts.done, animation.opts.complete )
			.fail( animation.opts.fail )
			.always( animation.opts.always );
	
		jQuery.fx.timer(
			jQuery.extend( tick, {
				elem: elem,
				anim: animation,
				queue: animation.opts.queue
			} )
		);
	
		return animation;
	}
	
	jQuery.Animation = jQuery.extend( Animation, {
	
		tweeners: {
			"*": [ function( prop, value ) {
				var tween = this.createTween( prop, value );
				adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
				return tween;
			} ]
		},
	
		tweener: function( props, callback ) {
			if ( jQuery.isFunction( props ) ) {
				callback = props;
				props = [ "*" ];
			} else {
				props = props.match( rnothtmlwhite );
			}
	
			var prop,
				index = 0,
				length = props.length;
	
			for ( ; index < length; index++ ) {
				prop = props[ index ];
				Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
				Animation.tweeners[ prop ].unshift( callback );
			}
		},
	
		prefilters: [ defaultPrefilter ],
	
		prefilter: function( callback, prepend ) {
			if ( prepend ) {
				Animation.prefilters.unshift( callback );
			} else {
				Animation.prefilters.push( callback );
			}
		}
	} );
	
	jQuery.speed = function( speed, easing, fn ) {
		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
			complete: fn || !fn && easing ||
				jQuery.isFunction( speed ) && speed,
			duration: speed,
			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
		};
	
		// Go to the end state if fx are off
		if ( jQuery.fx.off ) {
			opt.duration = 0;
	
		} else {
			if ( typeof opt.duration !== "number" ) {
				if ( opt.duration in jQuery.fx.speeds ) {
					opt.duration = jQuery.fx.speeds[ opt.duration ];
	
				} else {
					opt.duration = jQuery.fx.speeds._default;
				}
			}
		}
	
		// Normalize opt.queue - true/undefined/null -> "fx"
		if ( opt.queue == null || opt.queue === true ) {
			opt.queue = "fx";
		}
	
		// Queueing
		opt.old = opt.complete;
	
		opt.complete = function() {
			if ( jQuery.isFunction( opt.old ) ) {
				opt.old.call( this );
			}
	
			if ( opt.queue ) {
				jQuery.dequeue( this, opt.queue );
			}
		};
	
		return opt;
	};
	
	jQuery.fn.extend( {
		fadeTo: function( speed, to, easing, callback ) {
	
			// Show any hidden elements after setting opacity to 0
			return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
	
				// Animate to the value specified
				.end().animate( { opacity: to }, speed, easing, callback );
		},
		animate: function( prop, speed, easing, callback ) {
			var empty = jQuery.isEmptyObject( prop ),
				optall = jQuery.speed( speed, easing, callback ),
				doAnimation = function() {
	
					// Operate on a copy of prop so per-property easing won't be lost
					var anim = Animation( this, jQuery.extend( {}, prop ), optall );
	
					// Empty animations, or finishing resolves immediately
					if ( empty || dataPriv.get( this, "finish" ) ) {
						anim.stop( true );
					}
				};
				doAnimation.finish = doAnimation;
	
			return empty || optall.queue === false ?
				this.each( doAnimation ) :
				this.queue( optall.queue, doAnimation );
		},
		stop: function( type, clearQueue, gotoEnd ) {
			var stopQueue = function( hooks ) {
				var stop = hooks.stop;
				delete hooks.stop;
				stop( gotoEnd );
			};
	
			if ( typeof type !== "string" ) {
				gotoEnd = clearQueue;
				clearQueue = type;
				type = undefined;
			}
			if ( clearQueue && type !== false ) {
				this.queue( type || "fx", [] );
			}
	
			return this.each( function() {
				var dequeue = true,
					index = type != null && type + "queueHooks",
					timers = jQuery.timers,
					data = dataPriv.get( this );
	
				if ( index ) {
					if ( data[ index ] && data[ index ].stop ) {
						stopQueue( data[ index ] );
					}
				} else {
					for ( index in data ) {
						if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
							stopQueue( data[ index ] );
						}
					}
				}
	
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this &&
						( type == null || timers[ index ].queue === type ) ) {
	
						timers[ index ].anim.stop( gotoEnd );
						dequeue = false;
						timers.splice( index, 1 );
					}
				}
	
				// Start the next in the queue if the last step wasn't forced.
				// Timers currently will call their complete callbacks, which
				// will dequeue but only if they were gotoEnd.
				if ( dequeue || !gotoEnd ) {
					jQuery.dequeue( this, type );
				}
			} );
		},
		finish: function( type ) {
			if ( type !== false ) {
				type = type || "fx";
			}
			return this.each( function() {
				var index,
					data = dataPriv.get( this ),
					queue = data[ type + "queue" ],
					hooks = data[ type + "queueHooks" ],
					timers = jQuery.timers,
					length = queue ? queue.length : 0;
	
				// Enable finishing flag on private data
				data.finish = true;
	
				// Empty the queue first
				jQuery.queue( this, type, [] );
	
				if ( hooks && hooks.stop ) {
					hooks.stop.call( this, true );
				}
	
				// Look for any active animations, and finish them
				for ( index = timers.length; index--; ) {
					if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
						timers[ index ].anim.stop( true );
						timers.splice( index, 1 );
					}
				}
	
				// Look for any animations in the old queue and finish them
				for ( index = 0; index < length; index++ ) {
					if ( queue[ index ] && queue[ index ].finish ) {
						queue[ index ].finish.call( this );
					}
				}
	
				// Turn off finishing flag
				delete data.finish;
			} );
		}
	} );
	
	jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
		var cssFn = jQuery.fn[ name ];
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return speed == null || typeof speed === "boolean" ?
				cssFn.apply( this, arguments ) :
				this.animate( genFx( name, true ), speed, easing, callback );
		};
	} );
	
	// Generate shortcuts for custom animations
	jQuery.each( {
		slideDown: genFx( "show" ),
		slideUp: genFx( "hide" ),
		slideToggle: genFx( "toggle" ),
		fadeIn: { opacity: "show" },
		fadeOut: { opacity: "hide" },
		fadeToggle: { opacity: "toggle" }
	}, function( name, props ) {
		jQuery.fn[ name ] = function( speed, easing, callback ) {
			return this.animate( props, speed, easing, callback );
		};
	} );
	
	jQuery.timers = [];
	jQuery.fx.tick = function() {
		var timer,
			i = 0,
			timers = jQuery.timers;
	
		fxNow = jQuery.now();
	
		for ( ; i < timers.length; i++ ) {
			timer = timers[ i ];
	
			// Run the timer and safely remove it when done (allowing for external removal)
			if ( !timer() && timers[ i ] === timer ) {
				timers.splice( i--, 1 );
			}
		}
	
		if ( !timers.length ) {
			jQuery.fx.stop();
		}
		fxNow = undefined;
	};
	
	jQuery.fx.timer = function( timer ) {
		jQuery.timers.push( timer );
		jQuery.fx.start();
	};
	
	jQuery.fx.interval = 13;
	jQuery.fx.start = function() {
		if ( inProgress ) {
			return;
		}
	
		inProgress = true;
		schedule();
	};
	
	jQuery.fx.stop = function() {
		inProgress = null;
	};
	
	jQuery.fx.speeds = {
		slow: 600,
		fast: 200,
	
		// Default speed
		_default: 400
	};
	
	
	// Based off of the plugin by Clint Helfers, with permission.
	// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
	jQuery.fn.delay = function( time, type ) {
		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
		type = type || "fx";
	
		return this.queue( type, function( next, hooks ) {
			var timeout = window.setTimeout( next, time );
			hooks.stop = function() {
				window.clearTimeout( timeout );
			};
		} );
	};
	
	
	( function() {
		var input = document.createElement( "input" ),
			select = document.createElement( "select" ),
			opt = select.appendChild( document.createElement( "option" ) );
	
		input.type = "checkbox";
	
		// Support: Android <=4.3 only
		// Default value for a checkbox should be "on"
		support.checkOn = input.value !== "";
	
		// Support: IE <=11 only
		// Must access selectedIndex to make default options select
		support.optSelected = opt.selected;
	
		// Support: IE <=11 only
		// An input loses its value after becoming a radio
		input = document.createElement( "input" );
		input.value = "t";
		input.type = "radio";
		support.radioValue = input.value === "t";
	} )();
	
	
	var boolHook,
		attrHandle = jQuery.expr.attrHandle;
	
	jQuery.fn.extend( {
		attr: function( name, value ) {
			return access( this, jQuery.attr, name, value, arguments.length > 1 );
		},
	
		removeAttr: function( name ) {
			return this.each( function() {
				jQuery.removeAttr( this, name );
			} );
		}
	} );
	
	jQuery.extend( {
		attr: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set attributes on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			// Fallback to prop when attributes are not supported
			if ( typeof elem.getAttribute === "undefined" ) {
				return jQuery.prop( elem, name, value );
			}
	
			// Attribute hooks are determined by the lowercase version
			// Grab necessary hook if one is defined
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
				hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
					( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
			}
	
			if ( value !== undefined ) {
				if ( value === null ) {
					jQuery.removeAttr( elem, name );
					return;
				}
	
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				elem.setAttribute( name, value + "" );
				return value;
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			ret = jQuery.find.attr( elem, name );
	
			// Non-existent attributes return null, we normalize to undefined
			return ret == null ? undefined : ret;
		},
	
		attrHooks: {
			type: {
				set: function( elem, value ) {
					if ( !support.radioValue && value === "radio" &&
						nodeName( elem, "input" ) ) {
						var val = elem.value;
						elem.setAttribute( "type", value );
						if ( val ) {
							elem.value = val;
						}
						return value;
					}
				}
			}
		},
	
		removeAttr: function( elem, value ) {
			var name,
				i = 0,
	
				// Attribute names can contain non-HTML whitespace characters
				// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
				attrNames = value && value.match( rnothtmlwhite );
	
			if ( attrNames && elem.nodeType === 1 ) {
				while ( ( name = attrNames[ i++ ] ) ) {
					elem.removeAttribute( name );
				}
			}
		}
	} );
	
	// Hooks for boolean attributes
	boolHook = {
		set: function( elem, value, name ) {
			if ( value === false ) {
	
				// Remove boolean attributes when set to false
				jQuery.removeAttr( elem, name );
			} else {
				elem.setAttribute( name, name );
			}
			return name;
		}
	};
	
	jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
		var getter = attrHandle[ name ] || jQuery.find.attr;
	
		attrHandle[ name ] = function( elem, name, isXML ) {
			var ret, handle,
				lowercaseName = name.toLowerCase();
	
			if ( !isXML ) {
	
				// Avoid an infinite loop by temporarily removing this function from the getter
				handle = attrHandle[ lowercaseName ];
				attrHandle[ lowercaseName ] = ret;
				ret = getter( elem, name, isXML ) != null ?
					lowercaseName :
					null;
				attrHandle[ lowercaseName ] = handle;
			}
			return ret;
		};
	} );
	
	
	
	
	var rfocusable = /^(?:input|select|textarea|button)$/i,
		rclickable = /^(?:a|area)$/i;
	
	jQuery.fn.extend( {
		prop: function( name, value ) {
			return access( this, jQuery.prop, name, value, arguments.length > 1 );
		},
	
		removeProp: function( name ) {
			return this.each( function() {
				delete this[ jQuery.propFix[ name ] || name ];
			} );
		}
	} );
	
	jQuery.extend( {
		prop: function( elem, name, value ) {
			var ret, hooks,
				nType = elem.nodeType;
	
			// Don't get/set properties on text, comment and attribute nodes
			if ( nType === 3 || nType === 8 || nType === 2 ) {
				return;
			}
	
			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
	
				// Fix name and attach hooks
				name = jQuery.propFix[ name ] || name;
				hooks = jQuery.propHooks[ name ];
			}
	
			if ( value !== undefined ) {
				if ( hooks && "set" in hooks &&
					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
					return ret;
				}
	
				return ( elem[ name ] = value );
			}
	
			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
				return ret;
			}
	
			return elem[ name ];
		},
	
		propHooks: {
			tabIndex: {
				get: function( elem ) {
	
					// Support: IE <=9 - 11 only
					// elem.tabIndex doesn't always return the
					// correct value when it hasn't been explicitly set
					// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
					// Use proper attribute retrieval(#12072)
					var tabindex = jQuery.find.attr( elem, "tabindex" );
	
					if ( tabindex ) {
						return parseInt( tabindex, 10 );
					}
	
					if (
						rfocusable.test( elem.nodeName ) ||
						rclickable.test( elem.nodeName ) &&
						elem.href
					) {
						return 0;
					}
	
					return -1;
				}
			}
		},
	
		propFix: {
			"for": "htmlFor",
			"class": "className"
		}
	} );
	
	// Support: IE <=11 only
	// Accessing the selectedIndex property
	// forces the browser to respect setting selected
	// on the option
	// The getter ensures a default option is selected
	// when in an optgroup
	// eslint rule "no-unused-expressions" is disabled for this code
	// since it considers such accessions noop
	if ( !support.optSelected ) {
		jQuery.propHooks.selected = {
			get: function( elem ) {
	
				/* eslint no-unused-expressions: "off" */
	
				var parent = elem.parentNode;
				if ( parent && parent.parentNode ) {
					parent.parentNode.selectedIndex;
				}
				return null;
			},
			set: function( elem ) {
	
				/* eslint no-unused-expressions: "off" */
	
				var parent = elem.parentNode;
				if ( parent ) {
					parent.selectedIndex;
	
					if ( parent.parentNode ) {
						parent.parentNode.selectedIndex;
					}
				}
			}
		};
	}
	
	jQuery.each( [
		"tabIndex",
		"readOnly",
		"maxLength",
		"cellSpacing",
		"cellPadding",
		"rowSpan",
		"colSpan",
		"useMap",
		"frameBorder",
		"contentEditable"
	], function() {
		jQuery.propFix[ this.toLowerCase() ] = this;
	} );
	
	
	
	
		// Strip and collapse whitespace according to HTML spec
		// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
		function stripAndCollapse( value ) {
			var tokens = value.match( rnothtmlwhite ) || [];
			return tokens.join( " " );
		}
	
	
	function getClass( elem ) {
		return elem.getAttribute && elem.getAttribute( "class" ) || "";
	}
	
	jQuery.fn.extend( {
		addClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnothtmlwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
					cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
							if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
								cur += clazz + " ";
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = stripAndCollapse( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		removeClass: function( value ) {
			var classes, elem, cur, curValue, clazz, j, finalValue,
				i = 0;
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( j ) {
					jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
				} );
			}
	
			if ( !arguments.length ) {
				return this.attr( "class", "" );
			}
	
			if ( typeof value === "string" && value ) {
				classes = value.match( rnothtmlwhite ) || [];
	
				while ( ( elem = this[ i++ ] ) ) {
					curValue = getClass( elem );
	
					// This expression is here for better compressibility (see addClass)
					cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
	
					if ( cur ) {
						j = 0;
						while ( ( clazz = classes[ j++ ] ) ) {
	
							// Remove *all* instances
							while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
								cur = cur.replace( " " + clazz + " ", " " );
							}
						}
	
						// Only assign if different to avoid unneeded rendering.
						finalValue = stripAndCollapse( cur );
						if ( curValue !== finalValue ) {
							elem.setAttribute( "class", finalValue );
						}
					}
				}
			}
	
			return this;
		},
	
		toggleClass: function( value, stateVal ) {
			var type = typeof value;
	
			if ( typeof stateVal === "boolean" && type === "string" ) {
				return stateVal ? this.addClass( value ) : this.removeClass( value );
			}
	
			if ( jQuery.isFunction( value ) ) {
				return this.each( function( i ) {
					jQuery( this ).toggleClass(
						value.call( this, i, getClass( this ), stateVal ),
						stateVal
					);
				} );
			}
	
			return this.each( function() {
				var className, i, self, classNames;
	
				if ( type === "string" ) {
	
					// Toggle individual class names
					i = 0;
					self = jQuery( this );
					classNames = value.match( rnothtmlwhite ) || [];
	
					while ( ( className = classNames[ i++ ] ) ) {
	
						// Check each className given, space separated list
						if ( self.hasClass( className ) ) {
							self.removeClass( className );
						} else {
							self.addClass( className );
						}
					}
	
				// Toggle whole class name
				} else if ( value === undefined || type === "boolean" ) {
					className = getClass( this );
					if ( className ) {
	
						// Store className if set
						dataPriv.set( this, "__className__", className );
					}
	
					// If the element has a class name or if we're passed `false`,
					// then remove the whole classname (if there was one, the above saved it).
					// Otherwise bring back whatever was previously saved (if anything),
					// falling back to the empty string if nothing was stored.
					if ( this.setAttribute ) {
						this.setAttribute( "class",
							className || value === false ?
							"" :
							dataPriv.get( this, "__className__" ) || ""
						);
					}
				}
			} );
		},
	
		hasClass: function( selector ) {
			var className, elem,
				i = 0;
	
			className = " " + selector + " ";
			while ( ( elem = this[ i++ ] ) ) {
				if ( elem.nodeType === 1 &&
					( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
						return true;
				}
			}
	
			return false;
		}
	} );
	
	
	
	
	var rreturn = /\r/g;
	
	jQuery.fn.extend( {
		val: function( value ) {
			var hooks, ret, isFunction,
				elem = this[ 0 ];
	
			if ( !arguments.length ) {
				if ( elem ) {
					hooks = jQuery.valHooks[ elem.type ] ||
						jQuery.valHooks[ elem.nodeName.toLowerCase() ];
	
					if ( hooks &&
						"get" in hooks &&
						( ret = hooks.get( elem, "value" ) ) !== undefined
					) {
						return ret;
					}
	
					ret = elem.value;
	
					// Handle most common string cases
					if ( typeof ret === "string" ) {
						return ret.replace( rreturn, "" );
					}
	
					// Handle cases where value is null/undef or number
					return ret == null ? "" : ret;
				}
	
				return;
			}
	
			isFunction = jQuery.isFunction( value );
	
			return this.each( function( i ) {
				var val;
	
				if ( this.nodeType !== 1 ) {
					return;
				}
	
				if ( isFunction ) {
					val = value.call( this, i, jQuery( this ).val() );
				} else {
					val = value;
				}
	
				// Treat null/undefined as ""; convert numbers to string
				if ( val == null ) {
					val = "";
	
				} else if ( typeof val === "number" ) {
					val += "";
	
				} else if ( Array.isArray( val ) ) {
					val = jQuery.map( val, function( value ) {
						return value == null ? "" : value + "";
					} );
				}
	
				hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
	
				// If set returns undefined, fall back to normal setting
				if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
					this.value = val;
				}
			} );
		}
	} );
	
	jQuery.extend( {
		valHooks: {
			option: {
				get: function( elem ) {
	
					var val = jQuery.find.attr( elem, "value" );
					return val != null ?
						val :
	
						// Support: IE <=10 - 11 only
						// option.text throws exceptions (#14686, #14858)
						// Strip and collapse whitespace
						// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
						stripAndCollapse( jQuery.text( elem ) );
				}
			},
			select: {
				get: function( elem ) {
					var value, option, i,
						options = elem.options,
						index = elem.selectedIndex,
						one = elem.type === "select-one",
						values = one ? null : [],
						max = one ? index + 1 : options.length;
	
					if ( index < 0 ) {
						i = max;
	
					} else {
						i = one ? index : 0;
					}
	
					// Loop through all the selected options
					for ( ; i < max; i++ ) {
						option = options[ i ];
	
						// Support: IE <=9 only
						// IE8-9 doesn't update selected after form reset (#2551)
						if ( ( option.selected || i === index ) &&
	
								// Don't return options that are disabled or in a disabled optgroup
								!option.disabled &&
								( !option.parentNode.disabled ||
									!nodeName( option.parentNode, "optgroup" ) ) ) {
	
							// Get the specific value for the option
							value = jQuery( option ).val();
	
							// We don't need an array for one selects
							if ( one ) {
								return value;
							}
	
							// Multi-Selects return an array
							values.push( value );
						}
					}
	
					return values;
				},
	
				set: function( elem, value ) {
					var optionSet, option,
						options = elem.options,
						values = jQuery.makeArray( value ),
						i = options.length;
	
					while ( i-- ) {
						option = options[ i ];
	
						/* eslint-disable no-cond-assign */
	
						if ( option.selected =
							jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
						) {
							optionSet = true;
						}
	
						/* eslint-enable no-cond-assign */
					}
	
					// Force browsers to behave consistently when non-matching value is set
					if ( !optionSet ) {
						elem.selectedIndex = -1;
					}
					return values;
				}
			}
		}
	} );
	
	// Radios and checkboxes getter/setter
	jQuery.each( [ "radio", "checkbox" ], function() {
		jQuery.valHooks[ this ] = {
			set: function( elem, value ) {
				if ( Array.isArray( value ) ) {
					return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
				}
			}
		};
		if ( !support.checkOn ) {
			jQuery.valHooks[ this ].get = function( elem ) {
				return elem.getAttribute( "value" ) === null ? "on" : elem.value;
			};
		}
	} );
	
	
	
	
	// Return jQuery for attributes-only inclusion
	
	
	var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
	
	jQuery.extend( jQuery.event, {
	
		trigger: function( event, data, elem, onlyHandlers ) {
	
			var i, cur, tmp, bubbleType, ontype, handle, special,
				eventPath = [ elem || document ],
				type = hasOwn.call( event, "type" ) ? event.type : event,
				namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
	
			cur = tmp = elem = elem || document;
	
			// Don't do events on text and comment nodes
			if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
				return;
			}
	
			// focus/blur morphs to focusin/out; ensure we're not firing them right now
			if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
				return;
			}
	
			if ( type.indexOf( "." ) > -1 ) {
	
				// Namespaced trigger; create a regexp to match event type in handle()
				namespaces = type.split( "." );
				type = namespaces.shift();
				namespaces.sort();
			}
			ontype = type.indexOf( ":" ) < 0 && "on" + type;
	
			// Caller can pass in a jQuery.Event object, Object, or just an event type string
			event = event[ jQuery.expando ] ?
				event :
				new jQuery.Event( type, typeof event === "object" && event );
	
			// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
			event.isTrigger = onlyHandlers ? 2 : 3;
			event.namespace = namespaces.join( "." );
			event.rnamespace = event.namespace ?
				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
				null;
	
			// Clean up the event in case it is being reused
			event.result = undefined;
			if ( !event.target ) {
				event.target = elem;
			}
	
			// Clone any incoming data and prepend the event, creating the handler arg list
			data = data == null ?
				[ event ] :
				jQuery.makeArray( data, [ event ] );
	
			// Allow special events to draw outside the lines
			special = jQuery.event.special[ type ] || {};
			if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
				return;
			}
	
			// Determine event propagation path in advance, per W3C events spec (#9951)
			// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
			if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
	
				bubbleType = special.delegateType || type;
				if ( !rfocusMorph.test( bubbleType + type ) ) {
					cur = cur.parentNode;
				}
				for ( ; cur; cur = cur.parentNode ) {
					eventPath.push( cur );
					tmp = cur;
				}
	
				// Only add window if we got to document (e.g., not plain obj or detached DOM)
				if ( tmp === ( elem.ownerDocument || document ) ) {
					eventPath.push( tmp.defaultView || tmp.parentWindow || window );
				}
			}
	
			// Fire handlers on the event path
			i = 0;
			while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
	
				event.type = i > 1 ?
					bubbleType :
					special.bindType || type;
	
				// jQuery handler
				handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
					dataPriv.get( cur, "handle" );
				if ( handle ) {
					handle.apply( cur, data );
				}
	
				// Native handler
				handle = ontype && cur[ ontype ];
				if ( handle && handle.apply && acceptData( cur ) ) {
					event.result = handle.apply( cur, data );
					if ( event.result === false ) {
						event.preventDefault();
					}
				}
			}
			event.type = type;
	
			// If nobody prevented the default action, do it now
			if ( !onlyHandlers && !event.isDefaultPrevented() ) {
	
				if ( ( !special._default ||
					special._default.apply( eventPath.pop(), data ) === false ) &&
					acceptData( elem ) ) {
	
					// Call a native DOM method on the target with the same name as the event.
					// Don't do default actions on window, that's where global variables be (#6170)
					if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
	
						// Don't re-trigger an onFOO event when we call its FOO() method
						tmp = elem[ ontype ];
	
						if ( tmp ) {
							elem[ ontype ] = null;
						}
	
						// Prevent re-triggering of the same event, since we already bubbled it above
						jQuery.event.triggered = type;
						elem[ type ]();
						jQuery.event.triggered = undefined;
	
						if ( tmp ) {
							elem[ ontype ] = tmp;
						}
					}
				}
			}
	
			return event.result;
		},
	
		// Piggyback on a donor event to simulate a different one
		// Used only for `focus(in | out)` events
		simulate: function( type, elem, event ) {
			var e = jQuery.extend(
				new jQuery.Event(),
				event,
				{
					type: type,
					isSimulated: true
				}
			);
	
			jQuery.event.trigger( e, null, elem );
		}
	
	} );
	
	jQuery.fn.extend( {
	
		trigger: function( type, data ) {
			return this.each( function() {
				jQuery.event.trigger( type, data, this );
			} );
		},
		triggerHandler: function( type, data ) {
			var elem = this[ 0 ];
			if ( elem ) {
				return jQuery.event.trigger( type, data, elem, true );
			}
		}
	} );
	
	
	jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
		"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
		"change select submit keydown keypress keyup contextmenu" ).split( " " ),
		function( i, name ) {
	
		// Handle event binding
		jQuery.fn[ name ] = function( data, fn ) {
			return arguments.length > 0 ?
				this.on( name, null, data, fn ) :
				this.trigger( name );
		};
	} );
	
	jQuery.fn.extend( {
		hover: function( fnOver, fnOut ) {
			return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
		}
	} );
	
	
	
	
	support.focusin = "onfocusin" in window;
	
	
	// Support: Firefox <=44
	// Firefox doesn't have focus(in | out) events
	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
	//
	// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
	// focus(in | out) events fire after focus & blur events,
	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
	// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
	if ( !support.focusin ) {
		jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
	
			// Attach a single capturing handler on the document while someone wants focusin/focusout
			var handler = function( event ) {
				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
			};
	
			jQuery.event.special[ fix ] = {
				setup: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix );
	
					if ( !attaches ) {
						doc.addEventListener( orig, handler, true );
					}
					dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
				},
				teardown: function() {
					var doc = this.ownerDocument || this,
						attaches = dataPriv.access( doc, fix ) - 1;
	
					if ( !attaches ) {
						doc.removeEventListener( orig, handler, true );
						dataPriv.remove( doc, fix );
	
					} else {
						dataPriv.access( doc, fix, attaches );
					}
				}
			};
		} );
	}
	var location = window.location;
	
	var nonce = jQuery.now();
	
	var rquery = ( /\?/ );
	
	
	
	// Cross-browser xml parsing
	jQuery.parseXML = function( data ) {
		var xml;
		if ( !data || typeof data !== "string" ) {
			return null;
		}
	
		// Support: IE 9 - 11 only
		// IE throws on parseFromString with invalid input.
		try {
			xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
		} catch ( e ) {
			xml = undefined;
		}
	
		if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
			jQuery.error( "Invalid XML: " + data );
		}
		return xml;
	};
	
	
	var
		rbracket = /\[\]$/,
		rCRLF = /\r?\n/g,
		rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
		rsubmittable = /^(?:input|select|textarea|keygen)/i;
	
	function buildParams( prefix, obj, traditional, add ) {
		var name;
	
		if ( Array.isArray( obj ) ) {
	
			// Serialize array item.
			jQuery.each( obj, function( i, v ) {
				if ( traditional || rbracket.test( prefix ) ) {
	
					// Treat each array item as a scalar.
					add( prefix, v );
	
				} else {
	
					// Item is non-scalar (array or object), encode its numeric index.
					buildParams(
						prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
						v,
						traditional,
						add
					);
				}
			} );
	
		} else if ( !traditional && jQuery.type( obj ) === "object" ) {
	
			// Serialize object item.
			for ( name in obj ) {
				buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
			}
	
		} else {
	
			// Serialize scalar item.
			add( prefix, obj );
		}
	}
	
	// Serialize an array of form elements or a set of
	// key/values into a query string
	jQuery.param = function( a, traditional ) {
		var prefix,
			s = [],
			add = function( key, valueOrFunction ) {
	
				// If value is a function, invoke it and use its return value
				var value = jQuery.isFunction( valueOrFunction ) ?
					valueOrFunction() :
					valueOrFunction;
	
				s[ s.length ] = encodeURIComponent( key ) + "=" +
					encodeURIComponent( value == null ? "" : value );
			};
	
		// If an array was passed in, assume that it is an array of form elements.
		if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
	
			// Serialize the form elements
			jQuery.each( a, function() {
				add( this.name, this.value );
			} );
	
		} else {
	
			// If traditional, encode the "old" way (the way 1.3.2 or older
			// did it), otherwise encode params recursively.
			for ( prefix in a ) {
				buildParams( prefix, a[ prefix ], traditional, add );
			}
		}
	
		// Return the resulting serialization
		return s.join( "&" );
	};
	
	jQuery.fn.extend( {
		serialize: function() {
			return jQuery.param( this.serializeArray() );
		},
		serializeArray: function() {
			return this.map( function() {
	
				// Can add propHook for "elements" to filter or add form elements
				var elements = jQuery.prop( this, "elements" );
				return elements ? jQuery.makeArray( elements ) : this;
			} )
			.filter( function() {
				var type = this.type;
	
				// Use .is( ":disabled" ) so that fieldset[disabled] works
				return this.name && !jQuery( this ).is( ":disabled" ) &&
					rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
					( this.checked || !rcheckableType.test( type ) );
			} )
			.map( function( i, elem ) {
				var val = jQuery( this ).val();
	
				if ( val == null ) {
					return null;
				}
	
				if ( Array.isArray( val ) ) {
					return jQuery.map( val, function( val ) {
						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
					} );
				}
	
				return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
			} ).get();
		}
	} );
	
	
	var
		r20 = /%20/g,
		rhash = /#.*$/,
		rantiCache = /([?&])_=[^&]*/,
		rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
	
		// #7653, #8125, #8152: local protocol detection
		rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
		rnoContent = /^(?:GET|HEAD)$/,
		rprotocol = /^\/\//,
	
		/* Prefilters
		 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
		 * 2) These are called:
		 *    - BEFORE asking for a transport
		 *    - AFTER param serialization (s.data is a string if s.processData is true)
		 * 3) key is the dataType
		 * 4) the catchall symbol "*" can be used
		 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
		 */
		prefilters = {},
	
		/* Transports bindings
		 * 1) key is the dataType
		 * 2) the catchall symbol "*" can be used
		 * 3) selection will start with transport dataType and THEN go to "*" if needed
		 */
		transports = {},
	
		// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
		allTypes = "*/".concat( "*" ),
	
		// Anchor tag for parsing the document origin
		originAnchor = document.createElement( "a" );
		originAnchor.href = location.href;
	
	// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
	function addToPrefiltersOrTransports( structure ) {
	
		// dataTypeExpression is optional and defaults to "*"
		return function( dataTypeExpression, func ) {
	
			if ( typeof dataTypeExpression !== "string" ) {
				func = dataTypeExpression;
				dataTypeExpression = "*";
			}
	
			var dataType,
				i = 0,
				dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
	
			if ( jQuery.isFunction( func ) ) {
	
				// For each dataType in the dataTypeExpression
				while ( ( dataType = dataTypes[ i++ ] ) ) {
	
					// Prepend if requested
					if ( dataType[ 0 ] === "+" ) {
						dataType = dataType.slice( 1 ) || "*";
						( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
	
					// Otherwise append
					} else {
						( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
					}
				}
			}
		};
	}
	
	// Base inspection function for prefilters and transports
	function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
	
		var inspected = {},
			seekingTransport = ( structure === transports );
	
		function inspect( dataType ) {
			var selected;
			inspected[ dataType ] = true;
			jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
				var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
				if ( typeof dataTypeOrTransport === "string" &&
					!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
	
					options.dataTypes.unshift( dataTypeOrTransport );
					inspect( dataTypeOrTransport );
					return false;
				} else if ( seekingTransport ) {
					return !( selected = dataTypeOrTransport );
				}
			} );
			return selected;
		}
	
		return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
	}
	
	// A special extend for ajax options
	// that takes "flat" options (not to be deep extended)
	// Fixes #9887
	function ajaxExtend( target, src ) {
		var key, deep,
			flatOptions = jQuery.ajaxSettings.flatOptions || {};
	
		for ( key in src ) {
			if ( src[ key ] !== undefined ) {
				( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
			}
		}
		if ( deep ) {
			jQuery.extend( true, target, deep );
		}
	
		return target;
	}
	
	/* Handles responses to an ajax request:
	 * - finds the right dataType (mediates between content-type and expected dataType)
	 * - returns the corresponding response
	 */
	function ajaxHandleResponses( s, jqXHR, responses ) {
	
		var ct, type, finalDataType, firstDataType,
			contents = s.contents,
			dataTypes = s.dataTypes;
	
		// Remove auto dataType and get content-type in the process
		while ( dataTypes[ 0 ] === "*" ) {
			dataTypes.shift();
			if ( ct === undefined ) {
				ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
			}
		}
	
		// Check if we're dealing with a known content-type
		if ( ct ) {
			for ( type in contents ) {
				if ( contents[ type ] && contents[ type ].test( ct ) ) {
					dataTypes.unshift( type );
					break;
				}
			}
		}
	
		// Check to see if we have a response for the expected dataType
		if ( dataTypes[ 0 ] in responses ) {
			finalDataType = dataTypes[ 0 ];
		} else {
	
			// Try convertible dataTypes
			for ( type in responses ) {
				if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
					finalDataType = type;
					break;
				}
				if ( !firstDataType ) {
					firstDataType = type;
				}
			}
	
			// Or just use first one
			finalDataType = finalDataType || firstDataType;
		}
	
		// If we found a dataType
		// We add the dataType to the list if needed
		// and return the corresponding response
		if ( finalDataType ) {
			if ( finalDataType !== dataTypes[ 0 ] ) {
				dataTypes.unshift( finalDataType );
			}
			return responses[ finalDataType ];
		}
	}
	
	/* Chain conversions given the request and the original response
	 * Also sets the responseXXX fields on the jqXHR instance
	 */
	function ajaxConvert( s, response, jqXHR, isSuccess ) {
		var conv2, current, conv, tmp, prev,
			converters = {},
	
			// Work with a copy of dataTypes in case we need to modify it for conversion
			dataTypes = s.dataTypes.slice();
	
		// Create converters map with lowercased keys
		if ( dataTypes[ 1 ] ) {
			for ( conv in s.converters ) {
				converters[ conv.toLowerCase() ] = s.converters[ conv ];
			}
		}
	
		current = dataTypes.shift();
	
		// Convert to each sequential dataType
		while ( current ) {
	
			if ( s.responseFields[ current ] ) {
				jqXHR[ s.responseFields[ current ] ] = response;
			}
	
			// Apply the dataFilter if provided
			if ( !prev && isSuccess && s.dataFilter ) {
				response = s.dataFilter( response, s.dataType );
			}
	
			prev = current;
			current = dataTypes.shift();
	
			if ( current ) {
	
				// There's only work to do if current dataType is non-auto
				if ( current === "*" ) {
	
					current = prev;
	
				// Convert response if prev dataType is non-auto and differs from current
				} else if ( prev !== "*" && prev !== current ) {
	
					// Seek a direct converter
					conv = converters[ prev + " " + current ] || converters[ "* " + current ];
	
					// If none found, seek a pair
					if ( !conv ) {
						for ( conv2 in converters ) {
	
							// If conv2 outputs current
							tmp = conv2.split( " " );
							if ( tmp[ 1 ] === current ) {
	
								// If prev can be converted to accepted input
								conv = converters[ prev + " " + tmp[ 0 ] ] ||
									converters[ "* " + tmp[ 0 ] ];
								if ( conv ) {
	
									// Condense equivalence converters
									if ( conv === true ) {
										conv = converters[ conv2 ];
	
									// Otherwise, insert the intermediate dataType
									} else if ( converters[ conv2 ] !== true ) {
										current = tmp[ 0 ];
										dataTypes.unshift( tmp[ 1 ] );
									}
									break;
								}
							}
						}
					}
	
					// Apply converter (if not an equivalence)
					if ( conv !== true ) {
	
						// Unless errors are allowed to bubble, catch and return them
						if ( conv && s.throws ) {
							response = conv( response );
						} else {
							try {
								response = conv( response );
							} catch ( e ) {
								return {
									state: "parsererror",
									error: conv ? e : "No conversion from " + prev + " to " + current
								};
							}
						}
					}
				}
			}
		}
	
		return { state: "success", data: response };
	}
	
	jQuery.extend( {
	
		// Counter for holding the number of active queries
		active: 0,
	
		// Last-Modified header cache for next request
		lastModified: {},
		etag: {},
	
		ajaxSettings: {
			url: location.href,
			type: "GET",
			isLocal: rlocalProtocol.test( location.protocol ),
			global: true,
			processData: true,
			async: true,
			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
	
			/*
			timeout: 0,
			data: null,
			dataType: null,
			username: null,
			password: null,
			cache: null,
			throws: false,
			traditional: false,
			headers: {},
			*/
	
			accepts: {
				"*": allTypes,
				text: "text/plain",
				html: "text/html",
				xml: "application/xml, text/xml",
				json: "application/json, text/javascript"
			},
	
			contents: {
				xml: /\bxml\b/,
				html: /\bhtml/,
				json: /\bjson\b/
			},
	
			responseFields: {
				xml: "responseXML",
				text: "responseText",
				json: "responseJSON"
			},
	
			// Data converters
			// Keys separate source (or catchall "*") and destination types with a single space
			converters: {
	
				// Convert anything to text
				"* text": String,
	
				// Text to html (true = no transformation)
				"text html": true,
	
				// Evaluate text as a json expression
				"text json": JSON.parse,
	
				// Parse text as xml
				"text xml": jQuery.parseXML
			},
	
			// For options that shouldn't be deep extended:
			// you can add your own custom options here if
			// and when you create one that shouldn't be
			// deep extended (see ajaxExtend)
			flatOptions: {
				url: true,
				context: true
			}
		},
	
		// Creates a full fledged settings object into target
		// with both ajaxSettings and settings fields.
		// If target is omitted, writes into ajaxSettings.
		ajaxSetup: function( target, settings ) {
			return settings ?
	
				// Building a settings object
				ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
	
				// Extending ajaxSettings
				ajaxExtend( jQuery.ajaxSettings, target );
		},
	
		ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
		ajaxTransport: addToPrefiltersOrTransports( transports ),
	
		// Main method
		ajax: function( url, options ) {
	
			// If url is an object, simulate pre-1.5 signature
			if ( typeof url === "object" ) {
				options = url;
				url = undefined;
			}
	
			// Force options to be an object
			options = options || {};
	
			var transport,
	
				// URL without anti-cache param
				cacheURL,
	
				// Response headers
				responseHeadersString,
				responseHeaders,
	
				// timeout handle
				timeoutTimer,
	
				// Url cleanup var
				urlAnchor,
	
				// Request state (becomes false upon send and true upon completion)
				completed,
	
				// To know if global events are to be dispatched
				fireGlobals,
	
				// Loop variable
				i,
	
				// uncached part of the url
				uncached,
	
				// Create the final options object
				s = jQuery.ajaxSetup( {}, options ),
	
				// Callbacks context
				callbackContext = s.context || s,
	
				// Context for global events is callbackContext if it is a DOM node or jQuery collection
				globalEventContext = s.context &&
					( callbackContext.nodeType || callbackContext.jquery ) ?
						jQuery( callbackContext ) :
						jQuery.event,
	
				// Deferreds
				deferred = jQuery.Deferred(),
				completeDeferred = jQuery.Callbacks( "once memory" ),
	
				// Status-dependent callbacks
				statusCode = s.statusCode || {},
	
				// Headers (they are sent all at once)
				requestHeaders = {},
				requestHeadersNames = {},
	
				// Default abort message
				strAbort = "canceled",
	
				// Fake xhr
				jqXHR = {
					readyState: 0,
	
					// Builds headers hashtable if needed
					getResponseHeader: function( key ) {
						var match;
						if ( completed ) {
							if ( !responseHeaders ) {
								responseHeaders = {};
								while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
									responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
								}
							}
							match = responseHeaders[ key.toLowerCase() ];
						}
						return match == null ? null : match;
					},
	
					// Raw string
					getAllResponseHeaders: function() {
						return completed ? responseHeadersString : null;
					},
	
					// Caches the header
					setRequestHeader: function( name, value ) {
						if ( completed == null ) {
							name = requestHeadersNames[ name.toLowerCase() ] =
								requestHeadersNames[ name.toLowerCase() ] || name;
							requestHeaders[ name ] = value;
						}
						return this;
					},
	
					// Overrides response content-type header
					overrideMimeType: function( type ) {
						if ( completed == null ) {
							s.mimeType = type;
						}
						return this;
					},
	
					// Status-dependent callbacks
					statusCode: function( map ) {
						var code;
						if ( map ) {
							if ( completed ) {
	
								// Execute the appropriate callbacks
								jqXHR.always( map[ jqXHR.status ] );
							} else {
	
								// Lazy-add the new callbacks in a way that preserves old ones
								for ( code in map ) {
									statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
								}
							}
						}
						return this;
					},
	
					// Cancel the request
					abort: function( statusText ) {
						var finalText = statusText || strAbort;
						if ( transport ) {
							transport.abort( finalText );
						}
						done( 0, finalText );
						return this;
					}
				};
	
			// Attach deferreds
			deferred.promise( jqXHR );
	
			// Add protocol if not provided (prefilters might expect it)
			// Handle falsy url in the settings object (#10093: consistency with old signature)
			// We also use the url parameter if available
			s.url = ( ( url || s.url || location.href ) + "" )
				.replace( rprotocol, location.protocol + "//" );
	
			// Alias method option to type as per ticket #12004
			s.type = options.method || options.type || s.method || s.type;
	
			// Extract dataTypes list
			s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
	
			// A cross-domain request is in order when the origin doesn't match the current origin.
			if ( s.crossDomain == null ) {
				urlAnchor = document.createElement( "a" );
	
				// Support: IE <=8 - 11, Edge 12 - 13
				// IE throws exception on accessing the href property if url is malformed,
				// e.g. http://example.com:80x/
				try {
					urlAnchor.href = s.url;
	
					// Support: IE <=8 - 11 only
					// Anchor's host property isn't correctly set when s.url is relative
					urlAnchor.href = urlAnchor.href;
					s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
						urlAnchor.protocol + "//" + urlAnchor.host;
				} catch ( e ) {
	
					// If there is an error parsing the URL, assume it is crossDomain,
					// it can be rejected by the transport if it is invalid
					s.crossDomain = true;
				}
			}
	
			// Convert data if not already a string
			if ( s.data && s.processData && typeof s.data !== "string" ) {
				s.data = jQuery.param( s.data, s.traditional );
			}
	
			// Apply prefilters
			inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
	
			// If request was aborted inside a prefilter, stop there
			if ( completed ) {
				return jqXHR;
			}
	
			// We can fire global events as of now if asked to
			// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
			fireGlobals = jQuery.event && s.global;
	
			// Watch for a new set of requests
			if ( fireGlobals && jQuery.active++ === 0 ) {
				jQuery.event.trigger( "ajaxStart" );
			}
	
			// Uppercase the type
			s.type = s.type.toUpperCase();
	
			// Determine if request has content
			s.hasContent = !rnoContent.test( s.type );
	
			// Save the URL in case we're toying with the If-Modified-Since
			// and/or If-None-Match header later on
			// Remove hash to simplify url manipulation
			cacheURL = s.url.replace( rhash, "" );
	
			// More options handling for requests with no content
			if ( !s.hasContent ) {
	
				// Remember the hash so we can put it back
				uncached = s.url.slice( cacheURL.length );
	
				// If data is available, append data to url
				if ( s.data ) {
					cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
	
					// #9682: remove data so that it's not used in an eventual retry
					delete s.data;
				}
	
				// Add or update anti-cache param if needed
				if ( s.cache === false ) {
					cacheURL = cacheURL.replace( rantiCache, "$1" );
					uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
				}
	
				// Put hash and anti-cache on the URL that will be requested (gh-1732)
				s.url = cacheURL + uncached;
	
			// Change '%20' to '+' if this is encoded form body content (gh-2658)
			} else if ( s.data && s.processData &&
				( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
				s.data = s.data.replace( r20, "+" );
			}
	
			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
			if ( s.ifModified ) {
				if ( jQuery.lastModified[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
				}
				if ( jQuery.etag[ cacheURL ] ) {
					jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
				}
			}
	
			// Set the correct header, if data is being sent
			if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
				jqXHR.setRequestHeader( "Content-Type", s.contentType );
			}
	
			// Set the Accepts header for the server, depending on the dataType
			jqXHR.setRequestHeader(
				"Accept",
				s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
					s.accepts[ s.dataTypes[ 0 ] ] +
						( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
					s.accepts[ "*" ]
			);
	
			// Check for headers option
			for ( i in s.headers ) {
				jqXHR.setRequestHeader( i, s.headers[ i ] );
			}
	
			// Allow custom headers/mimetypes and early abort
			if ( s.beforeSend &&
				( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
	
				// Abort if not done already and return
				return jqXHR.abort();
			}
	
			// Aborting is no longer a cancellation
			strAbort = "abort";
	
			// Install callbacks on deferreds
			completeDeferred.add( s.complete );
			jqXHR.done( s.success );
			jqXHR.fail( s.error );
	
			// Get transport
			transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
	
			// If no transport, we auto-abort
			if ( !transport ) {
				done( -1, "No Transport" );
			} else {
				jqXHR.readyState = 1;
	
				// Send global event
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
				}
	
				// If request was aborted inside ajaxSend, stop there
				if ( completed ) {
					return jqXHR;
				}
	
				// Timeout
				if ( s.async && s.timeout > 0 ) {
					timeoutTimer = window.setTimeout( function() {
						jqXHR.abort( "timeout" );
					}, s.timeout );
				}
	
				try {
					completed = false;
					transport.send( requestHeaders, done );
				} catch ( e ) {
	
					// Rethrow post-completion exceptions
					if ( completed ) {
						throw e;
					}
	
					// Propagate others as results
					done( -1, e );
				}
			}
	
			// Callback for when everything is done
			function done( status, nativeStatusText, responses, headers ) {
				var isSuccess, success, error, response, modified,
					statusText = nativeStatusText;
	
				// Ignore repeat invocations
				if ( completed ) {
					return;
				}
	
				completed = true;
	
				// Clear timeout if it exists
				if ( timeoutTimer ) {
					window.clearTimeout( timeoutTimer );
				}
	
				// Dereference transport for early garbage collection
				// (no matter how long the jqXHR object will be used)
				transport = undefined;
	
				// Cache response headers
				responseHeadersString = headers || "";
	
				// Set readyState
				jqXHR.readyState = status > 0 ? 4 : 0;
	
				// Determine if successful
				isSuccess = status >= 200 && status < 300 || status === 304;
	
				// Get response data
				if ( responses ) {
					response = ajaxHandleResponses( s, jqXHR, responses );
				}
	
				// Convert no matter what (that way responseXXX fields are always set)
				response = ajaxConvert( s, response, jqXHR, isSuccess );
	
				// If successful, handle type chaining
				if ( isSuccess ) {
	
					// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
					if ( s.ifModified ) {
						modified = jqXHR.getResponseHeader( "Last-Modified" );
						if ( modified ) {
							jQuery.lastModified[ cacheURL ] = modified;
						}
						modified = jqXHR.getResponseHeader( "etag" );
						if ( modified ) {
							jQuery.etag[ cacheURL ] = modified;
						}
					}
	
					// if no content
					if ( status === 204 || s.type === "HEAD" ) {
						statusText = "nocontent";
	
					// if not modified
					} else if ( status === 304 ) {
						statusText = "notmodified";
	
					// If we have data, let's convert it
					} else {
						statusText = response.state;
						success = response.data;
						error = response.error;
						isSuccess = !error;
					}
				} else {
	
					// Extract error from statusText and normalize for non-aborts
					error = statusText;
					if ( status || !statusText ) {
						statusText = "error";
						if ( status < 0 ) {
							status = 0;
						}
					}
				}
	
				// Set data for the fake xhr object
				jqXHR.status = status;
				jqXHR.statusText = ( nativeStatusText || statusText ) + "";
	
				// Success/Error
				if ( isSuccess ) {
					deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
				} else {
					deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
				}
	
				// Status-dependent callbacks
				jqXHR.statusCode( statusCode );
				statusCode = undefined;
	
				if ( fireGlobals ) {
					globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
						[ jqXHR, s, isSuccess ? success : error ] );
				}
	
				// Complete
				completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
	
				if ( fireGlobals ) {
					globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
	
					// Handle the global AJAX counter
					if ( !( --jQuery.active ) ) {
						jQuery.event.trigger( "ajaxStop" );
					}
				}
			}
	
			return jqXHR;
		},
	
		getJSON: function( url, data, callback ) {
			return jQuery.get( url, data, callback, "json" );
		},
	
		getScript: function( url, callback ) {
			return jQuery.get( url, undefined, callback, "script" );
		}
	} );
	
	jQuery.each( [ "get", "post" ], function( i, method ) {
		jQuery[ method ] = function( url, data, callback, type ) {
	
			// Shift arguments if data argument was omitted
			if ( jQuery.isFunction( data ) ) {
				type = type || callback;
				callback = data;
				data = undefined;
			}
	
			// The url can be an options object (which then must have .url)
			return jQuery.ajax( jQuery.extend( {
				url: url,
				type: method,
				dataType: type,
				data: data,
				success: callback
			}, jQuery.isPlainObject( url ) && url ) );
		};
	} );
	
	
	jQuery._evalUrl = function( url ) {
		return jQuery.ajax( {
			url: url,
	
			// Make this explicit, since user can override this through ajaxSetup (#11264)
			type: "GET",
			dataType: "script",
			cache: true,
			async: false,
			global: false,
			"throws": true
		} );
	};
	
	
	jQuery.fn.extend( {
		wrapAll: function( html ) {
			var wrap;
	
			if ( this[ 0 ] ) {
				if ( jQuery.isFunction( html ) ) {
					html = html.call( this[ 0 ] );
				}
	
				// The elements to wrap the target around
				wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
	
				if ( this[ 0 ].parentNode ) {
					wrap.insertBefore( this[ 0 ] );
				}
	
				wrap.map( function() {
					var elem = this;
	
					while ( elem.firstElementChild ) {
						elem = elem.firstElementChild;
					}
	
					return elem;
				} ).append( this );
			}
	
			return this;
		},
	
		wrapInner: function( html ) {
			if ( jQuery.isFunction( html ) ) {
				return this.each( function( i ) {
					jQuery( this ).wrapInner( html.call( this, i ) );
				} );
			}
	
			return this.each( function() {
				var self = jQuery( this ),
					contents = self.contents();
	
				if ( contents.length ) {
					contents.wrapAll( html );
	
				} else {
					self.append( html );
				}
			} );
		},
	
		wrap: function( html ) {
			var isFunction = jQuery.isFunction( html );
	
			return this.each( function( i ) {
				jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
			} );
		},
	
		unwrap: function( selector ) {
			this.parent( selector ).not( "body" ).each( function() {
				jQuery( this ).replaceWith( this.childNodes );
			} );
			return this;
		}
	} );
	
	
	jQuery.expr.pseudos.hidden = function( elem ) {
		return !jQuery.expr.pseudos.visible( elem );
	};
	jQuery.expr.pseudos.visible = function( elem ) {
		return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
	};
	
	
	
	
	jQuery.ajaxSettings.xhr = function() {
		try {
			return new window.XMLHttpRequest();
		} catch ( e ) {}
	};
	
	var xhrSuccessStatus = {
	
			// File protocol always yields status code 0, assume 200
			0: 200,
	
			// Support: IE <=9 only
			// #1450: sometimes IE returns 1223 when it should be 204
			1223: 204
		},
		xhrSupported = jQuery.ajaxSettings.xhr();
	
	support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
	support.ajax = xhrSupported = !!xhrSupported;
	
	jQuery.ajaxTransport( function( options ) {
		var callback, errorCallback;
	
		// Cross domain only allowed if supported through XMLHttpRequest
		if ( support.cors || xhrSupported && !options.crossDomain ) {
			return {
				send: function( headers, complete ) {
					var i,
						xhr = options.xhr();
	
					xhr.open(
						options.type,
						options.url,
						options.async,
						options.username,
						options.password
					);
	
					// Apply custom fields if provided
					if ( options.xhrFields ) {
						for ( i in options.xhrFields ) {
							xhr[ i ] = options.xhrFields[ i ];
						}
					}
	
					// Override mime type if needed
					if ( options.mimeType && xhr.overrideMimeType ) {
						xhr.overrideMimeType( options.mimeType );
					}
	
					// X-Requested-With header
					// For cross-domain requests, seeing as conditions for a preflight are
					// akin to a jigsaw puzzle, we simply never set it to be sure.
					// (it can always be set on a per-request basis or even using ajaxSetup)
					// For same-domain requests, won't change header if already provided.
					if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
						headers[ "X-Requested-With" ] = "XMLHttpRequest";
					}
	
					// Set headers
					for ( i in headers ) {
						xhr.setRequestHeader( i, headers[ i ] );
					}
	
					// Callback
					callback = function( type ) {
						return function() {
							if ( callback ) {
								callback = errorCallback = xhr.onload =
									xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
	
								if ( type === "abort" ) {
									xhr.abort();
								} else if ( type === "error" ) {
	
									// Support: IE <=9 only
									// On a manual native abort, IE9 throws
									// errors on any property access that is not readyState
									if ( typeof xhr.status !== "number" ) {
										complete( 0, "error" );
									} else {
										complete(
	
											// File: protocol always yields status 0; see #8605, #14207
											xhr.status,
											xhr.statusText
										);
									}
								} else {
									complete(
										xhrSuccessStatus[ xhr.status ] || xhr.status,
										xhr.statusText,
	
										// Support: IE <=9 only
										// IE9 has no XHR2 but throws on binary (trac-11426)
										// For XHR2 non-text, let the caller handle it (gh-2498)
										( xhr.responseType || "text" ) !== "text"  ||
										typeof xhr.responseText !== "string" ?
											{ binary: xhr.response } :
											{ text: xhr.responseText },
										xhr.getAllResponseHeaders()
									);
								}
							}
						};
					};
	
					// Listen to events
					xhr.onload = callback();
					errorCallback = xhr.onerror = callback( "error" );
	
					// Support: IE 9 only
					// Use onreadystatechange to replace onabort
					// to handle uncaught aborts
					if ( xhr.onabort !== undefined ) {
						xhr.onabort = errorCallback;
					} else {
						xhr.onreadystatechange = function() {
	
							// Check readyState before timeout as it changes
							if ( xhr.readyState === 4 ) {
	
								// Allow onerror to be called first,
								// but that will not handle a native abort
								// Also, save errorCallback to a variable
								// as xhr.onerror cannot be accessed
								window.setTimeout( function() {
									if ( callback ) {
										errorCallback();
									}
								} );
							}
						};
					}
	
					// Create the abort callback
					callback = callback( "abort" );
	
					try {
	
						// Do send the request (this may raise an exception)
						xhr.send( options.hasContent && options.data || null );
					} catch ( e ) {
	
						// #14683: Only rethrow if this hasn't been notified as an error yet
						if ( callback ) {
							throw e;
						}
					}
				},
	
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
	jQuery.ajaxPrefilter( function( s ) {
		if ( s.crossDomain ) {
			s.contents.script = false;
		}
	} );
	
	// Install script dataType
	jQuery.ajaxSetup( {
		accepts: {
			script: "text/javascript, application/javascript, " +
				"application/ecmascript, application/x-ecmascript"
		},
		contents: {
			script: /\b(?:java|ecma)script\b/
		},
		converters: {
			"text script": function( text ) {
				jQuery.globalEval( text );
				return text;
			}
		}
	} );
	
	// Handle cache's special case and crossDomain
	jQuery.ajaxPrefilter( "script", function( s ) {
		if ( s.cache === undefined ) {
			s.cache = false;
		}
		if ( s.crossDomain ) {
			s.type = "GET";
		}
	} );
	
	// Bind script tag hack transport
	jQuery.ajaxTransport( "script", function( s ) {
	
		// This transport only deals with cross domain requests
		if ( s.crossDomain ) {
			var script, callback;
			return {
				send: function( _, complete ) {
					script = jQuery( "<script>" ).prop( {
						charset: s.scriptCharset,
						src: s.url
					} ).on(
						"load error",
						callback = function( evt ) {
							script.remove();
							callback = null;
							if ( evt ) {
								complete( evt.type === "error" ? 404 : 200, evt.type );
							}
						}
					);
	
					// Use native DOM manipulation to avoid our domManip AJAX trickery
					document.head.appendChild( script[ 0 ] );
				},
				abort: function() {
					if ( callback ) {
						callback();
					}
				}
			};
		}
	} );
	
	
	
	
	var oldCallbacks = [],
		rjsonp = /(=)\?(?=&|$)|\?\?/;
	
	// Default jsonp settings
	jQuery.ajaxSetup( {
		jsonp: "callback",
		jsonpCallback: function() {
			var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
			this[ callback ] = true;
			return callback;
		}
	} );
	
	// Detect, normalize options and install callbacks for jsonp requests
	jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
	
		var callbackName, overwritten, responseContainer,
			jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
				"url" :
				typeof s.data === "string" &&
					( s.contentType || "" )
						.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
					rjsonp.test( s.data ) && "data"
			);
	
		// Handle iff the expected data type is "jsonp" or we have a parameter to set
		if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
	
			// Get callback name, remembering preexisting value associated with it
			callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
				s.jsonpCallback() :
				s.jsonpCallback;
	
			// Insert callback into url or form data
			if ( jsonProp ) {
				s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
			} else if ( s.jsonp !== false ) {
				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
			}
	
			// Use data converter to retrieve json after script execution
			s.converters[ "script json" ] = function() {
				if ( !responseContainer ) {
					jQuery.error( callbackName + " was not called" );
				}
				return responseContainer[ 0 ];
			};
	
			// Force json dataType
			s.dataTypes[ 0 ] = "json";
	
			// Install callback
			overwritten = window[ callbackName ];
			window[ callbackName ] = function() {
				responseContainer = arguments;
			};
	
			// Clean-up function (fires after converters)
			jqXHR.always( function() {
	
				// If previous value didn't exist - remove it
				if ( overwritten === undefined ) {
					jQuery( window ).removeProp( callbackName );
	
				// Otherwise restore preexisting value
				} else {
					window[ callbackName ] = overwritten;
				}
	
				// Save back as free
				if ( s[ callbackName ] ) {
	
					// Make sure that re-using the options doesn't screw things around
					s.jsonpCallback = originalSettings.jsonpCallback;
	
					// Save the callback name for future use
					oldCallbacks.push( callbackName );
				}
	
				// Call if it was a function and we have a response
				if ( responseContainer && jQuery.isFunction( overwritten ) ) {
					overwritten( responseContainer[ 0 ] );
				}
	
				responseContainer = overwritten = undefined;
			} );
	
			// Delegate to script
			return "script";
		}
	} );
	
	
	
	
	// Support: Safari 8 only
	// In Safari 8 documents created via document.implementation.createHTMLDocument
	// collapse sibling forms: the second one becomes a child of the first one.
	// Because of that, this security measure has to be disabled in Safari 8.
	// https://bugs.webkit.org/show_bug.cgi?id=137337
	support.createHTMLDocument = ( function() {
		var body = document.implementation.createHTMLDocument( "" ).body;
		body.innerHTML = "<form></form><form></form>";
		return body.childNodes.length === 2;
	} )();
	
	
	// Argument "data" should be string of html
	// context (optional): If specified, the fragment will be created in this context,
	// defaults to document
	// keepScripts (optional): If true, will include scripts passed in the html string
	jQuery.parseHTML = function( data, context, keepScripts ) {
		if ( typeof data !== "string" ) {
			return [];
		}
		if ( typeof context === "boolean" ) {
			keepScripts = context;
			context = false;
		}
	
		var base, parsed, scripts;
	
		if ( !context ) {
	
			// Stop scripts or inline event handlers from being executed immediately
			// by using document.implementation
			if ( support.createHTMLDocument ) {
				context = document.implementation.createHTMLDocument( "" );
	
				// Set the base href for the created document
				// so any parsed elements with URLs
				// are based on the document's URL (gh-2965)
				base = context.createElement( "base" );
				base.href = document.location.href;
				context.head.appendChild( base );
			} else {
				context = document;
			}
		}
	
		parsed = rsingleTag.exec( data );
		scripts = !keepScripts && [];
	
		// Single tag
		if ( parsed ) {
			return [ context.createElement( parsed[ 1 ] ) ];
		}
	
		parsed = buildFragment( [ data ], context, scripts );
	
		if ( scripts && scripts.length ) {
			jQuery( scripts ).remove();
		}
	
		return jQuery.merge( [], parsed.childNodes );
	};
	
	
	/**
	 * Load a url into a page
	 */
	jQuery.fn.load = function( url, params, callback ) {
		var selector, type, response,
			self = this,
			off = url.indexOf( " " );
	
		if ( off > -1 ) {
			selector = stripAndCollapse( url.slice( off ) );
			url = url.slice( 0, off );
		}
	
		// If it's a function
		if ( jQuery.isFunction( params ) ) {
	
			// We assume that it's the callback
			callback = params;
			params = undefined;
	
		// Otherwise, build a param string
		} else if ( params && typeof params === "object" ) {
			type = "POST";
		}
	
		// If we have elements to modify, make the request
		if ( self.length > 0 ) {
			jQuery.ajax( {
				url: url,
	
				// If "type" variable is undefined, then "GET" method will be used.
				// Make value of this field explicit since
				// user can override it through ajaxSetup method
				type: type || "GET",
				dataType: "html",
				data: params
			} ).done( function( responseText ) {
	
				// Save response for use in complete callback
				response = arguments;
	
				self.html( selector ?
	
					// If a selector was specified, locate the right elements in a dummy div
					// Exclude scripts to avoid IE 'Permission Denied' errors
					jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
	
					// Otherwise use the full result
					responseText );
	
			// If the request succeeds, this function gets "data", "status", "jqXHR"
			// but they are ignored because response was set above.
			// If it fails, this function gets "jqXHR", "status", "error"
			} ).always( callback && function( jqXHR, status ) {
				self.each( function() {
					callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
				} );
			} );
		}
	
		return this;
	};
	
	
	
	
	// Attach a bunch of functions for handling common AJAX events
	jQuery.each( [
		"ajaxStart",
		"ajaxStop",
		"ajaxComplete",
		"ajaxError",
		"ajaxSuccess",
		"ajaxSend"
	], function( i, type ) {
		jQuery.fn[ type ] = function( fn ) {
			return this.on( type, fn );
		};
	} );
	
	
	
	
	jQuery.expr.pseudos.animated = function( elem ) {
		return jQuery.grep( jQuery.timers, function( fn ) {
			return elem === fn.elem;
		} ).length;
	};
	
	
	
	
	jQuery.offset = {
		setOffset: function( elem, options, i ) {
			var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
				position = jQuery.css( elem, "position" ),
				curElem = jQuery( elem ),
				props = {};
	
			// Set position first, in-case top/left are set even on static elem
			if ( position === "static" ) {
				elem.style.position = "relative";
			}
	
			curOffset = curElem.offset();
			curCSSTop = jQuery.css( elem, "top" );
			curCSSLeft = jQuery.css( elem, "left" );
			calculatePosition = ( position === "absolute" || position === "fixed" ) &&
				( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
	
			// Need to be able to calculate position if either
			// top or left is auto and position is either absolute or fixed
			if ( calculatePosition ) {
				curPosition = curElem.position();
				curTop = curPosition.top;
				curLeft = curPosition.left;
	
			} else {
				curTop = parseFloat( curCSSTop ) || 0;
				curLeft = parseFloat( curCSSLeft ) || 0;
			}
	
			if ( jQuery.isFunction( options ) ) {
	
				// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
				options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
			}
	
			if ( options.top != null ) {
				props.top = ( options.top - curOffset.top ) + curTop;
			}
			if ( options.left != null ) {
				props.left = ( options.left - curOffset.left ) + curLeft;
			}
	
			if ( "using" in options ) {
				options.using.call( elem, props );
	
			} else {
				curElem.css( props );
			}
		}
	};
	
	jQuery.fn.extend( {
		offset: function( options ) {
	
			// Preserve chaining for setter
			if ( arguments.length ) {
				return options === undefined ?
					this :
					this.each( function( i ) {
						jQuery.offset.setOffset( this, options, i );
					} );
			}
	
			var doc, docElem, rect, win,
				elem = this[ 0 ];
	
			if ( !elem ) {
				return;
			}
	
			// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
			// Support: IE <=11 only
			// Running getBoundingClientRect on a
			// disconnected node in IE throws an error
			if ( !elem.getClientRects().length ) {
				return { top: 0, left: 0 };
			}
	
			rect = elem.getBoundingClientRect();
	
			doc = elem.ownerDocument;
			docElem = doc.documentElement;
			win = doc.defaultView;
	
			return {
				top: rect.top + win.pageYOffset - docElem.clientTop,
				left: rect.left + win.pageXOffset - docElem.clientLeft
			};
		},
	
		position: function() {
			if ( !this[ 0 ] ) {
				return;
			}
	
			var offsetParent, offset,
				elem = this[ 0 ],
				parentOffset = { top: 0, left: 0 };
	
			// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
			// because it is its only offset parent
			if ( jQuery.css( elem, "position" ) === "fixed" ) {
	
				// Assume getBoundingClientRect is there when computed position is fixed
				offset = elem.getBoundingClientRect();
	
			} else {
	
				// Get *real* offsetParent
				offsetParent = this.offsetParent();
	
				// Get correct offsets
				offset = this.offset();
				if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
					parentOffset = offsetParent.offset();
				}
	
				// Add offsetParent borders
				parentOffset = {
					top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
					left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
				};
			}
	
			// Subtract parent offsets and element margins
			return {
				top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
				left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
			};
		},
	
		// This method will return documentElement in the following cases:
		// 1) For the element inside the iframe without offsetParent, this method will return
		//    documentElement of the parent window
		// 2) For the hidden or detached element
		// 3) For body or html element, i.e. in case of the html node - it will return itself
		//
		// but those exceptions were never presented as a real life use-cases
		// and might be considered as more preferable results.
		//
		// This logic, however, is not guaranteed and can change at any point in the future
		offsetParent: function() {
			return this.map( function() {
				var offsetParent = this.offsetParent;
	
				while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
					offsetParent = offsetParent.offsetParent;
				}
	
				return offsetParent || documentElement;
			} );
		}
	} );
	
	// Create scrollLeft and scrollTop methods
	jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
		var top = "pageYOffset" === prop;
	
		jQuery.fn[ method ] = function( val ) {
			return access( this, function( elem, method, val ) {
	
				// Coalesce documents and windows
				var win;
				if ( jQuery.isWindow( elem ) ) {
					win = elem;
				} else if ( elem.nodeType === 9 ) {
					win = elem.defaultView;
				}
	
				if ( val === undefined ) {
					return win ? win[ prop ] : elem[ method ];
				}
	
				if ( win ) {
					win.scrollTo(
						!top ? val : win.pageXOffset,
						top ? val : win.pageYOffset
					);
	
				} else {
					elem[ method ] = val;
				}
			}, method, val, arguments.length );
		};
	} );
	
	// Support: Safari <=7 - 9.1, Chrome <=37 - 49
	// Add the top/left cssHooks using jQuery.fn.position
	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
	// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
	// getComputedStyle returns percent when specified for top/left/bottom/right;
	// rather than make the css module depend on the offset module, just check for it here
	jQuery.each( [ "top", "left" ], function( i, prop ) {
		jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
			function( elem, computed ) {
				if ( computed ) {
					computed = curCSS( elem, prop );
	
					// If curCSS returns percentage, fallback to offset
					return rnumnonpx.test( computed ) ?
						jQuery( elem ).position()[ prop ] + "px" :
						computed;
				}
			}
		);
	} );
	
	
	// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
	jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
		jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
			function( defaultExtra, funcName ) {
	
			// Margin is only for outerHeight, outerWidth
			jQuery.fn[ funcName ] = function( margin, value ) {
				var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
					extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
	
				return access( this, function( elem, type, value ) {
					var doc;
	
					if ( jQuery.isWindow( elem ) ) {
	
						// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
						return funcName.indexOf( "outer" ) === 0 ?
							elem[ "inner" + name ] :
							elem.document.documentElement[ "client" + name ];
					}
	
					// Get document width or height
					if ( elem.nodeType === 9 ) {
						doc = elem.documentElement;
	
						// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
						// whichever is greatest
						return Math.max(
							elem.body[ "scroll" + name ], doc[ "scroll" + name ],
							elem.body[ "offset" + name ], doc[ "offset" + name ],
							doc[ "client" + name ]
						);
					}
	
					return value === undefined ?
	
						// Get width or height on the element, requesting but not forcing parseFloat
						jQuery.css( elem, type, extra ) :
	
						// Set width or height on the element
						jQuery.style( elem, type, value, extra );
				}, type, chainable ? margin : undefined, chainable );
			};
		} );
	} );
	
	
	jQuery.fn.extend( {
	
		bind: function( types, data, fn ) {
			return this.on( types, null, data, fn );
		},
		unbind: function( types, fn ) {
			return this.off( types, null, fn );
		},
	
		delegate: function( selector, types, data, fn ) {
			return this.on( types, selector, data, fn );
		},
		undelegate: function( selector, types, fn ) {
	
			// ( namespace ) or ( selector, types [, fn] )
			return arguments.length === 1 ?
				this.off( selector, "**" ) :
				this.off( types, selector || "**", fn );
		}
	} );
	
	jQuery.holdReady = function( hold ) {
		if ( hold ) {
			jQuery.readyWait++;
		} else {
			jQuery.ready( true );
		}
	};
	jQuery.isArray = Array.isArray;
	jQuery.parseJSON = JSON.parse;
	jQuery.nodeName = nodeName;
	
	
	
	
	// Register as a named AMD module, since jQuery can be concatenated with other
	// files that may use define, but not via a proper concatenation script that
	// understands anonymous AMD modules. A named AMD is safest and most robust
	// way to register. Lowercase jquery is used because AMD module names are
	// derived from file names, and jQuery is normally delivered in a lowercase
	// file name. Do this after creating the global so that if an AMD module wants
	// to call noConflict to hide this version of jQuery, it will work.
	
	// Note that for maximum portability, libraries that are not jQuery should
	// declare themselves as anonymous modules, and avoid setting a global if an
	// AMD loader is present. jQuery is a special case. For more information, see
	// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
	
	if ( true ) {
		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
			return jQuery;
		}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	}
	
	
	
	
	var
	
		// Map over jQuery in case of overwrite
		_jQuery = window.jQuery,
	
		// Map over the $ in case of overwrite
		_$ = window.$;
	
	jQuery.noConflict = function( deep ) {
		if ( window.$ === jQuery ) {
			window.$ = _$;
		}
	
		if ( deep && window.jQuery === jQuery ) {
			window.jQuery = _jQuery;
		}
	
		return jQuery;
	};
	
	// Expose jQuery and $ identifiers, even in AMD
	// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
	// and CommonJS for browser emulators (#13566)
	if ( !noGlobal ) {
		window.jQuery = window.$ = jQuery;
	}
	
	
	
	
	return jQuery;
	} );
	
})
/** END DEFINE BLOCK for jquery@3.2.1/dist/jquery.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/nativeview.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/nativeview.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*
	 This file contains substantial portions of https://github.com/akre54/Backbone.NativeView/blob/521188d9554b53d95d70ed34f878d8ac9fc10df2/backbone.nativeview.js, which has the following license:
	
	(c) 2015 Adam Krebs, Jimmy Yuen Ho Wong
	Backbone.NativeView may be freely distributed under the MIT license.
	
	Copyright (c) 2014 Adam Krebs
	
	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:
	
	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.
	
	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
	
	*/
	var Backbone = __jupyter_require__('backbone@1.2.0/backbone.js');
	// Caches a local reference to `Element.prototype` for faster access.
	var ElementProto = Element.prototype; //: typeof Element = (typeof Element !== 'undefined' && Element.prototype) || {};
	// Find the right `Element#matches` for IE>=9 and modern browsers.
	var matchesSelector = ElementProto.matches ||
	    ElementProto['webkitMatchesSelector'] ||
	    ElementProto['mozMatchesSelector'] ||
	    ElementProto['msMatchesSelector'] ||
	    ElementProto['oMatchesSelector'] ||
	    function matches(selector) {
	        var matches = (this.document || this.ownerDocument).querySelectorAll(selector), i = matches.length;
	        while (--i >= 0 && matches.item(i) !== this) { }
	        return i > -1;
	    };
	var NativeView = (function (_super) {
	    __extends(NativeView, _super);
	    function NativeView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    NativeView.prototype._removeElement = function () {
	        this.undelegateEvents();
	        if (this.el.parentNode) {
	            this.el.parentNode.removeChild(this.el);
	        }
	    };
	    // Apply the `element` to the view.
	    NativeView.prototype._setElement = function (element) {
	        this.el = element;
	    };
	    // Set a hash of attributes to the view's `el`. We use the "prop" version
	    // if available, falling back to `setAttribute` for the catch-all.
	    NativeView.prototype._setAttributes = function (attrs) {
	        for (var attr in attrs) {
	            attr in this.el ? this.el[attr] = attrs[attr] : this.el.setAttribute(attr, attrs[attr]);
	        }
	    };
	    /**
	     * Make an event delegation handler for the given `eventName` and `selector`
	     * and attach it to `this.el`.
	     * If selector is empty, the listener will be bound to `this.el`. If not, a
	     * new handler that will recursively traverse up the event target's DOM
	     * hierarchy looking for a node that matches the selector. If one is found,
	     * the event's `delegateTarget` property is set to it and the return the
	     * result of calling bound `listener` with the parameters given to the
	     * handler.
	     *
	     * This does not properly handle selectors for things like focus and blur (see
	     * https://github.com/jquery/jquery/blob/7d21f02b9ec9f655583e898350badf89165ed4d5/src/event.js#L442
	     * for some similar exceptional cases).
	     */
	    NativeView.prototype.delegate = function (eventName, selector, listener) {
	        if (typeof selector !== 'string') {
	            listener = selector;
	            selector = null;
	        }
	        // We have to initialize this here, instead of in the constructor, because the
	        // super constructor eventually calls this method before we get a chance to initialize
	        // this._domEvents to an empty list.
	        if (this._domEvents === void 0) {
	            this._domEvents = [];
	        }
	        var root = this.el;
	        var handler = selector ? function (e) {
	            var node = e.target || e.srcElement;
	            for (; node && node != root; node = node.parentNode) {
	                if (matchesSelector.call(node, selector)) {
	                    e.delegateTarget = node;
	                    if (listener.handleEvent) {
	                        return listener.handleEvent(e);
	                    }
	                    else {
	                        return listener(e);
	                    }
	                }
	            }
	        } : listener;
	        this.el.addEventListener(eventName, handler, false);
	        this._domEvents.push({ eventName: eventName, handler: handler, listener: listener, selector: selector });
	        return handler;
	    };
	    // Remove a single delegated event. Either `eventName` or `selector` must
	    // be included, `selector` and `listener` are optional.
	    NativeView.prototype.undelegate = function (eventName, selector, listener) {
	        if (typeof selector === 'function') {
	            listener = selector;
	            selector = null;
	        }
	        if (this.el && this._domEvents) {
	            var handlers = this._domEvents.slice();
	            var i = handlers.length;
	            while (i--) {
	                var item = handlers[i];
	                var match = item.eventName === eventName &&
	                    (listener ? item.listener === listener : true) &&
	                    (selector ? item.selector === selector : true);
	                if (!match)
	                    continue;
	                this.el.removeEventListener(item.eventName, item.handler, false);
	                this._domEvents.splice(i, 1);
	            }
	        }
	        return this;
	    };
	    // Remove all events created with `delegate` from `el`
	    NativeView.prototype.undelegateEvents = function () {
	        if (this.el && this._domEvents) {
	            for (var i = 0, len = this._domEvents.length; i < len; i++) {
	                var item = this._domEvents[i];
	                this.el.removeEventListener(item.eventName, item.handler, false);
	            }
	            ;
	            this._domEvents.length = 0;
	        }
	        return this;
	    };
	    return NativeView;
	}(Backbone.View));
	exports.NativeView = NativeView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/nativeview.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	// widget_core implements some common patterns for the core widget collection
	// that are not to be used directly by third-party widget authors.
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var jupyterWidgetSpecVersion = '3';
	var CoreWidgetModel = (function (_super) {
	    __extends(CoreWidgetModel, _super);
	    function CoreWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CoreWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'CoreWidgetModel',
	            _model_module_version: jupyterWidgetSpecVersion,
	            _view_module_version: jupyterWidgetSpecVersion
	        });
	    };
	    return CoreWidgetModel;
	}(widget_1.WidgetModel));
	exports.CoreWidgetModel = CoreWidgetModel;
	var CoreDOMWidgetModel = (function (_super) {
	    __extends(CoreDOMWidgetModel, _super);
	    function CoreDOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CoreDOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'CoreDOMWidgetModel',
	            _model_module_version: jupyterWidgetSpecVersion,
	            _view_module_version: jupyterWidgetSpecVersion
	        });
	    };
	    return CoreDOMWidgetModel;
	}(widget_1.DOMWidgetModel));
	exports.CoreDOMWidgetModel = CoreDOMWidgetModel;
	var CoreLabeledDOMWidgetModel = (function (_super) {
	    __extends(CoreLabeledDOMWidgetModel, _super);
	    function CoreLabeledDOMWidgetModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CoreLabeledDOMWidgetModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'CoreLabeledDOMWidgetModel',
	            _model_module_version: jupyterWidgetSpecVersion,
	            _view_module_version: jupyterWidgetSpecVersion
	        });
	    };
	    return CoreLabeledDOMWidgetModel;
	}(widget_1.LabeledDOMWidgetModel));
	exports.CoreLabeledDOMWidgetModel = CoreLabeledDOMWidgetModel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_layout.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_layout.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	/**
	 * css properties exposed by the layout widget with their default values.
	 */
	var css_properties = {
	    align_content: null,
	    align_items: null,
	    align_self: null,
	    border: null,
	    bottom: null,
	    display: null,
	    flex: null,
	    flex_flow: null,
	    height: null,
	    justify_content: null,
	    left: null,
	    margin: null,
	    max_height: null,
	    max_width: null,
	    min_height: null,
	    min_width: null,
	    overflow: null,
	    overflow_x: null,
	    overflow_y: null,
	    order: null,
	    padding: null,
	    right: null,
	    top: null,
	    visibility: null,
	    width: null
	};
	var LayoutModel = (function (_super) {
	    __extends(LayoutModel, _super);
	    function LayoutModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LayoutModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'LayoutModel',
	            _view_name: 'LayoutView'
	        }, css_properties);
	    };
	    return LayoutModel;
	}(widget_core_1.CoreWidgetModel));
	exports.LayoutModel = LayoutModel;
	var LayoutView = (function (_super) {
	    __extends(LayoutView, _super);
	    function LayoutView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    LayoutView.prototype.initialize = function (parameters) {
	        this._traitNames = [];
	        _super.prototype.initialize.call(this, parameters);
	        // Register the traits that live on the Python side
	        for (var _i = 0, _a = Object.keys(css_properties); _i < _a.length; _i++) {
	            var key = _a[_i];
	            this.registerTrait(key);
	        }
	    };
	    /**
	     * Register a CSS trait that is known by the model
	     * @param trait
	     */
	    LayoutView.prototype.registerTrait = function (trait) {
	        var _this = this;
	        this._traitNames.push(trait);
	        // Listen to changes, and set the value on change.
	        this.listenTo(this.model, 'change:' + trait, function (model, value) {
	            _this.handleChange(trait, value);
	        });
	        // Set the initial value on display.
	        this.handleChange(trait, this.model.get(trait));
	    };
	    /**
	     * Get the the name of the css property from the trait name
	     * @param  model attribute name
	     * @return css property name
	     */
	    LayoutView.prototype.css_name = function (trait) {
	        return trait.replace('_', '-');
	    };
	    /**
	     * Handles when a trait value changes
	     */
	    LayoutView.prototype.handleChange = function (trait, value) {
	        // should be synchronous so that we can measure later.
	        var parent = this.options.parent;
	        if (parent) {
	            if (value === null) {
	                parent.el.style.removeProperty(this.css_name(trait));
	            }
	            else {
	                parent.el.style[this.css_name(trait)] = value;
	            }
	        }
	        else {
	            console.warn('Style not applied because a parent view does not exist');
	        }
	    };
	    /**
	     * Remove the styling from the parent view.
	     */
	    LayoutView.prototype.unlayout = function () {
	        var _this = this;
	        var parent = this.options.parent;
	        this._traitNames.forEach(function (trait) {
	            if (parent) {
	                parent.el.style.removeProperty(_this.css_name(trait));
	            }
	            else {
	                console.warn('Style not removed because a parent view does not exist');
	            }
	        }, this);
	    };
	    return LayoutView;
	}(widget_1.WidgetView));
	exports.LayoutView = LayoutView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_layout.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_style.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_style.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var StyleModel = (function (_super) {
	    __extends(StyleModel, _super);
	    function StyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    StyleModel.prototype.defaults = function () {
	        var Derived = this.constructor;
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'StyleModel',
	            _view_name: 'StyleView',
	        }, _.reduce(Object.keys(Derived.styleProperties), function (obj, key) {
	            obj[key] = Derived.styleProperties[key].default;
	            return obj;
	        }, {}));
	    };
	    return StyleModel;
	}(widget_core_1.CoreWidgetModel));
	StyleModel.styleProperties = {};
	exports.StyleModel = StyleModel;
	var StyleView = (function (_super) {
	    __extends(StyleView, _super);
	    function StyleView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    StyleView.prototype.initialize = function (parameters) {
	        this._traitNames = [];
	        _super.prototype.initialize.call(this, parameters);
	        // Register the traits that live on the Python side
	        var ModelType = this.model.constructor;
	        for (var _i = 0, _a = Object.keys(ModelType.styleProperties); _i < _a.length; _i++) {
	            var key = _a[_i];
	            this.registerTrait(key);
	        }
	    };
	    /**
	     * Register a CSS trait that is known by the model
	     * @param trait
	     */
	    StyleView.prototype.registerTrait = function (trait) {
	        var _this = this;
	        this._traitNames.push(trait);
	        // Listen to changes, and set the value on change.
	        this.listenTo(this.model, 'change:' + trait, function (model, value) {
	            _this.handleChange(trait, value);
	        });
	        // Set the initial value on display.
	        this.handleChange(trait, this.model.get(trait));
	    };
	    /**
	     * Handles when a trait value changes
	     */
	    StyleView.prototype.handleChange = function (trait, value) {
	        // should be synchronous so that we can measure later.
	        var parent = this.options.parent;
	        if (parent) {
	            var ModelType = this.model.constructor;
	            var styleProperties = ModelType.styleProperties;
	            var attribute = styleProperties[trait].attribute;
	            var selector = styleProperties[trait].selector;
	            var elements = selector ? parent.el.querySelectorAll(selector) : [parent.el];
	            if (value === null) {
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style.removeProperty(attribute);
	                }
	            }
	            else {
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style[attribute] = value;
	                }
	            }
	        }
	        else {
	            console.warn('Style not applied because a parent view does not exist');
	        }
	    };
	    /**
	     * Remove the styling from the parent view.
	     */
	    StyleView.prototype.unstyle = function () {
	        var parent = this.options.parent;
	        var ModelType = this.model.constructor;
	        var styleProperties = ModelType.styleProperties;
	        this._traitNames.forEach(function (trait) {
	            if (parent) {
	                var attribute = styleProperties[trait].attribute;
	                var selector = styleProperties[trait].selector;
	                var elements = selector ? parent.el.querySelectorAll(selector) : [parent.el];
	                for (var i = 0; i !== elements.length; ++i) {
	                    elements[i].style.removeProperty(attribute);
	                }
	            }
	            else {
	                console.warn('Style not removed because a parent view does not exist');
	            }
	        }, this);
	    };
	    return StyleView;
	}(widget_1.WidgetView));
	exports.StyleView = StyleView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_style.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_link.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_link.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var DirectionalLinkModel = (function (_super) {
	    __extends(DirectionalLinkModel, _super);
	    function DirectionalLinkModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DirectionalLinkModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            target: undefined,
	            source: undefined,
	            _model_name: 'DirectionalLinkModel'
	        });
	    };
	    DirectionalLinkModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.on('change', this.updateBindings, this);
	        this.updateBindings();
	    };
	    DirectionalLinkModel.prototype.updateValue = function (sourceModel, sourceAttr, targetModel, targetAttr) {
	        if (this._updating) {
	            return;
	        }
	        this._updating = true;
	        try {
	            if (targetModel) {
	                targetModel.set(targetAttr, sourceModel.get(sourceAttr));
	                targetModel.save_changes();
	            }
	        }
	        finally {
	            this._updating = false;
	        }
	    };
	    DirectionalLinkModel.prototype.updateBindings = function () {
	        var _this = this;
	        this.cleanup();
	        _a = this.get('source') || [null, null], this.sourceModel = _a[0], this.sourceAttr = _a[1];
	        _b = this.get('target') || [null, null], this.targetModel = _b[0], this.targetAttr = _b[1];
	        if (this.sourceModel) {
	            this.listenTo(this.sourceModel, 'change:' + this.sourceAttr, function () {
	                _this.updateValue(_this.sourceModel, _this.sourceAttr, _this.targetModel, _this.targetAttr);
	            });
	            this.updateValue(this.sourceModel, this.sourceAttr, this.targetModel, this.targetAttr);
	            this.listenToOnce(this.sourceModel, 'destroy', this.cleanup);
	        }
	        if (this.targetModel) {
	            this.listenToOnce(this.targetModel, 'destroy', this.cleanup);
	        }
	        var _a, _b;
	    };
	    DirectionalLinkModel.prototype.cleanup = function () {
	        // Stop listening to 'change' and 'destroy' events of the source and target
	        if (this.sourceModel) {
	            this.stopListening(this.sourceModel, 'change:' + this.sourceAttr, null);
	            this.stopListening(this.sourceModel, 'destroy', null);
	        }
	        if (this.targetModel) {
	            this.stopListening(this.targetModel, 'destroy', null);
	        }
	    };
	    return DirectionalLinkModel;
	}(widget_core_1.CoreWidgetModel));
	DirectionalLinkModel.serializers = _.extend({
	    target: { deserialize: widget_1.unpack_models },
	    source: { deserialize: widget_1.unpack_models }
	}, widget_core_1.CoreWidgetModel.serializers);
	exports.DirectionalLinkModel = DirectionalLinkModel;
	var LinkModel = (function (_super) {
	    __extends(LinkModel, _super);
	    function LinkModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    LinkModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'LinkModel'
	        });
	    };
	    LinkModel.prototype.updateBindings = function () {
	        var _this = this;
	        _super.prototype.updateBindings.call(this);
	        if (this.targetModel) {
	            this.listenTo(this.targetModel, 'change:' + this.targetAttr, function () {
	                _this.updateValue(_this.targetModel, _this.targetAttr, _this.sourceModel, _this.sourceAttr);
	            });
	        }
	    };
	    LinkModel.prototype.cleanup = function () {
	        _super.prototype.cleanup.call(this);
	        if (this.targetModel) {
	            this.stopListening(this.targetModel, 'change:' + this.targetAttr, null);
	        }
	    };
	    return LinkModel;
	}(DirectionalLinkModel));
	exports.LinkModel = LinkModel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_link.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_bool.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_bool.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var BoolModel = (function (_super) {
	    __extends(BoolModel, _super);
	    function BoolModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoolModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: false,
	            disabled: false,
	            _model_name: 'BoolModel'
	        });
	    };
	    return BoolModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.BoolModel = BoolModel;
	var CheckboxModel = (function (_super) {
	    __extends(CheckboxModel, _super);
	    function CheckboxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    CheckboxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'CheckboxView',
	            _model_name: 'CheckboxModel'
	        });
	    };
	    return CheckboxModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.CheckboxModel = CheckboxModel;
	var CheckboxView = (function (_super) {
	    __extends(CheckboxView, _super);
	    function CheckboxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    CheckboxView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-checkbox');
	        this.checkbox = document.createElement('input');
	        this.checkbox.setAttribute('type', 'checkbox');
	        this.el.appendChild(this.checkbox);
	        this.update(); // Set defaults.
	    };
	    CheckboxView.prototype.events = function () {
	        return {
	            'click input[type="checkbox"]': '_handle_click'
	        };
	    };
	    /**
	     * Handles when the checkbox is clicked.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    CheckboxView.prototype._handle_click = function () {
	        var value = this.model.get('value');
	        this.model.set('value', !value, { updated_view: this });
	        this.touch();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed. The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    CheckboxView.prototype.update = function (options) {
	        this.checkbox.checked = this.model.get('value');
	        if (options === undefined || options.updated_view != this) {
	            this.checkbox.disabled = this.model.get('disabled');
	        }
	        return _super.prototype.update.call(this);
	    };
	    return CheckboxView;
	}(widget_1.LabeledDOMWidgetView));
	exports.CheckboxView = CheckboxView;
	var ToggleButtonModel = (function (_super) {
	    __extends(ToggleButtonModel, _super);
	    function ToggleButtonModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ToggleButtonModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'ToggleButtonView',
	            _model_name: 'ToggleButtonModel',
	            tooltip: '',
	            icon: '',
	            button_style: ''
	        });
	    };
	    return ToggleButtonModel;
	}(BoolModel));
	exports.ToggleButtonModel = ToggleButtonModel;
	var ToggleButtonView = (function (_super) {
	    __extends(ToggleButtonView, _super);
	    function ToggleButtonView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    ToggleButtonView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.className = 'jupyter-widgets jupyter-button widget-toggle-button';
	        this.listenTo(this.model, 'change:button_style', this.update_button_style);
	        this.set_button_style();
	        this.update(); // Set defaults.
	    };
	    ToggleButtonView.prototype.update_button_style = function () {
	        this.update_mapped_classes(ToggleButtonView.class_map, 'button_style');
	    };
	    ToggleButtonView.prototype.set_button_style = function () {
	        this.set_mapped_classes(ToggleButtonView.class_map, 'button_style');
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed. The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ToggleButtonView.prototype.update = function (options) {
	        if (this.model.get('value')) {
	            this.el.classList.add('mod-active');
	        }
	        else {
	            this.el.classList.remove('mod-active');
	        }
	        if (options === undefined || options.updated_view !== this) {
	            this.el.disabled = this.model.get('disabled');
	            this.el.setAttribute('title', this.model.get('tooltip'));
	            var description = this.model.get('description');
	            var icon = this.model.get('icon');
	            if (description.trim().length === 0 && icon.trim().length === 0) {
	                this.el.innerHTML = '&nbsp;'; // Preserve button height
	            }
	            else {
	                this.el.textContent = '';
	                if (icon.trim().length) {
	                    var i = document.createElement('i');
	                    this.el.appendChild(i);
	                    i.classList.add('fa');
	                    i.classList.add('fa-' + icon);
	                }
	                this.el.appendChild(document.createTextNode(description));
	            }
	        }
	        return _super.prototype.update.call(this);
	    };
	    ToggleButtonView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'click': '_handle_click'
	        };
	    };
	    /**
	     * Handles and validates user input.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    ToggleButtonView.prototype._handle_click = function (event) {
	        event.preventDefault();
	        var value = this.model.get('value');
	        this.model.set('value', !value, { updated_view: this });
	        this.touch();
	    };
	    Object.defineProperty(ToggleButtonView.prototype, "tagName", {
	        /**
	         * The default tag name.
	         *
	         * #### Notes
	         * This is a read-only attribute.
	         */
	        get: function () {
	            // We can't make this an attribute with a default value
	            // since it would be set after it is needed in the
	            // constructor.
	            return 'button';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ToggleButtonView;
	}(widget_1.DOMWidgetView));
	ToggleButtonView.class_map = {
	    primary: ['mod-primary'],
	    success: ['mod-success'],
	    info: ['mod-info'],
	    warning: ['mod-warning'],
	    danger: ['mod-danger']
	};
	exports.ToggleButtonView = ToggleButtonView;
	var ValidModel = (function (_super) {
	    __extends(ValidModel, _super);
	    function ValidModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ValidModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            readout: 'Invalid',
	            _view_name: 'ValidView',
	            _model_name: 'ValidModel'
	        });
	    };
	    return ValidModel;
	}(BoolModel));
	exports.ValidModel = ValidModel;
	var ValidView = (function (_super) {
	    __extends(ValidView, _super);
	    function ValidView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    ValidView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-valid');
	        this.el.classList.add('widget-inline-hbox');
	        var icon = document.createElement('i');
	        this.el.appendChild(icon);
	        this.readout = document.createElement('span');
	        this.readout.classList.add('widget-valid-readout');
	        this.readout.classList.add('widget-readout');
	        this.el.appendChild(this.readout);
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ValidView.prototype.update = function () {
	        this.el.classList.remove('mod-valid');
	        this.el.classList.remove('mod-invalid');
	        this.readout.textContent = this.model.get('readout');
	        if (this.model.get('value')) {
	            this.el.classList.add('mod-valid');
	        }
	        else {
	            this.el.classList.add('mod-invalid');
	        }
	    };
	    return ValidView;
	}(widget_1.LabeledDOMWidgetView));
	exports.ValidView = ValidView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_bool.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_button.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_button.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var widget_style_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_style.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var ButtonStyleModel = (function (_super) {
	    __extends(ButtonStyleModel, _super);
	    function ButtonStyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ButtonStyleModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ButtonStyleModel',
	        });
	    };
	    return ButtonStyleModel;
	}(widget_style_1.StyleModel));
	ButtonStyleModel.styleProperties = {
	    button_color: {
	        selector: '',
	        attribute: 'background-color',
	        default: null
	    },
	    font_weight: {
	        selector: '',
	        attribute: 'font-weight',
	        default: ''
	    }
	};
	exports.ButtonStyleModel = ButtonStyleModel;
	var ButtonModel = (function (_super) {
	    __extends(ButtonModel, _super);
	    function ButtonModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ButtonModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            description: '',
	            tooltip: '',
	            disabled: false,
	            icon: '',
	            button_style: '',
	            _view_name: 'ButtonView',
	            _model_name: 'ButtonModel',
	            style: void 0
	        });
	    };
	    return ButtonModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ButtonModel = ButtonModel;
	var ButtonView = (function (_super) {
	    __extends(ButtonView, _super);
	    function ButtonView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    ButtonView.prototype.render = function () {
	        this.el.className = 'jupyter-widgets jupyter-button widget-button';
	        this.listenTo(this.model, 'change:button_style', this.update_button_style);
	        this.set_button_style();
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed. The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ButtonView.prototype.update = function () {
	        this.el.disabled = this.model.get('disabled');
	        this.el.setAttribute('title', this.model.get('tooltip'));
	        var description = this.model.get('description');
	        var icon = this.model.get('icon');
	        if (description.trim().length || icon.trim().length) {
	            this.el.textContent = '';
	            if (icon.trim().length) {
	                var i = document.createElement('i');
	                i.classList.add('fa');
	                i.classList.add('fa-' + icon);
	                if (description.trim().length === 0) {
	                    i.classList.add('center');
	                }
	                this.el.appendChild(i);
	            }
	            this.el.appendChild(document.createTextNode(description));
	        }
	        return _super.prototype.update.call(this);
	    };
	    ButtonView.prototype.update_button_style = function () {
	        this.update_mapped_classes(ButtonView.class_map, 'button_style');
	    };
	    ButtonView.prototype.set_button_style = function () {
	        this.set_mapped_classes(ButtonView.class_map, 'button_style');
	    };
	    /**
	     * Dictionary of events and handlers
	     */
	    ButtonView.prototype.events = function () {
	        // TODO: return typing not needed in Typescript later than 1.8.x
	        // See http://stackoverflow.com/questions/22077023/why-cant-i-indirectly-return-an-object-literal-to-satisfy-an-index-signature-re and https://github.com/Microsoft/TypeScript/pull/7029
	        return { 'click': '_handle_click' };
	    };
	    /**
	     * Handles when the button is clicked.
	     */
	    ButtonView.prototype._handle_click = function (event) {
	        event.preventDefault();
	        this.send({ event: 'click' });
	    };
	    Object.defineProperty(ButtonView.prototype, "tagName", {
	        /**
	         * The default tag name.
	         *
	         * #### Notes
	         * This is a read-only attribute.
	         */
	        get: function () {
	            // We can't make this an attribute with a default value
	            // since it would be set after it is needed in the
	            // constructor.
	            return 'button';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ButtonView;
	}(widget_1.DOMWidgetView));
	ButtonView.class_map = {
	    primary: ['mod-primary'],
	    success: ['mod-success'],
	    info: ['mod-info'],
	    warning: ['mod-warning'],
	    danger: ['mod-danger']
	};
	exports.ButtonView = ButtonView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_button.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_box.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_box.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var utils_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js');
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.1.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.1.0/lib/index.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	var JupyterPhosphorPanelWidget = (function (_super) {
	    __extends(JupyterPhosphorPanelWidget, _super);
	    function JupyterPhosphorPanelWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        return _this;
	    }
	    /**
	     * Process the phosphor message.
	     *
	     * Any custom phosphor widget used inside a Jupyter widget should override
	     * the processMessage function like this.
	     */
	    JupyterPhosphorPanelWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        this._view.processPhosphorMessage(msg);
	    };
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorPanelWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    return JupyterPhosphorPanelWidget;
	}(widgets_1.Panel));
	exports.JupyterPhosphorPanelWidget = JupyterPhosphorPanelWidget;
	var BoxModel = (function (_super) {
	    __extends(BoxModel, _super);
	    function BoxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'BoxView',
	            _model_name: 'BoxModel',
	            children: [],
	            box_style: ''
	        });
	    };
	    return BoxModel;
	}(widget_core_1.CoreDOMWidgetModel));
	BoxModel.serializers = _.extend({
	    children: { deserialize: widget_1.unpack_models }
	}, widget_core_1.CoreDOMWidgetModel.serializers);
	exports.BoxModel = BoxModel;
	var HBoxModel = (function (_super) {
	    __extends(HBoxModel, _super);
	    function HBoxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    HBoxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'HBoxView',
	            _model_name: 'HBoxModel',
	        });
	    };
	    return HBoxModel;
	}(BoxModel));
	exports.HBoxModel = HBoxModel;
	var VBoxModel = (function (_super) {
	    __extends(VBoxModel, _super);
	    function VBoxModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    VBoxModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _view_name: 'VBoxView',
	            _model_name: 'VBoxModel',
	        });
	    };
	    return VBoxModel;
	}(BoxModel));
	exports.VBoxModel = VBoxModel;
	var BoxView = (function (_super) {
	    __extends(BoxView, _super);
	    function BoxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoxView.prototype._createElement = function (tagName) {
	        this.pWidget = new JupyterPhosphorPanelWidget({ view: this });
	        return this.pWidget.node;
	    };
	    BoxView.prototype._setElement = function (el) {
	        if (this.el || el !== this.pWidget.node) {
	            // Boxes don't allow setting the element beyond the initial creation.
	            throw new Error('Cannot reset the DOM element.');
	        }
	        this.el = this.pWidget.node;
	        this.$el = $(this.pWidget.node);
	    };
	    /**
	     * Public constructor
	     */
	    BoxView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.children_views = new widget_1.ViewList(this.add_child_model, null, this);
	        this.listenTo(this.model, 'change:children', this.update_children);
	        this.listenTo(this.model, 'change:box_style', this.update_box_style);
	        this.pWidget.addClass('jupyter-widgets');
	        this.pWidget.addClass('widget-container');
	        this.pWidget.addClass('widget-box');
	    };
	    /**
	     * Called when view is rendered.
	     */
	    BoxView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.update_children();
	        this.set_box_style();
	    };
	    BoxView.prototype.update_children = function () {
	        this.children_views.update(this.model.get('children')).then(function (views) {
	            // Notify all children that their sizes may have changed.
	            views.forEach(function (view) {
	                messaging_1.MessageLoop.postMessage(view.pWidget, widgets_1.Widget.ResizeMessage.UnknownSize);
	            });
	        });
	    };
	    BoxView.prototype.update_box_style = function () {
	        this.update_mapped_classes(BoxView.class_map, 'box_style');
	    };
	    BoxView.prototype.set_box_style = function () {
	        this.set_mapped_classes(BoxView.class_map, 'box_style');
	    };
	    BoxView.prototype.add_child_model = function (model) {
	        var _this = this;
	        // we insert a dummy element so the order is preserved when we add
	        // the rendered content later.
	        var dummy = new widgets_1.Widget();
	        this.pWidget.addWidget(dummy);
	        return this.create_child_view(model).then(function (view) {
	            // replace the dummy widget with the new one.
	            var i = algorithm_1.ArrayExt.firstIndexOf(_this.pWidget.widgets, dummy);
	            _this.pWidget.insertWidget(i, view.pWidget);
	            dummy.dispose();
	            return view;
	        }).catch(utils_1.reject('Could not add child view to box', true));
	    };
	    BoxView.prototype.remove = function () {
	        this.children_views = null;
	        _super.prototype.remove.call(this);
	    };
	    return BoxView;
	}(widget_1.DOMWidgetView));
	BoxView.class_map = {
	    success: ['alert', 'alert-success'],
	    info: ['alert', 'alert-info'],
	    warning: ['alert', 'alert-warning'],
	    danger: ['alert', 'alert-danger']
	};
	exports.BoxView = BoxView;
	var HBoxView = (function (_super) {
	    __extends(HBoxView, _super);
	    function HBoxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    HBoxView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.pWidget.addClass('widget-hbox');
	    };
	    return HBoxView;
	}(BoxView));
	exports.HBoxView = HBoxView;
	var VBoxView = (function (_super) {
	    __extends(VBoxView, _super);
	    function VBoxView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor
	     */
	    VBoxView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.pWidget.addClass('widget-vbox');
	    };
	    return VBoxView;
	}(BoxView));
	exports.VBoxView = VBoxView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_box.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_image.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_image.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var ImageModel = (function (_super) {
	    __extends(ImageModel, _super);
	    function ImageModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ImageModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ImageModel',
	            _view_name: 'ImageView',
	            format: 'png',
	            width: '',
	            height: '',
	            _b64value: ''
	        });
	    };
	    return ImageModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ImageModel = ImageModel;
	var ImageView = (function (_super) {
	    __extends(ImageView, _super);
	    function ImageView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ImageView.prototype.render = function () {
	        /**
	         * Called when view is rendered.
	         */
	        this.pWidget.addClass('jupyter-widgets');
	        this.pWidget.addClass('widget-image');
	        this.update(); // Set defaults.
	    };
	    ImageView.prototype.update = function () {
	        /**
	         * Update the contents of this view
	         *
	         * Called when the model is changed.  The model may have been
	         * changed by another view or by a state update from the back-end.
	         */
	        var image_src = 'data:image/' + this.model.get('format') + ';base64,' + this.model.get('_b64value');
	        this.el.setAttribute('src', image_src);
	        var width = this.model.get('width');
	        if (width !== undefined && width.length > 0) {
	            this.el.setAttribute('width', width);
	        }
	        else {
	            this.el.removeAttribute('width');
	        }
	        var height = this.model.get('height');
	        if (height !== undefined && height.length > 0) {
	            this.el.setAttribute('height', height);
	        }
	        else {
	            this.el.removeAttribute('height');
	        }
	        return _super.prototype.update.call(this);
	    };
	    Object.defineProperty(ImageView.prototype, "tagName", {
	        /**
	         * The default tag name.
	         *
	         * #### Notes
	         * This is a read-only attribute.
	         */
	        get: function () {
	            // We can't make this an attribute with a default value
	            // since it would be set after it is needed in the
	            // constructor.
	            return 'img';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ImageView;
	}(widget_1.DOMWidgetView));
	exports.ImageView = ImageView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_image.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_color.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_color.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var ColorPickerModel = (function (_super) {
	    __extends(ColorPickerModel, _super);
	    function ColorPickerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ColorPickerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: 'black',
	            concise: false,
	            _model_name: 'ColorPickerModel',
	            _view_name: 'ColorPickerView'
	        });
	    };
	    return ColorPickerModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.ColorPickerModel = ColorPickerModel;
	var ColorPickerView = (function (_super) {
	    __extends(ColorPickerView, _super);
	    function ColorPickerView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ColorPickerView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-colorpicker');
	        this._color_container = document.createElement('div');
	        this._color_container.className = 'widget-inline-hbox widget-colorpicker-input';
	        this.el.appendChild(this._color_container);
	        this._textbox = document.createElement('input');
	        this._textbox.setAttribute('type', 'text');
	        this._color_container.appendChild(this._textbox);
	        this._textbox.value = this.model.get('value');
	        this._colorpicker = document.createElement('input');
	        this._colorpicker.setAttribute('type', 'color');
	        this._color_container.appendChild(this._colorpicker);
	        this.listenTo(this.model, 'change:value', this._update_value);
	        this.listenTo(this.model, 'change:concise', this._update_concise);
	        this._update_concise();
	        this._update_value();
	    };
	    ColorPickerView.prototype.events = function () {
	        return {
	            'change [type="color"]': '_picker_change',
	            'change [type="text"]': '_text_change'
	        };
	    };
	    ColorPickerView.prototype._update_value = function () {
	        var value = this.model.get('value');
	        this._colorpicker.value = color2hex(value);
	        this._textbox.value = value;
	    };
	    ColorPickerView.prototype._update_concise = function () {
	        var concise = this.model.get('concise');
	        if (concise) {
	            this.el.classList.add('concise');
	            this._textbox.style.display = 'none';
	        }
	        else {
	            this.el.classList.remove('concise');
	            this._textbox.style.display = '';
	        }
	    };
	    ColorPickerView.prototype._picker_change = function () {
	        this.model.set('value', this._colorpicker.value);
	        this.touch();
	    };
	    ColorPickerView.prototype._text_change = function () {
	        var value = this._validate_color(this._textbox.value, this.model.get('value'));
	        this.model.set('value', value);
	        this.touch();
	    };
	    ColorPickerView.prototype._validate_color = function (color, fallback) {
	        return color.match(/#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$/) ||
	            named_colors[color.toLowerCase()] ? color : fallback;
	    };
	    return ColorPickerView;
	}(widget_1.LabeledDOMWidgetView));
	exports.ColorPickerView = ColorPickerView;
	var named_colors = { aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#00ffff', aquamarine: '#7fffd4', azure: '#f0ffff', beige: '#f5f5dc', bisque: '#ffe4c4', black: '#000000', blanchedalmond: '#ffebcd', blue: '#0000ff', blueviolet: '#8a2be2', brown: '#a52a2a', burlywood: '#deb887', cadetblue: '#5f9ea0', chartreuse: '#7fff00', chocolate: '#d2691e', coral: '#ff7f50', cornflowerblue: '#6495ed', cornsilk: '#fff8dc', crimson: '#dc143c', cyan: '#00ffff', darkblue: '#00008b', darkcyan: '#008b8b', darkgoldenrod: '#b8860b', darkgray: '#a9a9a9', darkgrey: '#a9a9a9', darkgreen: '#006400', darkkhaki: '#bdb76b', darkmagenta: '#8b008b', darkolivegreen: '#556b2f', darkorange: '#ff8c00', darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a', darkseagreen: '#8fbc8f', darkslateblue: '#483d8b', darkslategray: '#2f4f4f', darkslategrey: '#2f4f4f', darkturquoise: '#00ced1', darkviolet: '#9400d3', deeppink: '#ff1493', deepskyblue: '#00bfff', dimgray: '#696969', dimgrey: '#696969', dodgerblue: '#1e90ff', firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22', fuchsia: '#ff00ff', gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff', gold: '#ffd700', goldenrod: '#daa520', gray: '#808080', grey: '#808080', green: '#008000', greenyellow: '#adff2f', honeydew: '#f0fff0', hotpink: '#ff69b4', indianred: '#cd5c5c', indigo: '#4b0082', ivory: '#fffff0', khaki: '#f0e68c', lavender: '#e6e6fa', lavenderblush: '#fff0f5', lawngreen: '#7cfc00', lemonchiffon: '#fffacd', lightblue: '#add8e6', lightcoral: '#f08080', lightcyan: '#e0ffff', lightgoldenrodyellow: '#fafad2', lightgreen: '#90ee90', lightgray: '#d3d3d3', lightgrey: '#d3d3d3', lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa', lightskyblue: '#87cefa', lightslategray: '#778899', lightslategrey: '#778899', lightsteelblue: '#b0c4de', lightyellow: '#ffffe0', lime: '#00ff00', limegreen: '#32cd32', linen: '#faf0e6', magenta: '#ff00ff', maroon: '#800000', mediumaquamarine: '#66cdaa', mediumblue: '#0000cd', mediumorchid: '#ba55d3', mediumpurple: '#9370db', mediumseagreen: '#3cb371', mediumslateblue: '#7b68ee', mediumspringgreen: '#00fa9a', mediumturquoise: '#48d1cc', mediumvioletred: '#c71585', midnightblue: '#191970', mintcream: '#f5fffa', mistyrose: '#ffe4e1', moccasin: '#ffe4b5', navajowhite: '#ffdead', navy: '#000080', oldlace: '#fdf5e6', olive: '#808000', olivedrab: '#6b8e23', orange: '#ffa500', orangered: '#ff4500', orchid: '#da70d6', palegoldenrod: '#eee8aa', palegreen: '#98fb98', paleturquoise: '#afeeee', palevioletred: '#db7093', papayawhip: '#ffefd5', peachpuff: '#ffdab9', peru: '#cd853f', pink: '#ffc0cb', plum: '#dda0dd', powderblue: '#b0e0e6', purple: '#800080', red: '#ff0000', rosybrown: '#bc8f8f', royalblue: '#4169e1', saddlebrown: '#8b4513', salmon: '#fa8072', sandybrown: '#f4a460', seagreen: '#2e8b57', seashell: '#fff5ee', sienna: '#a0522d', silver: '#c0c0c0', skyblue: '#87ceeb', slateblue: '#6a5acd', slategray: '#708090', slategrey: '#708090', snow: '#fffafa', springgreen: '#00ff7f', steelblue: '#4682b4', tan: '#d2b48c', teal: '#008080', thistle: '#d8bfd8', tomato: '#ff6347', turquoise: '#40e0d0', violet: '#ee82ee', wheat: '#f5deb3', white: '#ffffff', whitesmoke: '#f5f5f5', yellow: '#ffff00', yellowgreen: '#9acd32', };
	/*
	 * From a valid html color (named color, 6-digits or 3-digits hex format)
	 * return a 6-digits hexadecimal color #rrggbb.
	 */
	function color2hex(color) {
	    return named_colors[color.toLowerCase()] || rgb3_to_rgb6(color);
	}
	function rgb3_to_rgb6(rgb) {
	    if (rgb.length === 7) {
	        return rgb;
	    }
	    else {
	        return '#' + rgb.charAt(1) + rgb.charAt(1) +
	            rgb.charAt(2) + rgb.charAt(2) +
	            rgb.charAt(3) + rgb.charAt(3);
	    }
	}
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_color.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_date.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_date.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	function serialize_datetime(value, manager) {
	    if (value === null) {
	        return null;
	    }
	    else {
	        value = new Date(value);
	        return {
	            year: value.getFullYear(),
	            month: value.getMonth(),
	            date: value.getDate(),
	            hours: value.getHours(),
	            minutes: value.getMinutes(),
	            seconds: value.getSeconds(),
	            milliseconds: value.getMilliseconds()
	        };
	    }
	}
	exports.serialize_datetime = serialize_datetime;
	;
	function deserialize_datetime(value, manager) {
	    if (value === null) {
	        return null;
	    }
	    else {
	        return new Date(value.year, value.month, value.date, value.hours, value.minutes, value.seconds, value.milliseconds);
	    }
	}
	exports.deserialize_datetime = deserialize_datetime;
	;
	function createDateAsUTC(date) {
	    if (date === null) {
	        return null;
	    }
	    else {
	        return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
	    }
	}
	function convertDateToUTC(date) {
	    if (date === null) {
	        return null;
	    }
	    else {
	        return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
	    }
	}
	var DatePickerModel = (function (_super) {
	    __extends(DatePickerModel, _super);
	    function DatePickerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DatePickerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            value: null,
	            _model_name: 'DatePickerModel',
	            _view_name: 'DatePickerView'
	        });
	    };
	    return DatePickerModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	DatePickerModel.serializers = _.extend({
	    value: {
	        serialize: serialize_datetime,
	        deserialize: deserialize_datetime
	    }
	}, widget_core_1.CoreLabeledDOMWidgetModel.serializers);
	exports.DatePickerModel = DatePickerModel;
	var DatePickerView = (function (_super) {
	    __extends(DatePickerView, _super);
	    function DatePickerView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DatePickerView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-datepicker');
	        this._datepicker = document.createElement('input');
	        this._datepicker.setAttribute('type', 'date');
	        this.el.appendChild(this._datepicker);
	        this.listenTo(this.model, 'change:value', this._update_value);
	        this._update_value();
	    };
	    DatePickerView.prototype.events = function () {
	        return {
	            'change [type="date"]': '_picker_change',
	        };
	    };
	    DatePickerView.prototype._update_value = function () {
	        var value = this.model.get('value');
	        this._datepicker.valueAsDate = createDateAsUTC(value);
	    };
	    DatePickerView.prototype._picker_change = function () {
	        this.model.set('value', convertDateToUTC(this._datepicker.valueAsDate));
	        this.touch();
	    };
	    return DatePickerView;
	}(widget_1.LabeledDOMWidgetView));
	exports.DatePickerView = DatePickerView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_date.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/services-shim.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/services-shim.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js');
	var shims;
	(function (shims) {
	    var services;
	    (function (services) {
	        /**
	         * Public constructor
	         * @param jsServicesKernel - @jupyterlab/services Kernel.IKernel instance
	         */
	        var CommManager = (function () {
	            function CommManager(jsServicesKernel) {
	                /**
	                 * Register a comm in the mapping
	                 */
	                this.register_comm = function (comm) {
	                    this.comms[comm.comm_id] = Promise.resolve(comm);
	                    comm.kernel = this.kernel;
	                    return comm.comm_id;
	                };
	                this.targets = Object.create(null);
	                this.comms = Object.create(null);
	                this.kernel = null;
	                this.jsServicesKernel = null;
	                this.init_kernel(jsServicesKernel);
	            }
	            ;
	            /**
	             * Hookup kernel events.
	             * @param  {Kernel.IKernel} jsServicesKernel - @jupyterlab/services Kernel.IKernel instance
	             */
	            CommManager.prototype.init_kernel = function (jsServicesKernel) {
	                this.kernel = jsServicesKernel; // These aren't really the same.
	                this.jsServicesKernel = jsServicesKernel;
	            };
	            ;
	            /**
	             * Creates a new connected comm
	             * @param  {string} target_name
	             * @param  {object} data
	             * @param  {object} callbacks
	             * @param  {object} metadata
	             * @param  {string} comm_id
	             * @return {Comm}
	             */
	            CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata, comm_id) {
	                var comm = new Comm(this.jsServicesKernel.connectToComm(target_name, comm_id));
	                this.register_comm(comm);
	                comm.open(data, callbacks, metadata);
	                return comm;
	            };
	            ;
	            /**
	             * Register a comm target
	             * @param  {string} target_name
	             * @param  {(Comm, object) => void} f - callback that is called when the
	             *                         comm is made.  Signature of f(comm, msg).
	             */
	            CommManager.prototype.register_target = function (target_name, f) {
	                var _this = this;
	                var handle = this.jsServicesKernel.registerCommTarget(target_name, function (jsServicesComm, msg) {
	                    // Create the comm.
	                    var comm = new Comm(jsServicesComm);
	                    _this.register_comm(comm);
	                    // Call the callback for the comm.
	                    try {
	                        return f(comm, msg);
	                    }
	                    catch (e) {
	                        comm.close();
	                        var wrapped_error = new utils.WrappedError('Exception opening new comm', e);
	                        console.error(wrapped_error);
	                        return;
	                    }
	                });
	                this.targets[target_name] = handle;
	            };
	            ;
	            /**
	             * Unregisters a comm target
	             * @param  {string} target_name
	             */
	            CommManager.prototype.unregister_target = function (target_name, f) {
	                var handle = this.targets[target_name];
	                handle.dispose();
	                delete this.targets[target_name];
	            };
	            ;
	            return CommManager;
	        }());
	        services.CommManager = CommManager;
	        /**
	         * Public constructor
	         * @param  {IComm} jsServicesComm - @jupyterlab/services IComm instance
	         */
	        var Comm = (function () {
	            function Comm(jsServicesComm) {
	                this.jsServicesComm = null;
	                this.jsServicesComm = jsServicesComm;
	            }
	            Object.defineProperty(Comm.prototype, "comm_id", {
	                /**
	                 * Comm id
	                 * @return {string}
	                 */
	                get: function () {
	                    return this.jsServicesComm.commId;
	                },
	                enumerable: true,
	                configurable: true
	            });
	            Object.defineProperty(Comm.prototype, "target_name", {
	                /**
	                 * Target name
	                 * @return {string}
	                 */
	                get: function () {
	                    return this.jsServicesComm.targetName;
	                },
	                enumerable: true,
	                configurable: true
	            });
	            /**
	             * Opens a sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @return msg id
	             */
	            Comm.prototype.open = function (data, callbacks, metadata) {
	                var future = this.jsServicesComm.open(data, metadata);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            ;
	            /**
	             * Sends a message to the sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @param  buffers
	             * @return message id
	             */
	            Comm.prototype.send = function (data, callbacks, metadata, buffers) {
	                var future = this.jsServicesComm.send(data, metadata, buffers);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            ;
	            /**
	             * Closes the sibling comm in the backend
	             * @param  data
	             * @param  callbacks
	             * @param  metadata
	             * @return msg id
	             */
	            Comm.prototype.close = function (data, callbacks, metadata) {
	                var future = this.jsServicesComm.close(data, metadata);
	                this._hookupCallbacks(future, callbacks);
	                return future.msg.header.msg_id;
	            };
	            ;
	            /**
	             * Register a message handler
	             * @param  callback, which is given a message
	             */
	            Comm.prototype.on_msg = function (callback) {
	                this.jsServicesComm.onMsg = callback.bind(this);
	            };
	            ;
	            /**
	             * Register a handler for when the comm is closed by the backend
	             * @param  callback, which is given a message
	             */
	            Comm.prototype.on_close = function (callback) {
	                this.jsServicesComm.onClose = callback.bind(this);
	            };
	            ;
	            /**
	             * Hooks callback object up with @jupyterlab/services IKernelFuture
	             * @param  @jupyterlab/services IKernelFuture instance
	             * @param  callbacks
	             */
	            Comm.prototype._hookupCallbacks = function (future, callbacks) {
	                if (callbacks) {
	                    future.onReply = function (msg) {
	                        if (callbacks.shell && callbacks.shell.reply)
	                            callbacks.shell.reply(msg);
	                        // TODO: Handle payloads.  See https://github.com/jupyter/notebook/blob/master/notebook/static/services/kernels/kernel.js#L923-L947
	                    };
	                    future.onStdin = function (msg) {
	                        if (callbacks.input)
	                            callbacks.input(msg);
	                    };
	                    future.onIOPub = function (msg) {
	                        if (callbacks.iopub) {
	                            if (callbacks.iopub.status && msg.header.msg_type === 'status') {
	                                callbacks.iopub.status(msg);
	                            }
	                            else if (callbacks.iopub.clear_output && msg.header.msg_type === 'clear_output') {
	                                callbacks.iopub.clear_output(msg);
	                            }
	                            else if (callbacks.iopub.output) {
	                                switch (msg.header.msg_type) {
	                                    case 'display_data':
	                                    case 'execute_result':
	                                        callbacks.iopub.output(msg);
	                                        break;
	                                }
	                                ;
	                            }
	                        }
	                    };
	                }
	            };
	            ;
	            return Comm;
	        }());
	        services.Comm = Comm;
	    })(services = shims.services || (shims.services = {}));
	})(shims = exports.shims || (exports.shims = {}));
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/services-shim.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_int.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_int.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_style_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_style.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	__jupyter_require__('jquery-ui@^1.12.1/ui/widgets/slider.js');
	var d3format = __jupyter_require__('d3-format@^0.5.1/build/d3-format.js').format;
	var IntModel = (function (_super) {
	    __extends(IntModel, _super);
	    function IntModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntModel',
	            value: 0,
	            disabled: false,
	        });
	    };
	    return IntModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.IntModel = IntModel;
	var BoundedIntModel = (function (_super) {
	    __extends(BoundedIntModel, _super);
	    function BoundedIntModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedIntModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'BoundedIntModel',
	            max: 100,
	            min: 0
	        });
	    };
	    return BoundedIntModel;
	}(IntModel));
	exports.BoundedIntModel = BoundedIntModel;
	var SliderStyleModel = (function (_super) {
	    __extends(SliderStyleModel, _super);
	    function SliderStyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SliderStyleModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SliderStyleModel',
	        });
	    };
	    return SliderStyleModel;
	}(widget_style_1.StyleModel));
	SliderStyleModel.styleProperties = {
	    handle_color: {
	        selector: '.ui-slider-handle',
	        attribute: 'background-color',
	        default: null
	    }
	};
	exports.SliderStyleModel = SliderStyleModel;
	var IntSliderModel = (function (_super) {
	    __extends(IntSliderModel, _super);
	    function IntSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntSliderModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntSliderModel',
	            _view_name: 'IntSliderView',
	            step: 1,
	            orientation: 'horizontal',
	            readout: true,
	            readout_format: 'd',
	            continuous_update: true,
	            style: void 0
	        });
	    };
	    IntSliderModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.on('change:readout_format', this.update_readout_format, this);
	        this.update_readout_format();
	    };
	    IntSliderModel.prototype.update_readout_format = function () {
	        this.readout_formatter = d3format(this.get('readout_format'));
	    };
	    return IntSliderModel;
	}(BoundedIntModel));
	exports.IntSliderModel = IntSliderModel;
	var IntRangeSliderModel = (function (_super) {
	    __extends(IntRangeSliderModel, _super);
	    function IntRangeSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    return IntRangeSliderModel;
	}(IntSliderModel));
	exports.IntRangeSliderModel = IntRangeSliderModel;
	var BaseIntSliderView = (function (_super) {
	    __extends(BaseIntSliderView, _super);
	    function BaseIntSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseInt;
	        return _this;
	    }
	    BaseIntSliderView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-slider');
	        this.el.classList.add('widget-hslider');
	        (this.$slider = $('<div />'))
	            .slider({
	            slide: this.handleSliderChange.bind(this),
	            stop: this.handleSliderChanged.bind(this)
	        })
	            .addClass('slider');
	        // Put the slider in a container
	        this.slider_container = document.createElement('div');
	        this.slider_container.classList.add('slider-container');
	        this.slider_container.appendChild(this.$slider[0]);
	        this.el.appendChild(this.slider_container);
	        this.readout = document.createElement('div');
	        this.el.appendChild(this.readout);
	        this.readout.classList.add('widget-readout');
	        this.readout.contentEditable = 'true';
	        this.readout.style.display = 'none';
	        // Set defaults.
	        this.update();
	    };
	    BaseIntSliderView.prototype.update = function (options) {
	        /**
	         * Update the contents of this view
	         *
	         * Called when the model is changed.  The model may have been
	         * changed by another view or by a state update from the back-end.
	         */
	        if (options === undefined || options.updated_view !== this) {
	            // JQuery slider option keys.  These keys happen to have a
	            // one-to-one mapping with the corresponding keys of the model.
	            var jquery_slider_keys = ['step', 'disabled'];
	            var that_1 = this;
	            that_1.$slider.slider({});
	            _.each(jquery_slider_keys, function (key, i) {
	                var model_value = that_1.model.get(key);
	                if (model_value !== undefined) {
	                    that_1.$slider.slider('option', key, model_value);
	                }
	            });
	            var max = this.model.get('max');
	            var min = this.model.get('min');
	            if (min <= max) {
	                if (max !== undefined)
	                    this.$slider.slider('option', 'max', max);
	                if (min !== undefined)
	                    this.$slider.slider('option', 'min', min);
	            }
	            // WORKAROUND FOR JQUERY SLIDER BUG.
	            // The horizontal position of the slider handle
	            // depends on the value of the slider at the time
	            // of orientation change.  Before applying the new
	            // workaround, we set the value to the minimum to
	            // make sure that the horizontal placement of the
	            // handle in the vertical slider is always
	            // consistent.
	            var orientation_1 = this.model.get('orientation');
	            this.$slider.slider('option', 'orientation', orientation_1);
	            // Use the right CSS classes for vertical & horizontal sliders
	            if (orientation_1 === 'vertical') {
	                this.el.classList.remove('widget-hslider');
	                this.el.classList.add('widget-vslider');
	                this.el.classList.remove('widget-inline-hbox');
	                this.el.classList.add('widget-inline-vbox');
	            }
	            else {
	                this.el.classList.remove('widget-vslider');
	                this.el.classList.add('widget-hslider');
	                this.el.classList.remove('widget-inline-vbox');
	                this.el.classList.add('widget-inline-hbox');
	            }
	            var readout = this.model.get('readout');
	            if (readout) {
	                this.readout.style.display = '';
	                this.displayed.then(function () {
	                    if (that_1.readout_overflow()) {
	                        that_1.readout.classList.add('overflow');
	                    }
	                    else {
	                        that_1.readout.classList.remove('overflow');
	                    }
	                });
	            }
	            else {
	                this.readout.style.display = 'none';
	            }
	        }
	        return _super.prototype.update.call(this);
	    };
	    /**
	     * Returns true if the readout box content overflows.
	     */
	    BaseIntSliderView.prototype.readout_overflow = function () {
	        return this.readout.scrollWidth > this.readout.clientWidth;
	    };
	    BaseIntSliderView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'slide': 'handleSliderChange',
	            'slidestop': 'handleSliderChanged',
	            'blur [contentEditable=true]': 'handleTextChange',
	            'keydown [contentEditable=true]': 'handleKeyDown'
	        };
	    };
	    BaseIntSliderView.prototype.handleKeyDown = function (e) {
	        if (e.keyCode === 13) {
	            e.preventDefault();
	            this.handleTextChange();
	        }
	    };
	    /**
	     * Validate the value of the slider before sending it to the back-end
	     * and applying it to the other views on the page.
	     */
	    BaseIntSliderView.prototype._validate_slide_value = function (x) {
	        return Math.floor(x);
	    };
	    return BaseIntSliderView;
	}(widget_1.LabeledDOMWidgetView));
	exports.BaseIntSliderView = BaseIntSliderView;
	var IntRangeSliderView = (function (_super) {
	    __extends(IntRangeSliderView, _super);
	    function IntRangeSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        // range numbers can be separated by a hyphen, colon, or an en-dash
	        _this._range_regex = /^\s*([+-]?\d+)\s*[-:–]\s*([+-]?\d+)/;
	        return _this;
	    }
	    IntRangeSliderView.prototype.update = function (options) {
	        _super.prototype.update.call(this, options);
	        this.$slider.slider('option', 'range', true);
	        // values for the range case are validated python-side in
	        // _Bounded{Int,Float}RangeWidget._validate
	        var value = this.model.get('value');
	        this.$slider.slider('option', 'values', value.slice());
	        this.readout.textContent = this.valueToString(value);
	        if (this.model.get('value') !== value) {
	            this.model.set('value', value, { updated_view: this });
	            this.touch();
	        }
	    };
	    /**
	     * Write value to a string
	     */
	    IntRangeSliderView.prototype.valueToString = function (value) {
	        var format = this.model.readout_formatter;
	        return value.map(function (v) {
	            return format(v);
	        }).join(' – ');
	    };
	    /**
	     * Parse value from a string
	     */
	    IntRangeSliderView.prototype.stringToValue = function (text) {
	        // ranges can be expressed either 'val-val' or 'val:val' (+spaces)
	        var match = this._range_regex.exec(text);
	        if (match) {
	            return [this._parse_value(match[1]), this._parse_value(match[2])];
	        }
	        else {
	            return null;
	        }
	    };
	    /**
	     * this handles the entry of text into the contentEditable label first, the
	     * value is checked if it contains a parseable value then it is clamped
	     * within the min-max range of the slider finally, the model is updated if
	     * the value is to be changed
	     *
	     * if any of these conditions are not met, the text is reset
	     */
	    IntRangeSliderView.prototype.handleTextChange = function () {
	        var value = this.stringToValue(this.readout.textContent);
	        var vmin = this.model.get('min');
	        var vmax = this.model.get('max');
	        // reject input where NaN or lower > upper
	        if (value === null ||
	            isNaN(value[0]) ||
	            isNaN(value[1]) ||
	            (value[0] > value[1])) {
	            this.readout.textContent = this.valueToString(this.model.get('value'));
	        }
	        else {
	            // clamp to range
	            value = [Math.max(Math.min(value[0], vmax), vmin),
	                Math.max(Math.min(value[1], vmax), vmin)];
	            if ((value[0] !== this.model.get('value')[0]) ||
	                (value[1] !== this.model.get('value')[1])) {
	                this.readout.textContent = this.valueToString(value);
	                this.model.set('value', value, { updated_view: this });
	                this.touch();
	            }
	            else {
	                this.readout.textContent = this.valueToString(this.model.get('value'));
	            }
	        }
	    };
	    /**
	     * Called when the slider value is changing.
	     */
	    IntRangeSliderView.prototype.handleSliderChange = function (e, ui) {
	        var actual_value = ui.values.map(this._validate_slide_value);
	        this.readout.textContent = this.valueToString(actual_value);
	        // Only persist the value while sliding if the continuous_update
	        // trait is set to true.
	        if (this.model.get('continuous_update')) {
	            this.handleSliderChanged(e, ui);
	        }
	    };
	    /**
	     * Called when the slider value has changed.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    IntRangeSliderView.prototype.handleSliderChanged = function (e, ui) {
	        var actual_value = ui.values.map(this._validate_slide_value);
	        this.model.set('value', actual_value, { updated_view: this });
	        this.touch();
	    };
	    return IntRangeSliderView;
	}(BaseIntSliderView));
	exports.IntRangeSliderView = IntRangeSliderView;
	var IntSliderView = (function (_super) {
	    __extends(IntSliderView, _super);
	    function IntSliderView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntSliderView.prototype.update = function (options) {
	        _super.prototype.update.call(this, options);
	        var min = this.model.get('min');
	        var max = this.model.get('max');
	        var value = this.model.get('value');
	        if (value > max) {
	            value = max;
	        }
	        else if (value < min) {
	            value = min;
	        }
	        this.$slider.slider('option', 'value', value);
	        this.readout.textContent = this.valueToString(value);
	        if (this.model.get('value') !== value) {
	            this.model.set('value', value, { updated_view: this });
	            this.touch();
	        }
	    };
	    /**
	     * Write value to a string
	     */
	    IntSliderView.prototype.valueToString = function (value) {
	        var format = this.model.readout_formatter;
	        return format(value);
	    };
	    /**
	     * Parse value from a string
	     */
	    IntSliderView.prototype.stringToValue = function (text) {
	        return this._parse_value(text);
	    };
	    /**
	     * this handles the entry of text into the contentEditable label first, the
	     * value is checked if it contains a parseable value then it is clamped
	     * within the min-max range of the slider finally, the model is updated if
	     * the value is to be changed
	     *
	     * if any of these conditions are not met, the text is reset
	     */
	    IntSliderView.prototype.handleTextChange = function () {
	        var value = this.stringToValue(this.readout.textContent);
	        var vmin = this.model.get('min');
	        var vmax = this.model.get('max');
	        if (isNaN(value)) {
	            this.readout.textContent = this.valueToString(this.model.get('value'));
	        }
	        else {
	            value = Math.max(Math.min(value, vmax), vmin);
	            if (value !== this.model.get('value')) {
	                this.readout.textContent = this.valueToString(value);
	                this.model.set('value', value, { updated_view: this });
	                this.touch();
	            }
	            else {
	                this.readout.textContent = this.valueToString(this.model.get('value'));
	            }
	        }
	    };
	    /**
	     * Called when the slider value is changing.
	     */
	    IntSliderView.prototype.handleSliderChange = function (e, ui) {
	        var actual_value = this._validate_slide_value(ui.value);
	        this.readout.textContent = this.valueToString(actual_value);
	        // Only persist the value while sliding if the continuous_update
	        // trait is set to true.
	        if (this.model.get('continuous_update')) {
	            this.handleSliderChanged(e, ui);
	        }
	    };
	    /**
	     * Called when the slider value has changed.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    IntSliderView.prototype.handleSliderChanged = function (e, ui) {
	        var actual_value = this._validate_slide_value(ui.value);
	        this.model.set('value', actual_value, { updated_view: this });
	        this.touch();
	    };
	    return IntSliderView;
	}(BaseIntSliderView));
	exports.IntSliderView = IntSliderView;
	var IntTextModel = (function (_super) {
	    __extends(IntTextModel, _super);
	    function IntTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntTextModel',
	            _view_name: 'IntTextView'
	        });
	    };
	    return IntTextModel;
	}(IntModel));
	exports.IntTextModel = IntTextModel;
	var BoundedIntTextModel = (function (_super) {
	    __extends(BoundedIntTextModel, _super);
	    function BoundedIntTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedIntTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'BoundedIntTextModel',
	            _view_name: 'IntTextView'
	        });
	    };
	    return BoundedIntTextModel;
	}(BoundedIntModel));
	exports.BoundedIntTextModel = BoundedIntTextModel;
	var IntTextView = (function (_super) {
	    __extends(IntTextView, _super);
	    function IntTextView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseInt;
	        return _this;
	    }
	    IntTextView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-text');
	        this.textbox = document.createElement('input');
	        this.textbox.setAttribute('type', 'text');
	        this.el.appendChild(this.textbox);
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    IntTextView.prototype.update = function (options) {
	        if (options === undefined || options.updated_view !== this) {
	            var value = this.model.get('value');
	            if (this._parse_value(this.textbox.value) !== value) {
	                this.textbox.value = value.toString();
	            }
	            var disabled = this.model.get('disabled');
	            if (disabled) {
	                this.textbox.setAttribute('disabled', disabled);
	            }
	            else {
	                this.textbox.removeAttribute('disabled');
	            }
	        }
	        return _super.prototype.update.call(this);
	    };
	    IntTextView.prototype.events = function () {
	        return {
	            // Dictionary of events and their handlers.
	            'keydown input': 'handleKeyDown',
	            'keypress input': 'handleKeypress',
	            'keyup input': 'handleChanging',
	            'paste input': 'handleChanging',
	            'cut input': 'handleChanging',
	            // Fires only when control is validated or looses focus.
	            'change input': 'handleChanged'
	        };
	    };
	    /**
	     * Handle key down
	     *
	     * Stop propagation so the event isn't sent to the application.
	     */
	    IntTextView.prototype.handleKeyDown = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles key press
	     *
	     * Stop propagation so the event isn't sent to the application.
	     */
	    IntTextView.prototype.handleKeypress = function (e) {
	        e.stopPropagation();
	    };
	    /**
	     * Handles and validates user input.
	     *
	     * Try to parse value as an int.
	     */
	    IntTextView.prototype.handleChanging = function (e) {
	        var numericalValue = 0;
	        var trimmed = e.target.value.trim();
	        if (trimmed === '') {
	            return;
	        }
	        else {
	            if (!(['-', '-.', '.', '+.', '+'].indexOf(trimmed) >= 0)) {
	                numericalValue = this._parse_value(e.target.value);
	            }
	        }
	        // If parse failed, reset value to value stored in model.
	        if (isNaN(numericalValue)) {
	            e.target.value = this.model.get('value');
	        }
	        else if (!isNaN(numericalValue)) {
	            // Handle both the IntTextModel and the BoundedIntTextModel by
	            // checking to see if the max/min properties are defined
	            if (this.model.get('max') !== undefined) {
	                numericalValue = Math.min(this.model.get('max'), numericalValue);
	            }
	            if (this.model.get('min') !== undefined) {
	                numericalValue = Math.max(this.model.get('min'), numericalValue);
	            }
	            // Apply the value if it has changed.
	            if (numericalValue !== this.model.get('value')) {
	                // Calling model.set will trigger all of the other views of the
	                // model to update.
	                this.model.set('value', numericalValue, { updated_view: this });
	                this.touch();
	            }
	        }
	    };
	    /**
	     * Applies validated input.
	     */
	    IntTextView.prototype.handleChanged = function (e) {
	        if (e.target.value.trim() === '' || e.target.value !== this.model.get('value')) {
	            e.target.value = this.model.get('value');
	        }
	    };
	    return IntTextView;
	}(widget_1.LabeledDOMWidgetView));
	exports.IntTextView = IntTextView;
	var ProgressStyleModel = (function (_super) {
	    __extends(ProgressStyleModel, _super);
	    function ProgressStyleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ProgressStyleModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ProgressStyleModel',
	        });
	    };
	    return ProgressStyleModel;
	}(widget_style_1.StyleModel));
	ProgressStyleModel.styleProperties = {
	    bar_color: {
	        selector: '.progress-bar',
	        attribute: 'background-color',
	        default: null
	    }
	};
	exports.ProgressStyleModel = ProgressStyleModel;
	var IntProgressModel = (function (_super) {
	    __extends(IntProgressModel, _super);
	    function IntProgressModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    IntProgressModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'IntProgressModel',
	            _view_name: 'ProgressView',
	            orientation: 'horizontal',
	            bar_style: '',
	            style: void 0
	        });
	    };
	    return IntProgressModel;
	}(BoundedIntModel));
	exports.IntProgressModel = IntProgressModel;
	var ProgressView = (function (_super) {
	    __extends(ProgressView, _super);
	    function ProgressView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ProgressView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.listenTo(this.model, 'change:bar_style', this.update_bar_style);
	        this.pWidget.addClass('jupyter-widgets');
	    };
	    ProgressView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        var orientation = this.model.get('orientation');
	        var className = orientation === 'horizontal' ?
	            'widget-hprogress' : 'widget-vprogress';
	        this.el.classList.add(className);
	        this.progress = document.createElement('div');
	        this.progress.classList.add('progress');
	        this.progress.style.position = 'relative';
	        this.el.appendChild(this.progress);
	        this.bar = document.createElement('div');
	        this.bar.classList.add('progress-bar');
	        this.bar.style.position = 'absolute';
	        this.bar.style.bottom = '0px';
	        this.bar.style.left = '0px';
	        this.progress.appendChild(this.bar);
	        // Set defaults.
	        this.update();
	        this.set_bar_style();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ProgressView.prototype.update = function () {
	        var value = this.model.get('value');
	        var max = this.model.get('max');
	        var min = this.model.get('min');
	        var orientation = this.model.get('orientation');
	        var percent = 100.0 * (value - min) / (max - min);
	        if (orientation === 'horizontal') {
	            this.el.classList.remove('widget-inline-vbox');
	            this.el.classList.remove('widget-vprogress');
	            this.el.classList.add('widget-inline-hbox');
	            this.el.classList.add('widget-hprogress');
	            this.bar.style.width = percent + '%';
	            this.bar.style.height = '100%';
	        }
	        else {
	            this.el.classList.remove('widget-inline-hbox');
	            this.el.classList.remove('widget-hprogress');
	            this.el.classList.add('widget-inline-vbox');
	            this.el.classList.add('widget-vprogress');
	            this.bar.style.width = '100%';
	            this.bar.style.height = percent + '%';
	        }
	        return _super.prototype.update.call(this);
	    };
	    ProgressView.prototype.update_bar_style = function () {
	        this.update_mapped_classes(ProgressView.class_map, 'bar_style', this.bar);
	    };
	    ProgressView.prototype.set_bar_style = function () {
	        this.set_mapped_classes(ProgressView.class_map, 'bar_style', this.bar);
	    };
	    return ProgressView;
	}(widget_1.LabeledDOMWidgetView));
	ProgressView.class_map = {
	    success: ['progress-bar-success'],
	    info: ['progress-bar-info'],
	    warning: ['progress-bar-warning'],
	    danger: ['progress-bar-danger']
	};
	exports.ProgressView = ProgressView;
	var PlayModel = (function (_super) {
	    __extends(PlayModel, _super);
	    function PlayModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    PlayModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'PlayModel',
	            _view_name: 'PlayView',
	            _playing: false,
	            _repeat: false,
	            show_repeat: true,
	            interval: 100,
	            step: 1,
	        });
	    };
	    PlayModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.on('change:_playing', function () {
	            if (this.get('_playing')) {
	                this.loop();
	            }
	        }, this);
	    };
	    PlayModel.prototype.loop = function () {
	        if (this.get('_playing')) {
	            var next_value = this.get('value') + this.get('step');
	            if (next_value <= this.get('max')) {
	                this.set('value', next_value);
	                window.setTimeout(this.loop.bind(this), this.get('interval'));
	            }
	            else {
	                if (this.get('_repeat')) {
	                    this.set('value', this.get('min'));
	                    window.setTimeout(this.loop.bind(this), this.get('interval'));
	                }
	                else {
	                    this.set('_playing', false);
	                }
	            }
	            this.save_changes();
	        }
	    };
	    PlayModel.prototype.stop = function () {
	        this.set('_playing', false);
	        this.set('value', this.get('min'));
	        this.save_changes();
	    };
	    PlayModel.prototype.pause = function () {
	        this.set('_playing', false);
	        this.save_changes();
	    };
	    PlayModel.prototype.play = function () {
	        this.set('_playing', true);
	        this.save_changes();
	    };
	    PlayModel.prototype.repeat = function () {
	        this.set('_repeat', !this.get('_repeat'));
	        this.save_changes();
	    };
	    return PlayModel;
	}(BoundedIntModel));
	exports.PlayModel = PlayModel;
	var PlayView = (function (_super) {
	    __extends(PlayView, _super);
	    function PlayView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    PlayView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-play');
	        this.playButton = document.createElement('button');
	        this.pauseButton = document.createElement('button');
	        this.stopButton = document.createElement('button');
	        this.repeatButton = document.createElement('button');
	        this.playButton.className = 'jupyter-button';
	        this.pauseButton.className = 'jupyter-button';
	        this.stopButton.className = 'jupyter-button';
	        this.repeatButton.className = 'jupyter-button';
	        this.el.appendChild(this.playButton); // Toggle button with playing
	        this.el.appendChild(this.pauseButton); // Disable if not playing
	        this.el.appendChild(this.stopButton); // Disable if not playing
	        this.el.appendChild(this.repeatButton); // Always enabled, but may be hidden
	        var playIcon = document.createElement('i');
	        playIcon.className = 'fa fa-play';
	        this.playButton.appendChild(playIcon);
	        var pauseIcon = document.createElement('i');
	        pauseIcon.className = 'fa fa-pause';
	        this.pauseButton.appendChild(pauseIcon);
	        var stopIcon = document.createElement('i');
	        stopIcon.className = 'fa fa-stop';
	        this.stopButton.appendChild(stopIcon);
	        var repeatIcon = document.createElement('i');
	        repeatIcon.className = 'fa fa-retweet';
	        this.repeatButton.appendChild(repeatIcon);
	        this.playButton.onclick = this.model.play.bind(this.model);
	        this.pauseButton.onclick = this.model.pause.bind(this.model);
	        this.stopButton.onclick = this.model.stop.bind(this.model);
	        this.repeatButton.onclick = this.model.repeat.bind(this.model);
	        this.listenTo(this.model, 'change:_playing', this.update_playing);
	        this.listenTo(this.model, 'change:_repeat', this.update_repeat);
	        this.listenTo(this.model, 'change:show_repeat', this.update_repeat);
	        this.update_playing();
	        this.update_repeat();
	    };
	    PlayView.prototype.update_playing = function () {
	        var playing = this.model.get('_playing');
	        if (playing) {
	            this.pauseButton.disabled = false;
	            this.playButton.classList.add('mod-active');
	        }
	        else {
	            this.pauseButton.disabled = true;
	            this.playButton.classList.remove('mod-active');
	        }
	    };
	    PlayView.prototype.update_repeat = function () {
	        var repeat = this.model.get('_repeat');
	        this.repeatButton.style.display = this.model.get('show_repeat') ? this.playButton.style.display : 'none';
	        if (repeat) {
	            this.repeatButton.classList.add('mod-active');
	        }
	        else {
	            this.repeatButton.classList.remove('mod-active');
	        }
	    };
	    return PlayView;
	}(widget_1.DOMWidgetView));
	exports.PlayView = PlayView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_int.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_float.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_float.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var widget_int_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_int.js');
	var d3format = __jupyter_require__('d3-format@^0.5.1/build/d3-format.js').format;
	var FloatModel = (function (_super) {
	    __extends(FloatModel, _super);
	    function FloatModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "FloatModel",
	            value: 0,
	            disabled: false,
	        });
	    };
	    return FloatModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.FloatModel = FloatModel;
	var BoundedFloatModel = (function (_super) {
	    __extends(BoundedFloatModel, _super);
	    function BoundedFloatModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedFloatModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "BoundedFloatModel",
	            max: 100.0,
	            min: 0.0
	        });
	    };
	    return BoundedFloatModel;
	}(FloatModel));
	exports.BoundedFloatModel = BoundedFloatModel;
	var FloatSliderModel = (function (_super) {
	    __extends(FloatSliderModel, _super);
	    function FloatSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatSliderModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "FloatSliderModel",
	            _view_name: "FloatSliderView",
	            step: 1.0,
	            orientation: "horizontal",
	            _range: false,
	            readout: true,
	            readout_format: '.2f',
	            slider_color: null,
	            continuous_update: true
	        });
	    };
	    FloatSliderModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        this.on('change:readout_format', this.update_readout_format, this);
	        this.update_readout_format();
	    };
	    FloatSliderModel.prototype.update_readout_format = function () {
	        this.readout_formatter = d3format(this.get('readout_format'));
	    };
	    return FloatSliderModel;
	}(BoundedFloatModel));
	exports.FloatSliderModel = FloatSliderModel;
	var FloatRangeSliderModel = (function (_super) {
	    __extends(FloatRangeSliderModel, _super);
	    function FloatRangeSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    return FloatRangeSliderModel;
	}(FloatSliderModel));
	exports.FloatRangeSliderModel = FloatRangeSliderModel;
	var FloatSliderView = (function (_super) {
	    __extends(FloatSliderView, _super);
	    function FloatSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseFloat;
	        return _this;
	    }
	    /**
	     * Validate the value of the slider before sending it to the back-end
	     * and applying it to the other views on the page.
	     */
	    FloatSliderView.prototype._validate_slide_value = function (x) {
	        return x;
	    };
	    return FloatSliderView;
	}(widget_int_1.IntSliderView));
	exports.FloatSliderView = FloatSliderView;
	var FloatRangeSliderView = (function (_super) {
	    __extends(FloatRangeSliderView, _super);
	    function FloatRangeSliderView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseFloat;
	        // matches: whitespace?, float, whitespace?, (hyphen, colon, or en-dash), whitespace?, float
	        _this._range_regex = /^\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][-:]?\d+)?)\s*[-:–]\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)/;
	        return _this;
	    }
	    /**
	     * Validate the value of the slider before sending it to the back-end
	     * and applying it to the other views on the page.
	     */
	    FloatRangeSliderView.prototype._validate_slide_value = function (x) {
	        return x;
	    };
	    return FloatRangeSliderView;
	}(widget_int_1.IntRangeSliderView));
	exports.FloatRangeSliderView = FloatRangeSliderView;
	var FloatTextModel = (function (_super) {
	    __extends(FloatTextModel, _super);
	    function FloatTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "FloatTextModel",
	            _view_name: "FloatTextView"
	        });
	    };
	    return FloatTextModel;
	}(FloatModel));
	exports.FloatTextModel = FloatTextModel;
	var BoundedFloatTextModel = (function (_super) {
	    __extends(BoundedFloatTextModel, _super);
	    function BoundedFloatTextModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    BoundedFloatTextModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: "BoundedFloatTextModel",
	            _view_name: "FloatTextView"
	        });
	    };
	    return BoundedFloatTextModel;
	}(BoundedFloatModel));
	exports.BoundedFloatTextModel = BoundedFloatTextModel;
	var FloatTextView = (function (_super) {
	    __extends(FloatTextView, _super);
	    function FloatTextView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._parse_value = parseFloat;
	        return _this;
	    }
	    return FloatTextView;
	}(widget_int_1.IntTextView));
	exports.FloatTextView = FloatTextView;
	var FloatProgressModel = (function (_super) {
	    __extends(FloatProgressModel, _super);
	    function FloatProgressModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    FloatProgressModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'FloatProgressModel',
	            _view_name: 'ProgressView',
	            orientation: 'horizontal',
	            bar_style: '',
	            style: void 0
	        });
	    };
	    return FloatProgressModel;
	}(BoundedFloatModel));
	exports.FloatProgressModel = FloatProgressModel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_float.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_controller.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_controller.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js');
	var ControllerButtonModel = (function (_super) {
	    __extends(ControllerButtonModel, _super);
	    function ControllerButtonModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerButtonModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ControllerButtonModel',
	            _view_name: 'ControllerButtonView',
	            value: 0.0,
	            pressed: false
	        });
	    };
	    return ControllerButtonModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ControllerButtonModel = ControllerButtonModel;
	/**
	 * Very simple view for a gamepad button.
	 */
	var ControllerButtonView = (function (_super) {
	    __extends(ControllerButtonView, _super);
	    function ControllerButtonView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerButtonView.prototype.render = function () {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-controller-button');
	        this.support = document.createElement('div');
	        this.support.style.position = 'relative';
	        this.support.style.margin = '1px';
	        this.support.style.width = '16px';
	        this.support.style.height = '16px';
	        this.support.style.border = '1px solid black';
	        this.support.style.background = 'lightgray';
	        this.el.appendChild(this.support);
	        this.bar = document.createElement('div');
	        this.bar.style.position = 'absolute';
	        this.bar.style.width = '100%';
	        this.bar.style.bottom = '0px';
	        this.bar.style.background = 'gray';
	        this.support.appendChild(this.bar);
	        this.update();
	        this.label = document.createElement('div');
	        this.label.textContent = this.model.get('description');
	        this.label.style.textAlign = 'center';
	        this.el.appendChild(this.label);
	    };
	    ControllerButtonView.prototype.update = function () {
	        this.bar.style.height = (100 * this.model.get('value')) + '%';
	    };
	    return ControllerButtonView;
	}(widget_1.DOMWidgetView));
	exports.ControllerButtonView = ControllerButtonView;
	var ControllerAxisModel = (function (_super) {
	    __extends(ControllerAxisModel, _super);
	    function ControllerAxisModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerAxisModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ControllerAxisModel',
	            _view_name: 'ControllerAxisView',
	            value: 0.0
	        });
	    };
	    return ControllerAxisModel;
	}(widget_core_1.CoreDOMWidgetModel));
	exports.ControllerAxisModel = ControllerAxisModel;
	/**
	 * Very simple view for a gamepad axis.
	 */
	var ControllerAxisView = (function (_super) {
	    __extends(ControllerAxisView, _super);
	    function ControllerAxisView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerAxisView.prototype.render = function () {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-controller-axis');
	        this.el.style.width = '16px';
	        this.el.style.padding = '4px';
	        this.support = document.createElement('div');
	        this.support.style.position = 'relative';
	        this.support.style.margin = '1px';
	        this.support.style.width = '4px';
	        this.support.style.height = '64px';
	        this.support.style.border = '1px solid black';
	        this.support.style.background = 'lightgray';
	        this.bullet = document.createElement('div');
	        this.bullet.style.position = 'absolute';
	        this.bullet.style.margin = '-4px';
	        this.bullet.style.width = '10px';
	        this.bullet.style.height = '10px';
	        this.bullet.style.background = 'gray';
	        this.label = document.createElement('div');
	        this.label.textContent = this.model.get('description');
	        this.label.style.textAlign = 'center';
	        this.support.appendChild(this.bullet);
	        this.el.appendChild(this.support);
	        this.el.appendChild(this.label);
	        this.update();
	    };
	    ControllerAxisView.prototype.update = function () {
	        this.bullet.style.top = (50 * (this.model.get('value') + 1)) + '%';
	    };
	    return ControllerAxisView;
	}(widget_1.DOMWidgetView));
	exports.ControllerAxisView = ControllerAxisView;
	var ControllerModel = (function (_super) {
	    __extends(ControllerModel, _super);
	    function ControllerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ControllerModel',
	            _view_name: 'ControllerView',
	            index: 0,
	            name: '',
	            mapping: '',
	            connected: false,
	            timestamp: 0,
	            buttons: [],
	            axes: []
	        });
	    };
	    ControllerModel.prototype.initialize = function (attributes, options) {
	        _super.prototype.initialize.call(this, attributes, options);
	        if (navigator.getGamepads === void 0) {
	            // Checks if the browser supports the gamepad API
	            this.readout = 'This browser does not support gamepads.';
	            console.error(this.readout);
	        }
	        else {
	            // Start the wait loop, and listen to updates of the only
	            // user-provided attribute, the gamepad index.
	            this.readout = 'Connect gamepad and press any button.';
	            if (this.get('connected')) {
	                // No need to re-create Button and Axis widgets, re-use
	                // the models provided by the backend which may already
	                // be wired to other things.
	                this.update_loop();
	            }
	            else {
	                // Wait for a gamepad to be connected.
	                this.wait_loop();
	            }
	        }
	    };
	    /**
	     * Waits for a gamepad to be connected at the provided index.
	     * Once one is connected, it will start the update loop, which
	     * populates the update of axes and button values.
	     */
	    ControllerModel.prototype.wait_loop = function () {
	        var index = this.get('index');
	        var pad = navigator.getGamepads()[index];
	        if (pad) {
	            var that = this;
	            this.setup(pad).then(function (controls) {
	                that.set(controls);
	                that.save_changes();
	                window.requestAnimationFrame(that.update_loop.bind(that));
	            });
	        }
	        else {
	            window.requestAnimationFrame(this.wait_loop.bind(this));
	        }
	    };
	    /**
	     * Given a native gamepad object, returns a promise for a dictionary of
	     * controls, of the form
	     * {
	     *     buttons: list of Button models,
	     *     axes: list of Axis models,
	     * }
	     */
	    ControllerModel.prototype.setup = function (pad) {
	        // Set up the main gamepad attributes
	        this.set({
	            name: pad.id,
	            mapping: pad.mapping,
	            connected: pad.connected,
	            timestamp: pad.timestamp
	        });
	        // Create buttons and axes. When done, start the update loop
	        var that = this;
	        return utils.resolvePromisesDict({
	            buttons: Promise.all(pad.buttons.map(function (btn, index) {
	                return that._create_button_model(index);
	            })),
	            axes: Promise.all(pad.axes.map(function (axis, index) {
	                return that._create_axis_model(index);
	            })),
	        });
	    };
	    /**
	     * Update axes and buttons values, until the gamepad is disconnected.
	     * When the gamepad is disconnected, this.reset_gamepad is called.
	     */
	    ControllerModel.prototype.update_loop = function () {
	        var index = this.get('index');
	        var id = this.get('name');
	        var pad = navigator.getGamepads()[index];
	        if (pad && index === pad.index && id === pad.id) {
	            this.set({
	                timestamp: pad.timestamp,
	                connected: pad.connected
	            });
	            this.save_changes();
	            this.get('buttons').forEach(function (model, index) {
	                model.set({
	                    value: pad.buttons[index].value,
	                    pressed: pad.buttons[index].pressed
	                });
	                model.save_changes();
	            });
	            this.get('axes').forEach(function (model, index) {
	                model.set('value', pad.axes[index]);
	                model.save_changes();
	            });
	            window.requestAnimationFrame(this.update_loop.bind(this));
	        }
	        else {
	            this.reset_gamepad();
	        }
	    };
	    /**
	     * Resets the gamepad attributes, and start the wait_loop.
	     */
	    ControllerModel.prototype.reset_gamepad = function () {
	        this.get('buttons').forEach(function (button) {
	            button.close();
	        });
	        this.get('axes').forEach(function (axis) {
	            axis.close();
	        });
	        this.set({
	            name: '',
	            mapping: '',
	            connected: false,
	            timestamp: 0.0,
	            buttons: [],
	            axes: []
	        });
	        this.save_changes();
	        window.requestAnimationFrame(this.wait_loop.bind(this));
	    };
	    /**
	     * Creates a gamepad button widget.
	     */
	    ControllerModel.prototype._create_button_model = function (index) {
	        return this.widget_manager.new_widget({
	            model_name: 'ControllerButtonModel',
	            model_module: 'jupyter-js-widgets',
	            model_module_version: this.get('_model_module_version'),
	            view_name: 'ControllerButtonView',
	            view_module: 'jupyter-js-widgets',
	            view_module_version: this.get('_view_module_version'),
	        }).then(function (model) {
	            model.set('description', index);
	            return model;
	        });
	    };
	    /**
	     * Creates a gamepad axis widget.
	     */
	    ControllerModel.prototype._create_axis_model = function (index) {
	        return this.widget_manager.new_widget({
	            model_name: 'ControllerAxisModel',
	            model_module: 'jupyter-js-widgets',
	            model_module_version: this.get('_model_module_version'),
	            view_name: 'ControllerAxisView',
	            view_module: 'jupyter-js-widgets',
	            view_module_version: this.get('_view_module_version'),
	        }).then(function (model) {
	            model.set('description', index);
	            return model;
	        });
	    };
	    return ControllerModel;
	}(widget_core_1.CoreDOMWidgetModel));
	ControllerModel.serializers = _.extend({
	    buttons: { deserialize: widget_1.unpack_models },
	    axes: { deserialize: widget_1.unpack_models }
	}, widget_core_1.CoreDOMWidgetModel.serializers);
	exports.ControllerModel = ControllerModel;
	/**
	 * A simple view for a gamepad.
	 */
	var ControllerView = (function (_super) {
	    __extends(ControllerView, _super);
	    function ControllerView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ControllerView.prototype.initialize = function (parameters) {
	        _super.prototype.initialize.call(this, parameters);
	        this.button_views = new widget_1.ViewList(this.add_button, null, this);
	        this.listenTo(this.model, 'change:buttons', function (model, value) {
	            this.button_views.update(value);
	        });
	        this.axis_views = new widget_1.ViewList(this.add_axis, null, this);
	        this.listenTo(this.model, 'change:axes', function (model, value) {
	            this.axis_views.update(value);
	        });
	        this.listenTo(this.model, 'change:name', this.update_label);
	    };
	    ControllerView.prototype.render = function () {
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-controller');
	        this.box = this.el;
	        this.label = document.createElement('div');
	        this.box.appendChild(this.label);
	        this.axis_box = document.createElement('div');
	        this.axis_box.style.display = 'flex';
	        this.box.appendChild(this.axis_box);
	        this.button_box = document.createElement('div');
	        this.button_box.style.display = 'flex';
	        this.box.appendChild(this.button_box);
	        this.button_views.update(this.model.get('buttons'));
	        this.axis_views.update(this.model.get('axes'));
	        this.update_label();
	    };
	    ControllerView.prototype.update_label = function () {
	        this.label.textContent = this.model.get('name') || this.model.readout;
	    };
	    ControllerView.prototype.add_button = function (model) {
	        var that = this;
	        var dummy = document.createElement('div');
	        that.button_box.appendChild(dummy);
	        return this.create_child_view(model).then(function (view) {
	            that.button_box.replaceChild(view.el, dummy);
	            that.displayed.then(function () {
	                view.trigger('displayed', that);
	            });
	            return view;
	        }).catch(utils.reject('Could not add button view', true));
	    };
	    ControllerView.prototype.add_axis = function (model) {
	        var that = this;
	        var dummy = document.createElement('div');
	        that.axis_box.appendChild(dummy);
	        return this.create_child_view(model).then(function (view) {
	            that.axis_box.replaceChild(view.el, dummy);
	            that.displayed.then(function () {
	                view.trigger('displayed', that);
	            });
	            return view;
	        }).catch(utils.reject('Could not add axis view', true));
	    };
	    ControllerView.prototype.remove = function () {
	        _super.prototype.remove.call(this);
	        this.button_views.remove();
	        this.axis_views.remove();
	    };
	    return ControllerView;
	}(widget_1.DOMWidgetView));
	exports.ControllerView = ControllerView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_controller.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selection.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selection.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_core_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_core.js');
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	function scrollIfNeeded(area, elem) {
	    var ar = area.getBoundingClientRect();
	    var er = elem.getBoundingClientRect();
	    if (er.top < ar.top) {
	        area.scrollTop -= ar.top - er.top;
	    }
	    else if (er.bottom > ar.bottom) {
	        area.scrollTop += er.bottom - ar.bottom;
	    }
	}
	var SelectionModel = (function (_super) {
	    __extends(SelectionModel, _super);
	    function SelectionModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectionModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SelectionModel',
	            index: '',
	            _options_labels: [],
	            disabled: false,
	        });
	    };
	    return SelectionModel;
	}(widget_core_1.CoreLabeledDOMWidgetModel));
	exports.SelectionModel = SelectionModel;
	var DropdownModel = (function (_super) {
	    __extends(DropdownModel, _super);
	    function DropdownModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    DropdownModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'DropdownModel',
	            _view_name: 'DropdownView',
	            button_style: ''
	        });
	    };
	    return DropdownModel;
	}(SelectionModel));
	exports.DropdownModel = DropdownModel;
	// TODO: Make a phosphor dropdown control, wrapped in DropdownView. Also, fix
	// bugs in keyboard handling. See
	// https://github.com/jupyter-widgets/ipywidgets/issues/1055 and
	// https://github.com/jupyter-widgets/ipywidgets/issues/1049
	// For now, we subclass SelectView to provide DropdownView
	// For the old code, see commit f68bfbc566f3a78a8f3350b438db8ed523ce3642
	var DropdownView = (function (_super) {
	    __extends(DropdownView, _super);
	    function DropdownView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor.
	     */
	    DropdownView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.listenTo(this.model, 'change:_options_labels', function () { return _this._updateOptions(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    DropdownView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-dropdown');
	        this.listbox = document.createElement('select');
	        this.el.appendChild(this.listbox);
	        this._updateOptions();
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     */
	    DropdownView.prototype.update = function () {
	        // Disable listbox if needed
	        this.listbox.disabled = this.model.get('disabled');
	        // Select the correct element
	        var index = this.model.get('index');
	        this.listbox.selectedIndex = index === null ? -1 : index;
	        return _super.prototype.update.call(this);
	    };
	    DropdownView.prototype._updateOptions = function () {
	        this.listbox.textContent = '';
	        var items = this.model.get('_options_labels');
	        for (var i = 0; i < items.length; i++) {
	            var item = items[i];
	            var option = document.createElement('option');
	            option.textContent = item.replace(/ /g, '\xa0'); // space -> &nbsp;
	            option.setAttribute('data-value', encodeURIComponent(item));
	            option.value = item;
	            this.listbox.appendChild(option);
	        }
	    };
	    DropdownView.prototype.events = function () {
	        return {
	            'change select': '_handle_change'
	        };
	    };
	    /**
	     * Handle when a new value is selected.
	     */
	    DropdownView.prototype._handle_change = function () {
	        this.model.set('index', this.listbox.selectedIndex === -1 ? null : this.listbox.selectedIndex);
	        this.touch();
	    };
	    return DropdownView;
	}(widget_1.LabeledDOMWidgetView));
	exports.DropdownView = DropdownView;
	var SelectModel = (function (_super) {
	    __extends(SelectModel, _super);
	    function SelectModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SelectModel',
	            _view_name: 'SelectView',
	            rows: 5
	        });
	    };
	    return SelectModel;
	}(SelectionModel));
	exports.SelectModel = SelectModel;
	var SelectView = (function (_super) {
	    __extends(SelectView, _super);
	    function SelectView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Public constructor.
	     */
	    SelectView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.listenTo(this.model, 'change:_options_labels', function () { return _this._updateOptions(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    SelectView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-select');
	        this.listbox = document.createElement('select');
	        this.el.appendChild(this.listbox);
	        this._updateOptions();
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     */
	    SelectView.prototype.update = function () {
	        _super.prototype.update.call(this);
	        // Disable listbox if needed
	        this.listbox.disabled = this.model.get('disabled');
	        this.listbox.size = this.model.get('rows');
	        this.updateSelection();
	    };
	    SelectView.prototype.updateSelection = function () {
	        var index = this.model.get('index');
	        this.listbox.selectedIndex = index === null ? -1 : index;
	    };
	    SelectView.prototype._updateOptions = function () {
	        this.listbox.textContent = '';
	        var items = this.model.get('_options_labels');
	        for (var i = 0; i < items.length; i++) {
	            var item = items[i];
	            var option = document.createElement('option');
	            option.textContent = item.replace(/ /g, '\xa0'); // space -> &nbsp;
	            option.setAttribute('data-value', encodeURIComponent(item));
	            option.value = item;
	            this.listbox.appendChild(option);
	        }
	    };
	    SelectView.prototype.events = function () {
	        return {
	            'change select': '_handle_change'
	        };
	    };
	    /**
	     * Handle when a new value is selected.
	     */
	    SelectView.prototype._handle_change = function () {
	        // Don't use [] indexing to work around https://github.com/Microsoft/TypeScript/issues/14522
	        this.model.set('index', this.listbox.selectedIndex);
	        this.touch();
	    };
	    return SelectView;
	}(widget_1.LabeledDOMWidgetView));
	exports.SelectView = SelectView;
	var RadioButtonsModel = (function (_super) {
	    __extends(RadioButtonsModel, _super);
	    function RadioButtonsModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    RadioButtonsModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'RadioButtonsModel',
	            _view_name: 'RadioButtonsView',
	            tooltips: [],
	            icons: [],
	            button_style: ''
	        });
	    };
	    return RadioButtonsModel;
	}(SelectionModel));
	exports.RadioButtonsModel = RadioButtonsModel;
	var RadioButtonsView = (function (_super) {
	    __extends(RadioButtonsView, _super);
	    function RadioButtonsView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    RadioButtonsView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-radio');
	        this.container = document.createElement('div');
	        this.el.appendChild(this.container);
	        this.container.classList.add('widget-radio-box');
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    RadioButtonsView.prototype.update = function (options) {
	        var view = this;
	        var items = this.model.get('_options_labels');
	        var radios = _.pluck(this.container.querySelectorAll('input[type="radio"]'), 'value');
	        var stale = false;
	        for (var i = 0, len = items.length; i < len; ++i) {
	            if (radios[i] !== items[i]) {
	                stale = true;
	                break;
	            }
	        }
	        if (stale && (options === undefined || options.updated_view !== this)) {
	            // Add items to the DOM.
	            this.container.textContent = '';
	            _.each(items, function (item, index) {
	                var label = document.createElement('label');
	                label.textContent = item;
	                view.container.appendChild(label);
	                var radio = document.createElement('input');
	                radio.setAttribute('type', 'radio');
	                radio.value = index.toString();
	                radio.setAttribute('data-value', encodeURIComponent(item));
	                label.appendChild(radio);
	            });
	        }
	        _.each(items, function (item, index) {
	            var item_query = 'input[data-value="' +
	                encodeURIComponent(item) + '"]';
	            var radio = view.container.querySelectorAll(item_query);
	            if (radio.length > 0) {
	                var radio_el = radio[0];
	                radio_el.checked = view.model.get('index') === index;
	                radio_el.disabled = view.model.get('disabled');
	            }
	        });
	        return _super.prototype.update.call(this, options);
	    };
	    RadioButtonsView.prototype.events = function () {
	        return {
	            'click input[type="radio"]': '_handle_click'
	        };
	    };
	    /**
	     * Handle when a value is clicked.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    RadioButtonsView.prototype._handle_click = function (event) {
	        this.model.set('index', parseInt(event.target.value), { updated_view: this });
	        this.touch();
	    };
	    return RadioButtonsView;
	}(widget_1.LabeledDOMWidgetView));
	exports.RadioButtonsView = RadioButtonsView;
	var ToggleButtonsModel = (function (_super) {
	    __extends(ToggleButtonsModel, _super);
	    function ToggleButtonsModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ToggleButtonsModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'ToggleButtonsModel',
	            _view_name: 'ToggleButtonsView'
	        });
	    };
	    return ToggleButtonsModel;
	}(SelectionModel));
	exports.ToggleButtonsModel = ToggleButtonsModel;
	var ToggleButtonsView = (function (_super) {
	    __extends(ToggleButtonsView, _super);
	    function ToggleButtonsView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    ToggleButtonsView.prototype.initialize = function (options) {
	        this._css_state = {};
	        _super.prototype.initialize.call(this, options);
	        this.listenTo(this.model, 'change:button_style', this.update_button_style);
	    };
	    /**
	     * Called when view is rendered.
	     */
	    ToggleButtonsView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-toggle-buttons');
	        this.buttongroup = document.createElement('div');
	        this.el.appendChild(this.buttongroup);
	        this.update();
	        this.set_button_style();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    ToggleButtonsView.prototype.update = function (options) {
	        var view = this;
	        var items = this.model.get('_options_labels');
	        var icons = this.model.get('icons') || [];
	        var previous_icons = this.model.previous('icons') || [];
	        var previous_bstyle = ToggleButtonsView.classMap[this.model.previous('button_style')] || '';
	        var tooltips = view.model.get('tooltips') || [];
	        var disabled = this.model.get('disabled');
	        var buttons = this.buttongroup.querySelectorAll('button');
	        var values = _.pluck(buttons, 'value');
	        var stale = false;
	        for (var i = 0, len = items.length; i < len; ++i) {
	            if (values[i] !== items[i] || icons[i] !== previous_icons[i]) {
	                stale = true;
	                break;
	            }
	        }
	        if (stale && options === undefined || options.updated_view !== this) {
	            // Add items to the DOM.
	            this.buttongroup.textContent = '';
	            _.each(items, function (item, index) {
	                var item_html;
	                var empty = item.trim().length === 0 &&
	                    (!icons[index] || icons[index].trim().length === 0);
	                if (empty) {
	                    item_html = '&nbsp;';
	                }
	                else {
	                    item_html = utils.escape_html(item);
	                }
	                var icon = document.createElement('i');
	                var button = document.createElement('button');
	                if (icons[index]) {
	                    icon.className = 'fa fa-' + icons[index];
	                }
	                button.setAttribute('type', 'button');
	                button.className = 'widget-toggle-button jupyter-button';
	                if (previous_bstyle) {
	                    button.classList.add(previous_bstyle);
	                }
	                button.innerHTML = item_html;
	                button.setAttribute('data-value', encodeURIComponent(item));
	                button.setAttribute('value', index.toString());
	                button.appendChild(icon);
	                button.disabled = disabled;
	                if (tooltips[index]) {
	                    button.setAttribute('title', tooltips[index]);
	                }
	                view.update_style_traits(button);
	                view.buttongroup.appendChild(button);
	            });
	        }
	        // Select active button.
	        _.each(items, function (item, index) {
	            var item_query = '[data-value="' + encodeURIComponent(item) + '"]';
	            var button = view.buttongroup.querySelector(item_query);
	            if (view.model.get('index') === index) {
	                button.classList.add('mod-active');
	            }
	            else {
	                button.classList.remove('mod-active');
	            }
	        });
	        return _super.prototype.update.call(this, options);
	    };
	    ToggleButtonsView.prototype.update_style_traits = function (button) {
	        for (var name in this._css_state) {
	            if (this._css_state.hasOwnProperty(name)) {
	                if (name === 'margin') {
	                    this.buttongroup.style[name] = this._css_state[name];
	                }
	                else if (name !== 'width') {
	                    if (button) {
	                        button.style[name] = this._css_state[name];
	                    }
	                    else {
	                        var buttons = this.buttongroup
	                            .querySelectorAll('button');
	                        if (buttons.length) {
	                            buttons[0].style[name] = this._css_state[name];
	                        }
	                    }
	                }
	            }
	        }
	    };
	    ToggleButtonsView.prototype.update_button_style = function () {
	        var _this = this;
	        var buttons = this.buttongroup.querySelectorAll('button');
	        _.each(buttons, function (button) {
	            _this.update_mapped_classes(ToggleButtonsView.classMap, 'button_style', button);
	        });
	    };
	    ToggleButtonsView.prototype.set_button_style = function () {
	        var _this = this;
	        var buttons = this.buttongroup.querySelectorAll('button');
	        _.each(buttons, function (button) {
	            _this.set_mapped_classes(ToggleButtonsView.classMap, 'button_style', button);
	        });
	    };
	    ToggleButtonsView.prototype.events = function () {
	        return {
	            'click button': '_handle_click'
	        };
	    };
	    /**
	     * Handle when a value is clicked.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    ToggleButtonsView.prototype._handle_click = function (event) {
	        this.model.set('index', parseInt(event.target.value), { updated_view: this });
	        this.touch();
	        // We also send a clicked event, since the value is only set if it changed.
	        // See https://github.com/jupyter-widgets/ipywidgets/issues/763
	        this.send({ event: 'click' });
	    };
	    return ToggleButtonsView;
	}(widget_1.LabeledDOMWidgetView));
	exports.ToggleButtonsView = ToggleButtonsView;
	(function (ToggleButtonsView) {
	    ToggleButtonsView.classMap = {
	        primary: ['mod-primary'],
	        success: ['mod-success'],
	        info: ['mod-info'],
	        warning: ['mod-warning'],
	        danger: ['mod-danger']
	    };
	})(ToggleButtonsView = exports.ToggleButtonsView || (exports.ToggleButtonsView = {}));
	exports.ToggleButtonsView = ToggleButtonsView;
	var SelectionSliderModel = (function (_super) {
	    __extends(SelectionSliderModel, _super);
	    function SelectionSliderModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectionSliderModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SelectionSliderModel',
	            _view_name: 'SelectionSliderView',
	            orientation: 'horizontal',
	            readout: true,
	            continuous_update: true
	        });
	    };
	    return SelectionSliderModel;
	}(SelectionModel));
	exports.SelectionSliderModel = SelectionSliderModel;
	var SelectionSliderView = (function (_super) {
	    __extends(SelectionSliderView, _super);
	    function SelectionSliderView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    SelectionSliderView.prototype.render = function () {
	        var _this = this;
	        _super.prototype.render.call(this);
	        this.el.classList.add('jupyter-widgets');
	        this.el.classList.add('widget-inline-hbox');
	        this.el.classList.add('widget-hslider');
	        this.el.classList.add('widget-slider');
	        (this.$slider = $('<div />'))
	            .slider({
	            slide: this.handleSliderChange.bind(this),
	            stop: this.handleSliderChanged.bind(this)
	        })
	            .addClass('slider');
	        // Put the slider in a container
	        this.slider_container = document.createElement('div');
	        this.slider_container.classList.add('slider-container');
	        this.slider_container.appendChild(this.$slider[0]);
	        this.el.appendChild(this.slider_container);
	        this.readout = document.createElement('div');
	        this.el.appendChild(this.readout);
	        this.readout.classList.add('widget-readout');
	        this.readout.style.display = 'none';
	        this.listenTo(this.model, 'change:slider_color', function (sender, value) {
	            _this.$slider.find('a').css('background', value);
	        });
	        this.$slider.find('a').css('background', this.model.get('slider_color'));
	        // Set defaults.
	        this.update();
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    SelectionSliderView.prototype.update = function (options) {
	        if (options === undefined || options.updated_view != this) {
	            var labels = this.model.get('_options_labels');
	            var max = labels.length - 1;
	            var min = 0;
	            this.$slider.slider('option', 'step', 1);
	            this.$slider.slider('option', 'max', max);
	            this.$slider.slider('option', 'min', min);
	            // WORKAROUND FOR JQUERY SLIDER BUG.
	            // The horizontal position of the slider handle
	            // depends on the value of the slider at the time
	            // of orientation change.  Before applying the new
	            // workaround, we set the value to the minimum to
	            // make sure that the horizontal placement of the
	            // handle in the vertical slider is always
	            // consistent.
	            var orientation = this.model.get('orientation');
	            this.$slider.slider('option', 'value', min);
	            this.$slider.slider('option', 'orientation', orientation);
	            var index = this.model.get('index');
	            var value = labels[index];
	            this.$slider.slider('option', 'value', index);
	            this.readout.textContent = value;
	            // Use the right CSS classes for vertical & horizontal sliders
	            if (orientation === 'vertical') {
	                this.el.classList.remove('widget-hslider');
	                this.el.classList.remove('widget-inline-hbox');
	                this.el.classList.add('widget-vslider');
	                this.el.classList.add('widget-inline-vbox');
	            }
	            else {
	                this.el.classList.remove('widget-vslider');
	                this.el.classList.remove('widget-inline-vbox');
	                this.el.classList.add('widget-hslider');
	                this.el.classList.add('widget-inline-hbox');
	            }
	            var readout = this.model.get('readout');
	            if (readout) {
	                // this.$readout.show();
	                this.readout.style.display = '';
	            }
	            else {
	                // this.$readout.hide();
	                this.readout.style.display = 'none';
	            }
	        }
	        return _super.prototype.update.call(this, options);
	    };
	    SelectionSliderView.prototype.events = function () {
	        return {
	            'slide': 'handleSliderChange',
	            'slidestop': 'handleSliderChanged'
	        };
	    };
	    /**
	     * Called when the slider value is changing.
	     */
	    SelectionSliderView.prototype.handleSliderChange = function (e, ui) {
	        var actual_value = this._validate_slide_value(ui.value);
	        var selected_label = this.model.get('_options_labels')[actual_value];
	        this.readout.textContent = selected_label;
	        // Only persist the value while sliding if the continuous_update
	        // trait is set to true.
	        if (this.model.get('continuous_update')) {
	            this.handleSliderChanged(e, ui);
	        }
	    };
	    /**
	     * Called when the slider value has changed.
	     *
	     * Calling model.set will trigger all of the other views of the
	     * model to update.
	     */
	    SelectionSliderView.prototype.handleSliderChanged = function (e, ui) {
	        var actual_value = this._validate_slide_value(ui.value);
	        this.readout.textContent = this.model.get('_options_labels')[actual_value];
	        this.model.set('index', actual_value, { updated_view: this });
	        this.touch();
	    };
	    SelectionSliderView.prototype._validate_slide_value = function (x) {
	        /**
	         * Validate the value of the slider before sending it to the back-end
	         * and applying it to the other views on the page.
	         */
	        return Math.floor(x);
	    };
	    return SelectionSliderView;
	}(widget_1.LabeledDOMWidgetView));
	exports.SelectionSliderView = SelectionSliderView;
	var MultipleSelectionModel = (function (_super) {
	    __extends(MultipleSelectionModel, _super);
	    function MultipleSelectionModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    MultipleSelectionModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'MultipleSelectionModel',
	        });
	    };
	    return MultipleSelectionModel;
	}(SelectionModel));
	exports.MultipleSelectionModel = MultipleSelectionModel;
	var SelectMultipleModel = (function (_super) {
	    __extends(SelectMultipleModel, _super);
	    function SelectMultipleModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectMultipleModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SelectMultipleModel',
	            _view_name: 'SelectMultipleView',
	            rows: null
	        });
	    };
	    return SelectMultipleModel;
	}(MultipleSelectionModel));
	exports.SelectMultipleModel = SelectMultipleModel;
	var SelectMultipleView = (function (_super) {
	    __extends(SelectMultipleView, _super);
	    function SelectMultipleView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    /**
	     * Called when view is rendered.
	     */
	    SelectMultipleView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        this.el.classList.add('widget-select-multiple');
	        this.listbox.multiple = true;
	    };
	    SelectMultipleView.prototype.updateSelection = function () {
	        // Set selected values
	        var selected = this.model.get('index') || [];
	        var options = this.listbox.options;
	        this.listbox.selectedIndex = -1;
	        selected.forEach(function (i) {
	            // Don't use [] indexing to work around https://github.com/Microsoft/TypeScript/issues/14522
	            options.item(i).selected = true;
	        });
	    };
	    /**
	     * Handle when a new value is selected.
	     */
	    SelectMultipleView.prototype._handle_change = function () {
	        var index = Array.prototype.map
	            .call(this.listbox.selectedOptions || [], function (option) {
	            return option.index;
	        });
	        this.model.set('index', index);
	        this.touch();
	    };
	    return SelectMultipleView;
	}(SelectView));
	exports.SelectMultipleView = SelectMultipleView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selection.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selectioncontainer.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selectioncontainer.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widget_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget.js');
	var widget_box_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/widget_box.js');
	var tabpanel_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/tabpanel.js');
	var accordion_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/accordion.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.1.0/lib/index.js');
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.1.0/lib/index.js');
	var _ = __jupyter_require__('underscore@^1.8.3/underscore.js');
	var utils = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/utils.js');
	var $ = __jupyter_require__('jquery@^3.1.1/dist/jquery.js');
	var SelectionContainerModel = (function (_super) {
	    __extends(SelectionContainerModel, _super);
	    function SelectionContainerModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    SelectionContainerModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'SelectionContainerModel',
	            selected_index: 0,
	            _titles: {}
	        });
	    };
	    return SelectionContainerModel;
	}(widget_box_1.BoxModel));
	exports.SelectionContainerModel = SelectionContainerModel;
	var AccordionModel = (function (_super) {
	    __extends(AccordionModel, _super);
	    function AccordionModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    AccordionModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'AccordionModel',
	            _view_name: 'AccordionView'
	        });
	    };
	    return AccordionModel;
	}(SelectionContainerModel));
	exports.AccordionModel = AccordionModel;
	// We implement our own tab widget since Phoshpor's TabPanel uses an absolute
	// positioning BoxLayout, but we want a more an html/css-based Panel layout.
	var JupyterPhosphorAccordionWidget = (function (_super) {
	    __extends(JupyterPhosphorAccordionWidget, _super);
	    function JupyterPhosphorAccordionWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        return _this;
	    }
	    /**
	     * Process the phosphor message.
	     *
	     * Any custom phosphor widget used inside a Jupyter widget should override
	     * the processMessage function like this.
	     */
	    JupyterPhosphorAccordionWidget.prototype.processMessage = function (msg) {
	        _super.prototype.processMessage.call(this, msg);
	        this._view.processPhosphorMessage(msg);
	    };
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorAccordionWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    return JupyterPhosphorAccordionWidget;
	}(accordion_1.Accordion));
	exports.JupyterPhosphorAccordionWidget = JupyterPhosphorAccordionWidget;
	var AccordionView = (function (_super) {
	    __extends(AccordionView, _super);
	    function AccordionView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    AccordionView.prototype._createElement = function (tagName) {
	        this.pWidget = new JupyterPhosphorAccordionWidget({ view: this });
	        return this.pWidget.node;
	    };
	    AccordionView.prototype._setElement = function (el) {
	        if (this.el || el !== this.pWidget.node) {
	            // Accordions don't allow setting the element beyond the initial creation.
	            throw new Error('Cannot reset the DOM element.');
	        }
	        this.el = this.pWidget.node;
	        this.$el = $(this.pWidget.node);
	    };
	    AccordionView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.children_views = new widget_1.ViewList(this.add_child_view, this.remove_child_view, this);
	        this.listenTo(this.model, 'change:children', function () { return _this.updateChildren(); });
	        this.listenTo(this.model, 'change:selected_index', function () { return _this.update_selected_index(); });
	        this.listenTo(this.model, 'change:_titles', function () { return _this.update_titles(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    AccordionView.prototype.render = function () {
	        var _this = this;
	        _super.prototype.render.call(this);
	        var accordion = this.pWidget;
	        accordion.addClass('jupyter-widgets');
	        accordion.addClass('widget-accordion');
	        accordion.addClass('widget-container');
	        accordion.selection.selectionChanged.connect(function (sender) {
	            if (!_this.updatingChildren) {
	                _this.model.set('selected_index', accordion.selection.index);
	                _this.touch();
	            }
	        });
	        this.children_views.update(this.model.get('children'));
	        this.update_titles();
	        this.update_selected_index();
	    };
	    /**
	     * Update children
	     */
	    AccordionView.prototype.updateChildren = function () {
	        // While we are updating, the index may not be valid, so deselect the
	        // tabs before updating so we don't get spurious changes in the index,
	        // which would then set off another sync cycle.
	        this.updatingChildren = true;
	        this.pWidget.selection.index = -1;
	        this.children_views.update(this.model.get('children'));
	        this.update_selected_index();
	        this.updatingChildren = false;
	    };
	    /**
	     * Set header titles
	     */
	    AccordionView.prototype.update_titles = function () {
	        var widgets = this.pWidget.widgets;
	        var titles = this.model.get('_titles');
	        for (var i = 0; i < widgets.length; i++) {
	            if (titles[i] !== void 0) {
	                widgets[i].title.label = titles[i];
	            }
	        }
	    };
	    /**
	     * Make the rendering and selected index consistent.
	     */
	    AccordionView.prototype.update_selected_index = function () {
	        this.pWidget.selection.index = this.model.get('selected_index');
	    };
	    /**
	     * Called when a child is removed from children list.
	     */
	    AccordionView.prototype.remove_child_view = function (view) {
	        this.pWidget.removeWidget(view.pWidget);
	        view.remove();
	    };
	    /**
	     * Called when a child is added to children list.
	     */
	    AccordionView.prototype.add_child_view = function (model, index) {
	        // Placeholder widget to keep our position in the tab panel while we create the view.
	        var accordion = this.pWidget;
	        var placeholder = new widgets_1.Widget();
	        placeholder.title.label = this.model.get('_titles')[index] || '';
	        ;
	        accordion.addWidget(placeholder);
	        return this.create_child_view(model).then(function (view) {
	            var widget = view.pWidget;
	            widget.title.label = placeholder.title.label;
	            var collapse = accordion.collapseWidgets[accordion.indexOf(placeholder)];
	            collapse.widget = widget;
	            placeholder.dispose();
	            return view;
	        }).catch(utils.reject('Could not add child view to box', true));
	    };
	    AccordionView.prototype.remove = function () {
	        this.children_views = null;
	        _super.prototype.remove.call(this);
	    };
	    return AccordionView;
	}(widget_1.DOMWidgetView));
	exports.AccordionView = AccordionView;
	var TabModel = (function (_super) {
	    __extends(TabModel, _super);
	    function TabModel() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    TabModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'TabModel',
	            _view_name: 'TabView'
	        });
	    };
	    return TabModel;
	}(SelectionContainerModel));
	exports.TabModel = TabModel;
	// We implement our own tab widget since Phoshpor's TabPanel uses an absolute
	// positioning BoxLayout, but we want a more an html/css-based Panel layout.
	var JupyterPhosphorTabPanelWidget = (function (_super) {
	    __extends(JupyterPhosphorTabPanelWidget, _super);
	    function JupyterPhosphorTabPanelWidget(options) {
	        var _this = this;
	        var view = options.view;
	        delete options.view;
	        _this = _super.call(this, options) || this;
	        _this._view = view;
	        // We want the view's messages to be the messages the tabContents panel
	        // gets.
	        messaging_1.MessageLoop.installMessageHook(_this.tabContents, function (handler, msg) {
	            // There may be times when we want the view's handler to be called
	            // *after* the message has been processed by the widget, in which
	            // case we'll need to revisit using a message hook.
	            _this._view.processPhosphorMessage(msg);
	            return true;
	        });
	        return _this;
	    }
	    /**
	     * Dispose the widget.
	     *
	     * This causes the view to be destroyed as well with 'remove'
	     */
	    JupyterPhosphorTabPanelWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        if (this._view) {
	            this._view.remove();
	        }
	        this._view = null;
	    };
	    return JupyterPhosphorTabPanelWidget;
	}(tabpanel_1.TabPanel));
	exports.JupyterPhosphorTabPanelWidget = JupyterPhosphorTabPanelWidget;
	var TabView = (function (_super) {
	    __extends(TabView, _super);
	    function TabView() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this.updatingTabs = false;
	        return _this;
	    }
	    TabView.prototype._createElement = function (tagName) {
	        this.pWidget = new JupyterPhosphorTabPanelWidget({
	            view: this,
	        });
	        return this.pWidget.node;
	    };
	    TabView.prototype._setElement = function (el) {
	        if (this.el || el !== this.pWidget.node) {
	            // TabViews don't allow setting the element beyond the initial creation.
	            throw new Error('Cannot reset the DOM element.');
	        }
	        this.el = this.pWidget.node;
	        this.$el = $(this.pWidget.node);
	    };
	    /**
	     * Public constructor.
	     */
	    TabView.prototype.initialize = function (parameters) {
	        var _this = this;
	        _super.prototype.initialize.call(this, parameters);
	        this.childrenViews = new widget_1.ViewList(this.addChildView, function (view) { view.remove(); }, this);
	        this.listenTo(this.model, 'change:children', function () { return _this.updateTabs(); });
	        this.listenTo(this.model, 'change:_titles', function () { return _this.updateTitles(); });
	    };
	    /**
	     * Called when view is rendered.
	     */
	    TabView.prototype.render = function () {
	        _super.prototype.render.call(this);
	        var tabs = this.pWidget;
	        tabs.addClass('jupyter-widgets');
	        tabs.addClass('widget-container');
	        tabs.addClass('widget-tab');
	        tabs.tabsMovable = true;
	        tabs.tabBar.insertBehavior = 'none'; // needed for insert behavior, see below.
	        tabs.tabBar.currentChanged.connect(this._onTabChanged, this);
	        tabs.tabBar.tabMoved.connect(this._onTabMoved, this);
	        tabs.tabBar.addClass('widget-tab-bar');
	        tabs.tabContents.addClass('widget-tab-contents');
	        // TODO: expose this option in python
	        tabs.tabBar.tabsMovable = false;
	        this.updateTabs();
	        this.update();
	    };
	    /**
	     * Render tab views based on the current model's children.
	     */
	    TabView.prototype.updateTabs = function () {
	        // While we are updating, the index may not be valid, so deselect the
	        // tabs before updating so we don't get spurious changes in the index,
	        // which would then set off another sync cycle.
	        this.updatingTabs = true;
	        this.pWidget.currentIndex = -1;
	        this.childrenViews.update(this.model.get('children'));
	        this.pWidget.currentIndex = this.model.get('selected_index');
	        this.updatingTabs = false;
	    };
	    /**
	     * Called when a child is added to children list.
	     */
	    TabView.prototype.addChildView = function (model, index) {
	        // Placeholder widget to keep our position in the tab panel while we create the view.
	        var label = this.model.get('_titles')[index] || '';
	        var tabs = this.pWidget;
	        var placeholder = new widgets_1.Widget();
	        placeholder.title.label = label;
	        tabs.addWidget(placeholder);
	        return this.create_child_view(model).then(function (view) {
	            var widget = view.pWidget;
	            widget.title.label = placeholder.title.label;
	            widget.title.closable = true;
	            var i = algorithm_1.ArrayExt.firstIndexOf(tabs.widgets, placeholder);
	            // insert after placeholder so that if placholder is selected, the
	            // real widget will be selected now (this depends on the tab bar
	            // insert behavior)
	            tabs.insertWidget(i + 1, widget);
	            placeholder.dispose();
	            return view;
	        }).catch(utils.reject('Could not add child view to box', true));
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    TabView.prototype.update = function () {
	        // Update the selected index in the overall update method because it
	        // should be run after the tabs have been updated. Otherwise the
	        // selected index may not be a valid tab in the tab bar.
	        this.updateSelectedIndex();
	        return _super.prototype.update.call(this);
	    };
	    /**
	     * Updates the tab page titles.
	     */
	    TabView.prototype.updateTitles = function () {
	        var titles = this.model.get('_titles') || {};
	        algorithm_1.each(this.pWidget.widgets, function (widget, i) {
	            widget.title.label = titles[i] || '';
	        });
	    };
	    /**
	     * Updates the selected index.
	     */
	    TabView.prototype.updateSelectedIndex = function () {
	        this.pWidget.currentIndex = this.model.get('selected_index');
	    };
	    TabView.prototype.remove = function () {
	        this.childrenViews = null;
	        _super.prototype.remove.call(this);
	    };
	    TabView.prototype._onTabChanged = function (sender, args) {
	        if (!this.updatingTabs) {
	            this.model.set('selected_index', args.currentIndex);
	            this.touch();
	        }
	    };
	    /**
	     * Handle the `tabMoved` signal from the tab bar.
	     */
	    TabView.prototype._onTabMoved = function (sender, args) {
	        var children = this.model.get('children').slice();
	        algorithm_1.ArrayExt.move(children, args.fromIndex, args.toIndex);
	        this.model.set('children', children);
	        this.touch();
	    };
	    return TabView;
	}(widget_1.DOMWidgetView));
	exports.TabView = TabView;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/widget_selectioncontainer.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/tabpanel.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/tabpanel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	/*-----------------------------------------------------------------------------
	| Copyright (c) 2014-2017, PhosphorJS Contributors
	|
	| Distributed under the terms of the BSD 3-Clause License.
	|
	| The full license is in the file LICENSE, distributed with this software.
	|----------------------------------------------------------------------------*/
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.1.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@1.2.1/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.1.0/lib/index.js');
	/**
	 * A panel where visible widgets are stacked atop one another.
	 *
	 * #### Notes
	 * This class provides a convenience wrapper around a [[PanelLayout]].
	 */
	var EventedPanel = (function (_super) {
	    __extends(EventedPanel, _super);
	    function EventedPanel() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._widgetRemoved = new signaling_1.Signal(_this);
	        return _this;
	    }
	    Object.defineProperty(EventedPanel.prototype, "widgetRemoved", {
	        /**
	         * A signal emitted when a widget is removed from the panel.
	         */
	        get: function () {
	            return this._widgetRemoved;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * A message handler invoked on a `'child-removed'` message.
	     */
	    EventedPanel.prototype.onChildRemoved = function (msg) {
	        this._widgetRemoved.emit(msg.child);
	    };
	    return EventedPanel;
	}(widgets_1.Panel));
	exports.EventedPanel = EventedPanel;
	/**
	 * A widget which combines a `TabBar` and a `EventedPanel`.
	 *
	 * #### Notes
	 * This is a simple panel which handles the common case of a tab bar
	 * placed next to a content area. The selected tab controls the widget
	 * which is shown in the content area.
	 *
	 * For use cases which require more control than is provided by this
	 * panel, the `TabBar` widget may be used independently.
	 *
	 * TODO: Support setting the direction??
	 */
	var TabPanel = (function (_super) {
	    __extends(TabPanel, _super);
	    /**
	     * Construct a new tab panel.
	     *
	     * @param options - The options for initializing the tab panel.
	     */
	    function TabPanel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this._currentChanged = new signaling_1.Signal(_this);
	        _this.addClass('p-TabPanel');
	        // Create the tab bar and contents panel.
	        _this.tabBar = new widgets_1.TabBar(options);
	        _this.tabBar.addClass('p-TabPanel-tabBar');
	        _this.tabContents = new EventedPanel();
	        _this.tabContents.addClass('p-TabPanel-tabContents');
	        // Connect the tab bar signal handlers.
	        _this.tabBar.tabMoved.connect(_this._onTabMoved, _this);
	        _this.tabBar.currentChanged.connect(_this._onCurrentChanged, _this);
	        _this.tabBar.tabCloseRequested.connect(_this._onTabCloseRequested, _this);
	        _this.tabBar.tabActivateRequested.connect(_this._onTabActivateRequested, _this);
	        // Connect the evented panel signal handlers.
	        _this.tabContents.widgetRemoved.connect(_this._onWidgetRemoved, _this);
	        // Create the layout.
	        var layout = new widgets_1.PanelLayout();
	        // Add the child widgets to the layout.
	        layout.addWidget(_this.tabBar);
	        layout.addWidget(_this.tabContents);
	        // Install the layout on the tab panel.
	        _this.layout = layout;
	        return _this;
	    }
	    Object.defineProperty(TabPanel.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current tab is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected tab is changed
	         * either through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current
	         * tab changes due to tabs being inserted, removed, or moved. It is
	         * only emitted when the actual current tab node is changed.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentIndex", {
	        /**
	         * Get the index of the currently selected tab.
	         *
	         * #### Notes
	         * This will be `-1` if no tab is selected.
	         */
	        get: function () {
	            return this.tabBar.currentIndex;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * #### Notes
	         * If the index is out of range, it will be set to `-1`.
	         */
	        set: function (value) {
	            this.tabBar.currentIndex = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "currentWidget", {
	        /**
	         * Get the currently selected widget.
	         *
	         * #### Notes
	         * This will be `null` if there is no selected tab.
	         */
	        get: function () {
	            var title = this.tabBar.currentTitle;
	            return title ? title.owner : null;
	        },
	        /**
	         * Set the currently selected widget.
	         *
	         * #### Notes
	         * If the widget is not in the panel, it will be set to `null`.
	         */
	        set: function (value) {
	            this.tabBar.currentTitle = value ? value.title : null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "tabsMovable", {
	        /**
	         * Get the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        get: function () {
	            return this.tabBar.tabsMovable;
	        },
	        /**
	         * Set the whether the tabs are movable by the user.
	         *
	         * #### Notes
	         * Tabs can always be moved programmatically.
	         */
	        set: function (value) {
	            this.tabBar.tabsMovable = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TabPanel.prototype, "widgets", {
	        /**
	         * A read-only array of the widgets in the panel.
	         */
	        get: function () {
	            return this.tabContents.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a widget to the end of the tab panel.
	     *
	     * @param widget - The widget to add to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.addWidget = function (widget) {
	        this.insertWidget(this.widgets.length, widget);
	    };
	    /**
	     * Insert a widget into the tab panel at a specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the tab panel.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     *
	     * The widget's `title` is used to populate the tab.
	     */
	    TabPanel.prototype.insertWidget = function (index, widget) {
	        if (widget !== this.currentWidget) {
	            widget.hide();
	        }
	        this.tabContents.insertWidget(index, widget);
	        this.tabBar.insertTab(index, widget.title);
	    };
	    /**
	     * Handle the `currentChanged` signal from the tab bar.
	     */
	    TabPanel.prototype._onCurrentChanged = function (sender, args) {
	        // Extract the previous and current title from the args.
	        var previousIndex = args.previousIndex, previousTitle = args.previousTitle, currentIndex = args.currentIndex, currentTitle = args.currentTitle;
	        // Extract the widgets from the titles.
	        var previousWidget = previousTitle ? previousTitle.owner : null;
	        var currentWidget = currentTitle ? currentTitle.owner : null;
	        // Hide the previous widget.
	        if (previousWidget) {
	            previousWidget.hide();
	        }
	        // Show the current widget.
	        if (currentWidget) {
	            currentWidget.show();
	        }
	        // Emit the `currentChanged` signal for the tab panel.
	        this._currentChanged.emit({
	            previousIndex: previousIndex, previousWidget: previousWidget, currentIndex: currentIndex, currentWidget: currentWidget
	        });
	        // Flush the message loop on IE and Edge to prevent flicker.
	        if (domutils_1.Platform.IS_EDGE || domutils_1.Platform.IS_IE) {
	            messaging_1.MessageLoop.flush();
	        }
	    };
	    /**
	     * Handle the `tabActivateRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabActivateRequested = function (sender, args) {
	        args.title.owner.activate();
	    };
	    /**
	     * Handle the `tabCloseRequested` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabCloseRequested = function (sender, args) {
	        args.title.owner.close();
	    };
	    /**
	     * Handle the `tabMoved` signal from the tab bar.
	     */
	    TabPanel.prototype._onTabMoved = function (sender, args) {
	        this.tabContents.insertWidget(args.toIndex, args.title.owner);
	    };
	    /**
	     * Handle the `widgetRemoved` signal from the stacked panel.
	     */
	    TabPanel.prototype._onWidgetRemoved = function (sender, widget) {
	        this.tabBar.removeTab(widget.title);
	    };
	    return TabPanel;
	}(widgets_1.Widget));
	exports.TabPanel = TabPanel;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/tabpanel.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/accordion.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/accordion.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@1.2.1/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.1.0/lib/index.js');
	var currentselection_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/currentselection.js');
	/**
	 * The class name added to Collapse instances.
	 */
	var COLLAPSE_CLASS = 'p-Collapse';
	/**
	 * The class name added to a Collapse's header.
	 */
	var COLLAPSE_HEADER_CLASS = 'p-Collapse-header';
	/**
	 * The class name added to a Collapse's contents.
	 */
	var COLLAPSE_CONTENTS_CLASS = 'p-Collapse-contents';
	/**
	 * The class name added to a Collapse when it is opened
	 */
	var COLLAPSE_CLASS_OPEN = 'p-Collapse-open';
	/**
	 * A panel that supports a collapsible header, made from the widget's title.
	 * Clicking on the title expands or contracts the widget.
	 */
	var Collapse = (function (_super) {
	    __extends(Collapse, _super);
	    function Collapse(options) {
	        var _this = _super.call(this, options) || this;
	        _this._collapseChanged = new signaling_1.Signal(_this);
	        _this.addClass(COLLAPSE_CLASS);
	        _this._header = new widgets_1.Widget();
	        _this._header.addClass(COLLAPSE_HEADER_CLASS);
	        _this._header.node.addEventListener('click', _this);
	        _this._content = new widgets_1.Panel();
	        _this._content.addClass(COLLAPSE_CONTENTS_CLASS);
	        var layout = new widgets_1.PanelLayout();
	        _this.layout = layout;
	        layout.addWidget(_this._header);
	        layout.addWidget(_this._content);
	        if (options.widget) {
	            _this.widget = options.widget;
	        }
	        _this.collapsed = false;
	        return _this;
	    }
	    Collapse.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        this._header = null;
	        this._widget = null;
	        this._content = null;
	    };
	    Object.defineProperty(Collapse.prototype, "widget", {
	        get: function () {
	            return this._widget;
	        },
	        set: function (widget) {
	            var oldWidget = this._widget;
	            if (oldWidget) {
	                oldWidget.disposed.disconnect(this._onChildDisposed, this);
	                oldWidget.title.changed.disconnect(this._onTitleChanged, this);
	                oldWidget.parent = null;
	            }
	            this._widget = widget;
	            widget.disposed.connect(this._onChildDisposed, this);
	            widget.title.changed.connect(this._onTitleChanged, this);
	            this._onTitleChanged(widget.title);
	            this._content.addWidget(widget);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Collapse.prototype, "collapsed", {
	        get: function () {
	            return this._collapsed;
	        },
	        set: function (value) {
	            // TODO: should we have this check here?
	            if (value === this._collapsed) {
	                return;
	            }
	            if (value) {
	                this._collapse();
	            }
	            else {
	                this._uncollapse();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Collapse.prototype.toggle = function () {
	        this.collapsed = !this.collapsed;
	    };
	    Object.defineProperty(Collapse.prototype, "collapseChanged", {
	        get: function () {
	            return this._collapseChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Collapse.prototype._collapse = function () {
	        this._collapsed = true;
	        if (this._content) {
	            this._content.hide();
	        }
	        this.removeClass(COLLAPSE_CLASS_OPEN);
	        this._collapseChanged.emit(void 0);
	    };
	    Collapse.prototype._uncollapse = function () {
	        this._collapsed = false;
	        if (this._content) {
	            this._content.show();
	        }
	        this.addClass(COLLAPSE_CLASS_OPEN);
	        this._collapseChanged.emit(void 0);
	    };
	    /**
	     * Handle the DOM events for the Collapse widget.
	     *
	     * @param event - The DOM event sent to the panel.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    Collapse.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(event);
	                break;
	            default:
	                break;
	        }
	    };
	    Collapse.prototype._evtClick = function (event) {
	        this.toggle();
	    };
	    /**
	     * Handle the `changed` signal of a title object.
	     */
	    Collapse.prototype._onTitleChanged = function (sender) {
	        this._header.node.textContent = this._widget.title.label;
	    };
	    Collapse.prototype._onChildDisposed = function (sender) {
	        this.dispose();
	    };
	    return Collapse;
	}(widgets_1.Widget));
	exports.Collapse = Collapse;
	/**
	 * The class name added to Accordion instances.
	 */
	var ACCORDION_CLASS = 'p-Accordion';
	/**
	 * The class name added to an Accordion child.
	 */
	var ACCORDION_CHILD_CLASS = 'p-Accordion-child';
	var ACCORDION_CHILD_ACTIVE_CLASS = 'p-Accordion-child-active';
	/**
	 * A panel that supports a collapsible header, made from the widget's title.
	 * Clicking on the title expands or contracts the widget.
	 */
	var Accordion = (function (_super) {
	    __extends(Accordion, _super);
	    function Accordion(options) {
	        var _this = _super.call(this, options) || this;
	        _this._selection = new currentselection_1.Selection(_this.widgets);
	        _this._selection.selectionChanged.connect(_this._onSelectionChanged, _this);
	        _this.addClass(ACCORDION_CLASS);
	        return _this;
	    }
	    Object.defineProperty(Accordion.prototype, "collapseWidgets", {
	        /**
	         * A read-only sequence of the widgets in the panel.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        /*  get widgets(): ISequence<Widget> {
	            return new ArraySequence(toArray(map((this.layout as PanelLayout).widgets, (w: Collapse) => w.widget)));
	          }
	        */
	        get: function () {
	            return this.layout.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Accordion.prototype, "selection", {
	        get: function () {
	            return this._selection;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Accordion.prototype.indexOf = function (widget) {
	        return algorithm_1.ArrayExt.findFirstIndex(this.collapseWidgets, function (w) { return w.widget === widget; });
	    };
	    /**
	     * Add a widget to the end of the accordion.
	     *
	     * @param widget - The widget to add to the accordion.
	     *
	     * @returns The Collapse widget wrapping the added widget.
	     * #### Notes
	     * The widget will be wrapped in a CollapsedWidget.
	     */
	    Accordion.prototype.addWidget = function (widget) {
	        var collapse = this._wrapWidget(widget);
	        collapse.collapsed = true;
	        _super.prototype.addWidget.call(this, collapse);
	        this._selection.adjustSelectionForInsert(this.widgets.length - 1, collapse);
	        return collapse;
	    };
	    /**
	     * Insert a widget at the specified index.
	     *
	     * @param index - The index at which to insert the widget.
	     *
	     * @param widget - The widget to insert into to the accordion.
	     *
	     * #### Notes
	     * If the widget is already contained in the panel, it will be moved.
	     */
	    Accordion.prototype.insertWidget = function (index, widget) {
	        var collapse = this._wrapWidget(widget);
	        collapse.collapsed = true;
	        _super.prototype.insertWidget.call(this, index, collapse);
	        this._selection.adjustSelectionForInsert(index, collapse);
	    };
	    Accordion.prototype.removeWidget = function (widget) {
	        var index = this.indexOf(widget);
	        if (index >= 0) {
	            var collapse = this.collapseWidgets[index];
	            widget.parent = null;
	            collapse.dispose();
	            this._selection.adjustSelectionForRemove(index, null);
	        }
	    };
	    Accordion.prototype._wrapWidget = function (widget) {
	        var collapse = new Collapse({ widget: widget });
	        collapse.addClass(ACCORDION_CHILD_CLASS);
	        collapse.collapseChanged.connect(this._onCollapseChange, this);
	        return collapse;
	    };
	    Accordion.prototype._onCollapseChange = function (sender) {
	        if (!sender.collapsed) {
	            this._selection.value = sender;
	        }
	        else if (this._selection.value === sender && sender.collapsed) {
	            this._selection.value = null;
	        }
	    };
	    Accordion.prototype._onSelectionChanged = function (sender, change) {
	        // Collapse previous widget, open current widget
	        var pv = change.previousValue;
	        var cv = change.currentValue;
	        if (pv) {
	            pv.collapsed = true;
	            pv.removeClass(ACCORDION_CHILD_ACTIVE_CLASS);
	        }
	        if (cv) {
	            cv.collapsed = false;
	            cv.addClass(ACCORDION_CHILD_ACTIVE_CLASS);
	        }
	    };
	    return Accordion;
	}(widgets_1.Panel));
	exports.Accordion = Accordion;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/accordion.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/currentselection.js **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/currentselection.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A variety of convenience methods for maintaining a current selection
	 */
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@1.2.1/lib/index.js');
	var Selection = (function () {
	    function Selection(sequence, options) {
	        if (options === void 0) { options = {}; }
	        this._array = null;
	        this._value = null;
	        this._previousValue = null;
	        this._selectionChanged = new signaling_1.Signal(this);
	        this._array = sequence;
	        this._insertBehavior = options.insertBehavior || 'select-item-if-needed';
	        this._removeBehavior = options.removeBehavior || 'select-item-after';
	    }
	    Object.defineProperty(Selection.prototype, "selectionChanged", {
	        /**
	         * A signal emitted when the current item is changed.
	         *
	         * #### Notes
	         * This signal is emitted when the currently selected item is changed either
	         * through user or programmatic interaction.
	         *
	         * Notably, this signal is not emitted when the index of the current item
	         * changes due to other items being inserted, removed, or moved, but the
	         * current item remains the same. It is only emitted when the actual current
	         * item is changed.
	         */
	        get: function () {
	            return this._selectionChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Adjust for setting an item.
	     *
	     * This should be called *after* the set.
	     *
	     * @param index - The index set.
	     * @param oldValue - The old value at the index.
	     */
	    Selection.prototype.adjustSelectionForSet = function (index) {
	        // We just need to send a signal if the currentValue changed.
	        // Get the current index and value.
	        var pi = this.index;
	        var pv = this.value;
	        // Exit early if this doesn't affect the selection
	        if (index !== pi) {
	            return;
	        }
	        this._updateSelectedValue();
	        var cv = this.value;
	        // The previous item is now null, since it is no longer in the array.
	        this._previousValue = null;
	        // Send signal if there was a change
	        if (pv !== cv) {
	            // Emit the current changed signal.
	            this._selectionChanged.emit({
	                previousIndex: pi, previousValue: pv,
	                currentIndex: pi, currentValue: cv
	            });
	        }
	    };
	    Object.defineProperty(Selection.prototype, "value", {
	        /**
	         * Get the currently selected item.
	         *
	         * #### Notes
	         * This will be `null` if no item is selected.
	         */
	        get: function () {
	            return this._value;
	        },
	        /**
	         * Set the currently selected item.
	         *
	         * #### Notes
	         * If the item does not exist in the vector, the currentValue will be set to
	         * `null`. This selects the first entry equal to the desired item.
	         */
	        set: function (value) {
	            if (value === null) {
	                this.index = -1;
	            }
	            else {
	                this.index = algorithm_1.ArrayExt.firstIndexOf(this._array, value);
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Selection.prototype, "index", {
	        /**
	         * Get the index of the currently selected item.
	         *
	         * #### Notes
	         * This will be `-1` if no item is selected.
	         */
	        get: function () {
	            return this._index;
	        },
	        /**
	         * Set the index of the currently selected tab.
	         *
	         * @param index - The index to select.
	         *
	         * #### Notes
	         * If the value is out of range, the index will be set to `-1`, which
	         * indicates no item is selected.
	         */
	        set: function (index) {
	            // Coerce the value to an index.
	            var i = Math.floor(index);
	            if (i < 0 || i >= this._array.length) {
	                i = -1;
	            }
	            // Bail early if the index will not change.
	            if (this._index === i) {
	                return;
	            }
	            // Look up the previous index and item.
	            var pi = this._index;
	            var pv = this._value;
	            // Update the state
	            this._index = i;
	            this._updateSelectedValue();
	            this._previousValue = pv;
	            // Emit the current changed signal.
	            this._selectionChanged.emit({
	                previousIndex: pi, previousValue: pv,
	                currentIndex: i, currentValue: this._value
	            });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Selection.prototype, "insertBehavior", {
	        /**
	         * Get the selection behavior when inserting a tab.
	         */
	        get: function () {
	            return this._insertBehavior;
	        },
	        /**
	         * Set the selection behavior when inserting a tab.
	         */
	        set: function (value) {
	            this._insertBehavior = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Selection.prototype, "removeBehavior", {
	        /**
	         * Get the selection behavior when removing a tab.
	         */
	        get: function () {
	            return this._removeBehavior;
	        },
	        /**
	         * Set the selection behavior when removing a tab.
	         */
	        set: function (value) {
	            this._removeBehavior = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Adjust the current index for a tab insert operation.
	     *
	     * @param i - The new index of the inserted item.
	     * @param j - The inserted item.
	     *
	     * #### Notes
	     * This method accounts for the tab bar's insertion behavior when adjusting
	     * the current index and emitting the changed signal. This should be called
	     * after the insertion.
	     */
	    Selection.prototype.adjustSelectionForInsert = function (i, item) {
	        // Lookup commonly used variables.
	        var cv = this._value;
	        var ci = this._index;
	        var bh = this._insertBehavior;
	        // Handle the behavior where the new item is always selected,
	        // or the behavior where the new item is selected if needed.
	        if (bh === 'select-item' || (bh === 'select-item-if-needed' && ci === -1)) {
	            this._index = i;
	            this._value = item;
	            this._previousValue = cv;
	            this._selectionChanged.emit({
	                previousIndex: ci, previousValue: cv,
	                currentIndex: i, currentValue: item
	            });
	            return;
	        }
	        // Otherwise, silently adjust the current index if needed.
	        if (ci >= i) {
	            this._index++;
	        }
	    };
	    /**
	     * Adjust the current index for move operation.
	     *
	     * @param i - The previous index of the item.
	     * @param j - The new index of the item.
	     *
	     * #### Notes
	     * This method will not cause the actual current item to change. It silently
	     * adjusts the current index to account for the given move.
	     */
	    Selection.prototype.adjustSelectionForMove = function (i, j) {
	        if (this._index === i) {
	            this._index = j;
	        }
	        else if (this._index < i && this._index >= j) {
	            this._index++;
	        }
	        else if (this._index > i && this._index <= j) {
	            this._index--;
	        }
	    };
	    /**
	     * Clear the selection and history.
	     */
	    Selection.prototype.clearSelection = function () {
	        // Get the current index and item.
	        var pi = this._index;
	        var pv = this._value;
	        // Reset the current index and previous item.
	        this._index = -1;
	        this._value = null;
	        this._previousValue = null;
	        // If no item was selected, there's nothing else to do.
	        if (pi === -1) {
	            return;
	        }
	        // Emit the current changed signal.
	        this._selectionChanged.emit({
	            previousIndex: pi, previousValue: pv,
	            currentIndex: -1, currentValue: null
	        });
	    };
	    /**
	     * Adjust the current index for an item remove operation.
	     *
	     * @param i - The former index of the removed item.
	     * @param item - The removed item.
	     *
	     * #### Notes
	     * This method accounts for the remove behavior when adjusting the current
	     * index and emitting the changed signal. It should be called after the item
	     * is removed.
	     */
	    Selection.prototype.adjustSelectionForRemove = function (i, item) {
	        // Lookup commonly used variables.
	        var ci = this._index;
	        var bh = this._removeBehavior;
	        // Silently adjust the index if the current item is not removed.
	        if (ci !== i) {
	            if (ci > i) {
	                this._index--;
	            }
	            return;
	        }
	        // No item gets selected if the vector is empty.
	        if (this._array.length === 0) {
	            // Reset the current index and previous item.
	            this._index = -1;
	            this._value = null;
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: -1, currentValue: null
	            });
	            return;
	        }
	        // Handle behavior where the next sibling item is selected.
	        if (bh === 'select-item-after') {
	            this._index = Math.min(i, this._array.length - 1);
	            this._updateSelectedValue();
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: this._index, currentValue: this._value
	            });
	            return;
	        }
	        // Handle behavior where the previous sibling item is selected.
	        if (bh === 'select-item-before') {
	            this._index = Math.max(0, i - 1);
	            this._updateSelectedValue();
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: this._index, currentValue: this._value
	            });
	            return;
	        }
	        // Handle behavior where the previous history item is selected.
	        if (bh === 'select-previous-item') {
	            if (this._previousValue) {
	                this.value = this._previousValue;
	            }
	            else {
	                this._index = Math.min(i, this._array.length - 1);
	                this._updateSelectedValue();
	            }
	            this._previousValue = null;
	            this._selectionChanged.emit({
	                previousIndex: i, previousValue: item,
	                currentIndex: this._index, currentValue: this.value
	            });
	            return;
	        }
	        // Otherwise, no item gets selected.
	        this._index = -1;
	        this._value = null;
	        this._previousValue = null;
	        this._selectionChanged.emit({
	            previousIndex: i, previousValue: item,
	            currentIndex: -1, currentValue: null
	        });
	    };
	    /**
	     * Set the current value based on the current index.
	     */
	    Selection.prototype._updateSelectedValue = function () {
	        var i = this._index;
	        this._value = i !== -1 ? this._array[i] : null;
	    };
	    return Selection;
	}());
	exports.Selection = Selection;
	
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/lib/phosphor/currentselection.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/package.json **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/package.json', function (module, exports, __jupyter_require__) {
	module.exports = {
		"_args": [
			[
				{
					"raw": "jupyter-js-widgets@3.0.0-alpha.0",
					"scope": null,
					"escapedName": "jupyter-js-widgets",
					"name": "jupyter-js-widgets",
					"rawSpec": "3.0.0-alpha.0",
					"spec": "3.0.0-alpha.0",
					"type": "version"
				},
				"/Users/haichit/programs/3d/nglview/js/node_modules/@jupyterlab/nbwidgets"
			]
		],
		"_from": "jupyter-js-widgets@3.0.0-alpha.0",
		"_id": "jupyter-js-widgets@3.0.0-alpha.0",
		"_inCache": true,
		"_location": "/@jupyterlab/nbwidgets/jupyter-js-widgets",
		"_nodeVersion": "6.9.0",
		"_npmOperationalInternal": {
			"host": "packages-18-east.internal.npmjs.com",
			"tmp": "tmp/jupyter-js-widgets-3.0.0-alpha.0.tgz_1493303793704_0.6478447637055069"
		},
		"_npmUser": {
			"name": "jasongrout",
			"email": "jason@jasongrout.org"
		},
		"_npmVersion": "3.10.8",
		"_phantomChildren": {},
		"_requested": {
			"raw": "jupyter-js-widgets@3.0.0-alpha.0",
			"scope": null,
			"escapedName": "jupyter-js-widgets",
			"name": "jupyter-js-widgets",
			"rawSpec": "3.0.0-alpha.0",
			"spec": "3.0.0-alpha.0",
			"type": "version"
		},
		"_requiredBy": [
			"/@jupyterlab/nbwidgets"
		],
		"_resolved": "https://registry.npmjs.org/jupyter-js-widgets/-/jupyter-js-widgets-3.0.0-alpha.0.tgz",
		"_shasum": "8baa45ee23a37f88ba2efcf949307dad721211dd",
		"_shrinkwrap": null,
		"_spec": "jupyter-js-widgets@3.0.0-alpha.0",
		"_where": "/Users/haichit/programs/3d/nglview/js/node_modules/@jupyterlab/nbwidgets",
		"author": {
			"name": "Project Jupyter"
		},
		"bugs": {
			"url": "https://github.com/jupyter-widgets/ipywidgets/issues"
		},
		"dependencies": {
			"@jupyterlab/services": "^0.41.0",
			"@phosphor/algorithm": "^1.0.0",
			"@phosphor/domutils": "^1.0.0",
			"@phosphor/messaging": "^1.1.0",
			"@phosphor/widgets": "^1.1.0",
			"@types/backbone": "^1.3.33",
			"@types/semver": "^5.3.30",
			"ajv": "^4.9.0",
			"backbone": "1.2.0",
			"base64-js": "1.2.0",
			"d3-format": "^0.5.1",
			"font-awesome": "^4.5.0",
			"jquery": "^3.1.1",
			"jquery-ui": "^1.12.1",
			"jupyter-widgets-schema": "^0.3.0-beta.2",
			"lolex": "^1.4.0",
			"scriptjs": "^2.5.8",
			"semver": "^5.1.0",
			"underscore": "^1.8.3"
		},
		"description": "Jupyter interactive widgets",
		"devDependencies": {
			"@types/expect.js": "^0.3.29",
			"@types/mathjax": "0.0.31",
			"@types/mocha": "2.2.32",
			"@types/requirejs": "^2.1.28",
			"@types/sinon": "^1.16.31",
			"cpx": "^1.5.0",
			"css-loader": "^0.23.1",
			"es6-promise": "^3.1.2",
			"expect.js": "^0.3.1",
			"file-loader": "^0.8.5",
			"istanbul-instrumenter-loader": "^0.2.0",
			"json-loader": "^0.5.4",
			"karma": "^0.13.15",
			"karma-chrome-launcher": "^0.2.2",
			"karma-coverage": "^1.0.0",
			"karma-firefox-launcher": "^0.1.7",
			"karma-ie-launcher": "^1.0.0",
			"karma-mocha": "^0.2.1",
			"karma-mocha-reporter": "^1.1.3",
			"karma-webpack": "^1.7.0",
			"mocha": "^2.3.4",
			"npm-run-all": "^1.5.1",
			"postcss-cli": "^2.6.0",
			"postcss-cssnext": "^2.8.0",
			"postcss-import": "^8.1.2",
			"postcss-loader": "^1.3.2",
			"rimraf": "^2.4.1",
			"sinon": "^1.17.2",
			"spawn-sync": "^1.0.14",
			"style-loader": "^0.13.1",
			"typedoc": "^0.5.0",
			"typescript": "~2.2.1",
			"url-loader": "^0.5.7",
			"webpack": "^1.12.11"
		},
		"directories": {},
		"dist": {
			"shasum": "8baa45ee23a37f88ba2efcf949307dad721211dd",
			"tarball": "https://registry.npmjs.org/jupyter-js-widgets/-/jupyter-js-widgets-3.0.0-alpha.0.tgz"
		},
		"files": [
			"lib/**/*.d.ts",
			"lib/**/*.js",
			"css/*.css",
			"dist/"
		],
		"homepage": "https://github.com/jupyter-widgets/ipywidgets#readme",
		"license": "BSD-3-Clause",
		"main": "lib/index.js",
		"maintainers": [
			{
				"name": "sylvaincorlay",
				"email": "sylvain.corlay@gmail.com"
			}
		],
		"name": "jupyter-js-widgets",
		"optionalDependencies": {},
		"readme": "Jupyter JS Widgets\n==================\n\nInteractive widgets for the Jupyter notebook.\n\nThis packages contains the implementation of the core Jupyter interactive\nwidgets.\n\nThe reference Python backend, `ipywidgets` is available\n[here](https://github.com/jupyter-widgets/ipywidgets), with more examples.\n\nPackage Install\n---------------\n\n**Prerequisites**\n- [node](http://nodejs.org/)\n\nRun the following command **at the root of this repository**.\n\n```bash\nnpm install --save jupyter-js-widgets\n```\n",
		"readmeFilename": "README.md",
		"repository": {
			"type": "git",
			"url": "git+https://github.com/jupyter-widgets/ipywidgets.git"
		},
		"scripts": {
			"build": "npm run build:src && npm run build:src-embed && npm run build:css && webpack",
			"build:css": "postcss --use postcss-import --use postcss-cssnext -o css/widgets.built.css css/widgets.css",
			"build:src": "tsc --project src",
			"build:src-embed": "tsc --project src-embed",
			"build:test": "tsc --project test/src && webpack --config test/webpack.conf.js",
			"clean": "npm run clean:src && npm run clean:embed",
			"clean:embed": "rimraf lib-embed",
			"clean:src": "rimraf lib",
			"docs": "npm run docs:src && npm run docs:embed",
			"docs:embed": "typedoc --mode file --module commonjs --excludeNotExported --target es5 --moduleResolution node --out docs-embed/ src-embed",
			"docs:src": "typedoc --mode file --module commonjs --excludeNotExported --target es5 --moduleResolution node --out docs/ src",
			"postinstall": "npm dedupe",
			"prepublish": "npm run build",
			"test": "npm run test:unit && npm run test:examples",
			"test:coverage": "npm run build:test && webpack --config test/webpack-cov.conf.js && karma start test/karma-cov.conf.js",
			"test:example:web2": "cd examples/web2 && npm install && npm run test:default",
			"test:example:web3": "cd examples/web3 && npm install && npm run test:default",
			"test:example:web4": "cd examples/web4 && npm install && npm run test:default",
			"test:example:web5": "cd examples/web5 && npm install && npm run test:default",
			"test:examples": "npm run test:examples:chrome && npm run test:examples:firefox",
			"test:examples:chrome": "npm-run-all \"test:example:*\"",
			"test:examples:firefox": "npm-run-all \"test:example:* -- -- --browsers Firefox\"",
			"test:unit": "npm run test:unit:firefox && npm run test:unit:chrome",
			"test:unit:chrome": "npm run test:unit:default -- --browsers=Chrome",
			"test:unit:default": "npm run build:test && karma start test/karma.conf.js --log-level debug",
			"test:unit:firefox": "npm run test:unit:default -- --browsers=Firefox",
			"test:unit:ie": "npm run test:unit:default -- --browsers=IE"
		},
		"typings": "lib/index.d.ts",
		"version": "3.0.0-alpha.0"
	};
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/package.json **/


/** START DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/semvercache.js **/
jupyter.define('@jupyterlab/nbwidgets@0.6.17/lib/semvercache.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	var semver_1 = __jupyter_require__('semver@5.3.0/semver.js');
	/**
	 * A cache using semver ranges to retrieve values.
	 */
	var SemVerCache = (function () {
	    function SemVerCache() {
	        this._cache = Object.create(null);
	    }
	    SemVerCache.prototype.set = function (key, version, object) {
	        if (!(key in this._cache)) {
	            this._cache[key] = Object.create(null);
	        }
	        if (!(version in this._cache[key])) {
	            this._cache[key][version] = object;
	        }
	    };
	    SemVerCache.prototype.get = function (key, semver) {
	        if (key in this._cache) {
	            var versions = this._cache[key];
	            var best = semver_1.maxSatisfying(Object.keys(versions), semver);
	            return versions[best];
	        }
	    };
	    return SemVerCache;
	}());
	exports.SemVerCache = SemVerCache;
	
})
/** END DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/semvercache.js **/


/** START DEFINE BLOCK for semver@5.3.0/semver.js **/
jupyter.define('semver@5.3.0/semver.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(process) {exports = module.exports = SemVer;
	
	// The debug function is excluded entirely from the minified version.
	/* nomin */ var debug;
	/* nomin */ if (typeof process === 'object' &&
	    /* nomin */ process.env &&
	    /* nomin */ process.env.NODE_DEBUG &&
	    /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG))
	  /* nomin */ debug = function() {
	    /* nomin */ var args = Array.prototype.slice.call(arguments, 0);
	    /* nomin */ args.unshift('SEMVER');
	    /* nomin */ console.log.apply(console, args);
	    /* nomin */ };
	/* nomin */ else
	  /* nomin */ debug = function() {};
	
	// Note: this is the semver.org version of the spec that it implements
	// Not necessarily the package version of this code.
	exports.SEMVER_SPEC_VERSION = '2.0.0';
	
	var MAX_LENGTH = 256;
	var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
	
	// The actual regexps go on exports.re
	var re = exports.re = [];
	var src = exports.src = [];
	var R = 0;
	
	// The following Regular Expressions can be used for tokenizing,
	// validating, and parsing SemVer version strings.
	
	// ## Numeric Identifier
	// A single `0`, or a non-zero digit followed by zero or more digits.
	
	var NUMERICIDENTIFIER = R++;
	src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
	var NUMERICIDENTIFIERLOOSE = R++;
	src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
	
	
	// ## Non-numeric Identifier
	// Zero or more digits, followed by a letter or hyphen, and then zero or
	// more letters, digits, or hyphens.
	
	var NONNUMERICIDENTIFIER = R++;
	src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
	
	
	// ## Main Version
	// Three dot-separated numeric identifiers.
	
	var MAINVERSION = R++;
	src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
	                   '(' + src[NUMERICIDENTIFIER] + ')\\.' +
	                   '(' + src[NUMERICIDENTIFIER] + ')';
	
	var MAINVERSIONLOOSE = R++;
	src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
	                        '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
	                        '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
	
	// ## Pre-release Version Identifier
	// A numeric identifier, or a non-numeric identifier.
	
	var PRERELEASEIDENTIFIER = R++;
	src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
	                            '|' + src[NONNUMERICIDENTIFIER] + ')';
	
	var PRERELEASEIDENTIFIERLOOSE = R++;
	src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
	                                 '|' + src[NONNUMERICIDENTIFIER] + ')';
	
	
	// ## Pre-release Version
	// Hyphen, followed by one or more dot-separated pre-release version
	// identifiers.
	
	var PRERELEASE = R++;
	src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
	                  '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
	
	var PRERELEASELOOSE = R++;
	src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
	                       '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
	
	// ## Build Metadata Identifier
	// Any combination of digits, letters, or hyphens.
	
	var BUILDIDENTIFIER = R++;
	src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
	
	// ## Build Metadata
	// Plus sign, followed by one or more period-separated build metadata
	// identifiers.
	
	var BUILD = R++;
	src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
	             '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
	
	
	// ## Full Version String
	// A main version, followed optionally by a pre-release version and
	// build metadata.
	
	// Note that the only major, minor, patch, and pre-release sections of
	// the version string are capturing groups.  The build metadata is not a
	// capturing group, because it should not ever be used in version
	// comparison.
	
	var FULL = R++;
	var FULLPLAIN = 'v?' + src[MAINVERSION] +
	                src[PRERELEASE] + '?' +
	                src[BUILD] + '?';
	
	src[FULL] = '^' + FULLPLAIN + '$';
	
	// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
	// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
	// common in the npm registry.
	var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
	                 src[PRERELEASELOOSE] + '?' +
	                 src[BUILD] + '?';
	
	var LOOSE = R++;
	src[LOOSE] = '^' + LOOSEPLAIN + '$';
	
	var GTLT = R++;
	src[GTLT] = '((?:<|>)?=?)';
	
	// Something like "2.*" or "1.2.x".
	// Note that "x.x" is a valid xRange identifer, meaning "any version"
	// Only the first item is strictly required.
	var XRANGEIDENTIFIERLOOSE = R++;
	src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
	var XRANGEIDENTIFIER = R++;
	src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
	
	var XRANGEPLAIN = R++;
	src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
	                   '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
	                   '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
	                   '(?:' + src[PRERELEASE] + ')?' +
	                   src[BUILD] + '?' +
	                   ')?)?';
	
	var XRANGEPLAINLOOSE = R++;
	src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
	                        '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
	                        '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
	                        '(?:' + src[PRERELEASELOOSE] + ')?' +
	                        src[BUILD] + '?' +
	                        ')?)?';
	
	var XRANGE = R++;
	src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
	var XRANGELOOSE = R++;
	src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
	
	// Tilde ranges.
	// Meaning is "reasonably at or greater than"
	var LONETILDE = R++;
	src[LONETILDE] = '(?:~>?)';
	
	var TILDETRIM = R++;
	src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
	re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
	var tildeTrimReplace = '$1~';
	
	var TILDE = R++;
	src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
	var TILDELOOSE = R++;
	src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
	
	// Caret ranges.
	// Meaning is "at least and backwards compatible with"
	var LONECARET = R++;
	src[LONECARET] = '(?:\\^)';
	
	var CARETTRIM = R++;
	src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
	re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
	var caretTrimReplace = '$1^';
	
	var CARET = R++;
	src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
	var CARETLOOSE = R++;
	src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
	
	// A simple gt/lt/eq thing, or just "" to indicate "any version"
	var COMPARATORLOOSE = R++;
	src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
	var COMPARATOR = R++;
	src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
	
	
	// An expression to strip any whitespace between the gtlt and the thing
	// it modifies, so that `> 1.2.3` ==> `>1.2.3`
	var COMPARATORTRIM = R++;
	src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
	                      '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
	
	// this one has to use the /g flag
	re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
	var comparatorTrimReplace = '$1$2$3';
	
	
	// Something like `1.2.3 - 1.2.4`
	// Note that these all use the loose form, because they'll be
	// checked against either the strict or loose comparator form
	// later.
	var HYPHENRANGE = R++;
	src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
	                   '\\s+-\\s+' +
	                   '(' + src[XRANGEPLAIN] + ')' +
	                   '\\s*$';
	
	var HYPHENRANGELOOSE = R++;
	src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
	                        '\\s+-\\s+' +
	                        '(' + src[XRANGEPLAINLOOSE] + ')' +
	                        '\\s*$';
	
	// Star ranges basically just allow anything at all.
	var STAR = R++;
	src[STAR] = '(<|>)?=?\\s*\\*';
	
	// Compile to actual regexp objects.
	// All are flag-free, unless they were created above with a flag.
	for (var i = 0; i < R; i++) {
	  debug(i, src[i]);
	  if (!re[i])
	    re[i] = new RegExp(src[i]);
	}
	
	exports.parse = parse;
	function parse(version, loose) {
	  if (version instanceof SemVer)
	    return version;
	
	  if (typeof version !== 'string')
	    return null;
	
	  if (version.length > MAX_LENGTH)
	    return null;
	
	  var r = loose ? re[LOOSE] : re[FULL];
	  if (!r.test(version))
	    return null;
	
	  try {
	    return new SemVer(version, loose);
	  } catch (er) {
	    return null;
	  }
	}
	
	exports.valid = valid;
	function valid(version, loose) {
	  var v = parse(version, loose);
	  return v ? v.version : null;
	}
	
	
	exports.clean = clean;
	function clean(version, loose) {
	  var s = parse(version.trim().replace(/^[=v]+/, ''), loose);
	  return s ? s.version : null;
	}
	
	exports.SemVer = SemVer;
	
	function SemVer(version, loose) {
	  if (version instanceof SemVer) {
	    if (version.loose === loose)
	      return version;
	    else
	      version = version.version;
	  } else if (typeof version !== 'string') {
	    throw new TypeError('Invalid Version: ' + version);
	  }
	
	  if (version.length > MAX_LENGTH)
	    throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters')
	
	  if (!(this instanceof SemVer))
	    return new SemVer(version, loose);
	
	  debug('SemVer', version, loose);
	  this.loose = loose;
	  var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
	
	  if (!m)
	    throw new TypeError('Invalid Version: ' + version);
	
	  this.raw = version;
	
	  // these are actually numbers
	  this.major = +m[1];
	  this.minor = +m[2];
	  this.patch = +m[3];
	
	  if (this.major > MAX_SAFE_INTEGER || this.major < 0)
	    throw new TypeError('Invalid major version')
	
	  if (this.minor > MAX_SAFE_INTEGER || this.minor < 0)
	    throw new TypeError('Invalid minor version')
	
	  if (this.patch > MAX_SAFE_INTEGER || this.patch < 0)
	    throw new TypeError('Invalid patch version')
	
	  // numberify any prerelease numeric ids
	  if (!m[4])
	    this.prerelease = [];
	  else
	    this.prerelease = m[4].split('.').map(function(id) {
	      if (/^[0-9]+$/.test(id)) {
	        var num = +id;
	        if (num >= 0 && num < MAX_SAFE_INTEGER)
	          return num;
	      }
	      return id;
	    });
	
	  this.build = m[5] ? m[5].split('.') : [];
	  this.format();
	}
	
	SemVer.prototype.format = function() {
	  this.version = this.major + '.' + this.minor + '.' + this.patch;
	  if (this.prerelease.length)
	    this.version += '-' + this.prerelease.join('.');
	  return this.version;
	};
	
	SemVer.prototype.toString = function() {
	  return this.version;
	};
	
	SemVer.prototype.compare = function(other) {
	  debug('SemVer.compare', this.version, this.loose, other);
	  if (!(other instanceof SemVer))
	    other = new SemVer(other, this.loose);
	
	  return this.compareMain(other) || this.comparePre(other);
	};
	
	SemVer.prototype.compareMain = function(other) {
	  if (!(other instanceof SemVer))
	    other = new SemVer(other, this.loose);
	
	  return compareIdentifiers(this.major, other.major) ||
	         compareIdentifiers(this.minor, other.minor) ||
	         compareIdentifiers(this.patch, other.patch);
	};
	
	SemVer.prototype.comparePre = function(other) {
	  if (!(other instanceof SemVer))
	    other = new SemVer(other, this.loose);
	
	  // NOT having a prerelease is > having one
	  if (this.prerelease.length && !other.prerelease.length)
	    return -1;
	  else if (!this.prerelease.length && other.prerelease.length)
	    return 1;
	  else if (!this.prerelease.length && !other.prerelease.length)
	    return 0;
	
	  var i = 0;
	  do {
	    var a = this.prerelease[i];
	    var b = other.prerelease[i];
	    debug('prerelease compare', i, a, b);
	    if (a === undefined && b === undefined)
	      return 0;
	    else if (b === undefined)
	      return 1;
	    else if (a === undefined)
	      return -1;
	    else if (a === b)
	      continue;
	    else
	      return compareIdentifiers(a, b);
	  } while (++i);
	};
	
	// preminor will bump the version up to the next minor release, and immediately
	// down to pre-release. premajor and prepatch work the same way.
	SemVer.prototype.inc = function(release, identifier) {
	  switch (release) {
	    case 'premajor':
	      this.prerelease.length = 0;
	      this.patch = 0;
	      this.minor = 0;
	      this.major++;
	      this.inc('pre', identifier);
	      break;
	    case 'preminor':
	      this.prerelease.length = 0;
	      this.patch = 0;
	      this.minor++;
	      this.inc('pre', identifier);
	      break;
	    case 'prepatch':
	      // If this is already a prerelease, it will bump to the next version
	      // drop any prereleases that might already exist, since they are not
	      // relevant at this point.
	      this.prerelease.length = 0;
	      this.inc('patch', identifier);
	      this.inc('pre', identifier);
	      break;
	    // If the input is a non-prerelease version, this acts the same as
	    // prepatch.
	    case 'prerelease':
	      if (this.prerelease.length === 0)
	        this.inc('patch', identifier);
	      this.inc('pre', identifier);
	      break;
	
	    case 'major':
	      // If this is a pre-major version, bump up to the same major version.
	      // Otherwise increment major.
	      // 1.0.0-5 bumps to 1.0.0
	      // 1.1.0 bumps to 2.0.0
	      if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0)
	        this.major++;
	      this.minor = 0;
	      this.patch = 0;
	      this.prerelease = [];
	      break;
	    case 'minor':
	      // If this is a pre-minor version, bump up to the same minor version.
	      // Otherwise increment minor.
	      // 1.2.0-5 bumps to 1.2.0
	      // 1.2.1 bumps to 1.3.0
	      if (this.patch !== 0 || this.prerelease.length === 0)
	        this.minor++;
	      this.patch = 0;
	      this.prerelease = [];
	      break;
	    case 'patch':
	      // If this is not a pre-release version, it will increment the patch.
	      // If it is a pre-release it will bump up to the same patch version.
	      // 1.2.0-5 patches to 1.2.0
	      // 1.2.0 patches to 1.2.1
	      if (this.prerelease.length === 0)
	        this.patch++;
	      this.prerelease = [];
	      break;
	    // This probably shouldn't be used publicly.
	    // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
	    case 'pre':
	      if (this.prerelease.length === 0)
	        this.prerelease = [0];
	      else {
	        var i = this.prerelease.length;
	        while (--i >= 0) {
	          if (typeof this.prerelease[i] === 'number') {
	            this.prerelease[i]++;
	            i = -2;
	          }
	        }
	        if (i === -1) // didn't increment anything
	          this.prerelease.push(0);
	      }
	      if (identifier) {
	        // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
	        // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
	        if (this.prerelease[0] === identifier) {
	          if (isNaN(this.prerelease[1]))
	            this.prerelease = [identifier, 0];
	        } else
	          this.prerelease = [identifier, 0];
	      }
	      break;
	
	    default:
	      throw new Error('invalid increment argument: ' + release);
	  }
	  this.format();
	  this.raw = this.version;
	  return this;
	};
	
	exports.inc = inc;
	function inc(version, release, loose, identifier) {
	  if (typeof(loose) === 'string') {
	    identifier = loose;
	    loose = undefined;
	  }
	
	  try {
	    return new SemVer(version, loose).inc(release, identifier).version;
	  } catch (er) {
	    return null;
	  }
	}
	
	exports.diff = diff;
	function diff(version1, version2) {
	  if (eq(version1, version2)) {
	    return null;
	  } else {
	    var v1 = parse(version1);
	    var v2 = parse(version2);
	    if (v1.prerelease.length || v2.prerelease.length) {
	      for (var key in v1) {
	        if (key === 'major' || key === 'minor' || key === 'patch') {
	          if (v1[key] !== v2[key]) {
	            return 'pre'+key;
	          }
	        }
	      }
	      return 'prerelease';
	    }
	    for (var key in v1) {
	      if (key === 'major' || key === 'minor' || key === 'patch') {
	        if (v1[key] !== v2[key]) {
	          return key;
	        }
	      }
	    }
	  }
	}
	
	exports.compareIdentifiers = compareIdentifiers;
	
	var numeric = /^[0-9]+$/;
	function compareIdentifiers(a, b) {
	  var anum = numeric.test(a);
	  var bnum = numeric.test(b);
	
	  if (anum && bnum) {
	    a = +a;
	    b = +b;
	  }
	
	  return (anum && !bnum) ? -1 :
	         (bnum && !anum) ? 1 :
	         a < b ? -1 :
	         a > b ? 1 :
	         0;
	}
	
	exports.rcompareIdentifiers = rcompareIdentifiers;
	function rcompareIdentifiers(a, b) {
	  return compareIdentifiers(b, a);
	}
	
	exports.major = major;
	function major(a, loose) {
	  return new SemVer(a, loose).major;
	}
	
	exports.minor = minor;
	function minor(a, loose) {
	  return new SemVer(a, loose).minor;
	}
	
	exports.patch = patch;
	function patch(a, loose) {
	  return new SemVer(a, loose).patch;
	}
	
	exports.compare = compare;
	function compare(a, b, loose) {
	  return new SemVer(a, loose).compare(b);
	}
	
	exports.compareLoose = compareLoose;
	function compareLoose(a, b) {
	  return compare(a, b, true);
	}
	
	exports.rcompare = rcompare;
	function rcompare(a, b, loose) {
	  return compare(b, a, loose);
	}
	
	exports.sort = sort;
	function sort(list, loose) {
	  return list.sort(function(a, b) {
	    return exports.compare(a, b, loose);
	  });
	}
	
	exports.rsort = rsort;
	function rsort(list, loose) {
	  return list.sort(function(a, b) {
	    return exports.rcompare(a, b, loose);
	  });
	}
	
	exports.gt = gt;
	function gt(a, b, loose) {
	  return compare(a, b, loose) > 0;
	}
	
	exports.lt = lt;
	function lt(a, b, loose) {
	  return compare(a, b, loose) < 0;
	}
	
	exports.eq = eq;
	function eq(a, b, loose) {
	  return compare(a, b, loose) === 0;
	}
	
	exports.neq = neq;
	function neq(a, b, loose) {
	  return compare(a, b, loose) !== 0;
	}
	
	exports.gte = gte;
	function gte(a, b, loose) {
	  return compare(a, b, loose) >= 0;
	}
	
	exports.lte = lte;
	function lte(a, b, loose) {
	  return compare(a, b, loose) <= 0;
	}
	
	exports.cmp = cmp;
	function cmp(a, op, b, loose) {
	  var ret;
	  switch (op) {
	    case '===':
	      if (typeof a === 'object') a = a.version;
	      if (typeof b === 'object') b = b.version;
	      ret = a === b;
	      break;
	    case '!==':
	      if (typeof a === 'object') a = a.version;
	      if (typeof b === 'object') b = b.version;
	      ret = a !== b;
	      break;
	    case '': case '=': case '==': ret = eq(a, b, loose); break;
	    case '!=': ret = neq(a, b, loose); break;
	    case '>': ret = gt(a, b, loose); break;
	    case '>=': ret = gte(a, b, loose); break;
	    case '<': ret = lt(a, b, loose); break;
	    case '<=': ret = lte(a, b, loose); break;
	    default: throw new TypeError('Invalid operator: ' + op);
	  }
	  return ret;
	}
	
	exports.Comparator = Comparator;
	function Comparator(comp, loose) {
	  if (comp instanceof Comparator) {
	    if (comp.loose === loose)
	      return comp;
	    else
	      comp = comp.value;
	  }
	
	  if (!(this instanceof Comparator))
	    return new Comparator(comp, loose);
	
	  debug('comparator', comp, loose);
	  this.loose = loose;
	  this.parse(comp);
	
	  if (this.semver === ANY)
	    this.value = '';
	  else
	    this.value = this.operator + this.semver.version;
	
	  debug('comp', this);
	}
	
	var ANY = {};
	Comparator.prototype.parse = function(comp) {
	  var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
	  var m = comp.match(r);
	
	  if (!m)
	    throw new TypeError('Invalid comparator: ' + comp);
	
	  this.operator = m[1];
	  if (this.operator === '=')
	    this.operator = '';
	
	  // if it literally is just '>' or '' then allow anything.
	  if (!m[2])
	    this.semver = ANY;
	  else
	    this.semver = new SemVer(m[2], this.loose);
	};
	
	Comparator.prototype.toString = function() {
	  return this.value;
	};
	
	Comparator.prototype.test = function(version) {
	  debug('Comparator.test', version, this.loose);
	
	  if (this.semver === ANY)
	    return true;
	
	  if (typeof version === 'string')
	    version = new SemVer(version, this.loose);
	
	  return cmp(version, this.operator, this.semver, this.loose);
	};
	
	
	exports.Range = Range;
	function Range(range, loose) {
	  if ((range instanceof Range) && range.loose === loose)
	    return range;
	
	  if (!(this instanceof Range))
	    return new Range(range, loose);
	
	  this.loose = loose;
	
	  // First, split based on boolean or ||
	  this.raw = range;
	  this.set = range.split(/\s*\|\|\s*/).map(function(range) {
	    return this.parseRange(range.trim());
	  }, this).filter(function(c) {
	    // throw out any that are not relevant for whatever reason
	    return c.length;
	  });
	
	  if (!this.set.length) {
	    throw new TypeError('Invalid SemVer Range: ' + range);
	  }
	
	  this.format();
	}
	
	Range.prototype.format = function() {
	  this.range = this.set.map(function(comps) {
	    return comps.join(' ').trim();
	  }).join('||').trim();
	  return this.range;
	};
	
	Range.prototype.toString = function() {
	  return this.range;
	};
	
	Range.prototype.parseRange = function(range) {
	  var loose = this.loose;
	  range = range.trim();
	  debug('range', range, loose);
	  // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
	  var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
	  range = range.replace(hr, hyphenReplace);
	  debug('hyphen replace', range);
	  // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
	  range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
	  debug('comparator trim', range, re[COMPARATORTRIM]);
	
	  // `~ 1.2.3` => `~1.2.3`
	  range = range.replace(re[TILDETRIM], tildeTrimReplace);
	
	  // `^ 1.2.3` => `^1.2.3`
	  range = range.replace(re[CARETTRIM], caretTrimReplace);
	
	  // normalize spaces
	  range = range.split(/\s+/).join(' ');
	
	  // At this point, the range is completely trimmed and
	  // ready to be split into comparators.
	
	  var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
	  var set = range.split(' ').map(function(comp) {
	    return parseComparator(comp, loose);
	  }).join(' ').split(/\s+/);
	  if (this.loose) {
	    // in loose mode, throw out any that are not valid comparators
	    set = set.filter(function(comp) {
	      return !!comp.match(compRe);
	    });
	  }
	  set = set.map(function(comp) {
	    return new Comparator(comp, loose);
	  });
	
	  return set;
	};
	
	// Mostly just for testing and legacy API reasons
	exports.toComparators = toComparators;
	function toComparators(range, loose) {
	  return new Range(range, loose).set.map(function(comp) {
	    return comp.map(function(c) {
	      return c.value;
	    }).join(' ').trim().split(' ');
	  });
	}
	
	// comprised of xranges, tildes, stars, and gtlt's at this point.
	// already replaced the hyphen ranges
	// turn into a set of JUST comparators.
	function parseComparator(comp, loose) {
	  debug('comp', comp);
	  comp = replaceCarets(comp, loose);
	  debug('caret', comp);
	  comp = replaceTildes(comp, loose);
	  debug('tildes', comp);
	  comp = replaceXRanges(comp, loose);
	  debug('xrange', comp);
	  comp = replaceStars(comp, loose);
	  debug('stars', comp);
	  return comp;
	}
	
	function isX(id) {
	  return !id || id.toLowerCase() === 'x' || id === '*';
	}
	
	// ~, ~> --> * (any, kinda silly)
	// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
	// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
	// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
	// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
	// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
	function replaceTildes(comp, loose) {
	  return comp.trim().split(/\s+/).map(function(comp) {
	    return replaceTilde(comp, loose);
	  }).join(' ');
	}
	
	function replaceTilde(comp, loose) {
	  var r = loose ? re[TILDELOOSE] : re[TILDE];
	  return comp.replace(r, function(_, M, m, p, pr) {
	    debug('tilde', comp, _, M, m, p, pr);
	    var ret;
	
	    if (isX(M))
	      ret = '';
	    else if (isX(m))
	      ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
	    else if (isX(p))
	      // ~1.2 == >=1.2.0 <1.3.0
	      ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
	    else if (pr) {
	      debug('replaceTilde pr', pr);
	      if (pr.charAt(0) !== '-')
	        pr = '-' + pr;
	      ret = '>=' + M + '.' + m + '.' + p + pr +
	            ' <' + M + '.' + (+m + 1) + '.0';
	    } else
	      // ~1.2.3 == >=1.2.3 <1.3.0
	      ret = '>=' + M + '.' + m + '.' + p +
	            ' <' + M + '.' + (+m + 1) + '.0';
	
	    debug('tilde return', ret);
	    return ret;
	  });
	}
	
	// ^ --> * (any, kinda silly)
	// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
	// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
	// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
	// ^1.2.3 --> >=1.2.3 <2.0.0
	// ^1.2.0 --> >=1.2.0 <2.0.0
	function replaceCarets(comp, loose) {
	  return comp.trim().split(/\s+/).map(function(comp) {
	    return replaceCaret(comp, loose);
	  }).join(' ');
	}
	
	function replaceCaret(comp, loose) {
	  debug('caret', comp, loose);
	  var r = loose ? re[CARETLOOSE] : re[CARET];
	  return comp.replace(r, function(_, M, m, p, pr) {
	    debug('caret', comp, _, M, m, p, pr);
	    var ret;
	
	    if (isX(M))
	      ret = '';
	    else if (isX(m))
	      ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
	    else if (isX(p)) {
	      if (M === '0')
	        ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
	      else
	        ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0';
	    } else if (pr) {
	      debug('replaceCaret pr', pr);
	      if (pr.charAt(0) !== '-')
	        pr = '-' + pr;
	      if (M === '0') {
	        if (m === '0')
	          ret = '>=' + M + '.' + m + '.' + p + pr +
	                ' <' + M + '.' + m + '.' + (+p + 1);
	        else
	          ret = '>=' + M + '.' + m + '.' + p + pr +
	                ' <' + M + '.' + (+m + 1) + '.0';
	      } else
	        ret = '>=' + M + '.' + m + '.' + p + pr +
	              ' <' + (+M + 1) + '.0.0';
	    } else {
	      debug('no pr');
	      if (M === '0') {
	        if (m === '0')
	          ret = '>=' + M + '.' + m + '.' + p +
	                ' <' + M + '.' + m + '.' + (+p + 1);
	        else
	          ret = '>=' + M + '.' + m + '.' + p +
	                ' <' + M + '.' + (+m + 1) + '.0';
	      } else
	        ret = '>=' + M + '.' + m + '.' + p +
	              ' <' + (+M + 1) + '.0.0';
	    }
	
	    debug('caret return', ret);
	    return ret;
	  });
	}
	
	function replaceXRanges(comp, loose) {
	  debug('replaceXRanges', comp, loose);
	  return comp.split(/\s+/).map(function(comp) {
	    return replaceXRange(comp, loose);
	  }).join(' ');
	}
	
	function replaceXRange(comp, loose) {
	  comp = comp.trim();
	  var r = loose ? re[XRANGELOOSE] : re[XRANGE];
	  return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
	    debug('xRange', comp, ret, gtlt, M, m, p, pr);
	    var xM = isX(M);
	    var xm = xM || isX(m);
	    var xp = xm || isX(p);
	    var anyX = xp;
	
	    if (gtlt === '=' && anyX)
	      gtlt = '';
	
	    if (xM) {
	      if (gtlt === '>' || gtlt === '<') {
	        // nothing is allowed
	        ret = '<0.0.0';
	      } else {
	        // nothing is forbidden
	        ret = '*';
	      }
	    } else if (gtlt && anyX) {
	      // replace X with 0
	      if (xm)
	        m = 0;
	      if (xp)
	        p = 0;
	
	      if (gtlt === '>') {
	        // >1 => >=2.0.0
	        // >1.2 => >=1.3.0
	        // >1.2.3 => >= 1.2.4
	        gtlt = '>=';
	        if (xm) {
	          M = +M + 1;
	          m = 0;
	          p = 0;
	        } else if (xp) {
	          m = +m + 1;
	          p = 0;
	        }
	      } else if (gtlt === '<=') {
	        // <=0.7.x is actually <0.8.0, since any 0.7.x should
	        // pass.  Similarly, <=7.x is actually <8.0.0, etc.
	        gtlt = '<';
	        if (xm)
	          M = +M + 1;
	        else
	          m = +m + 1;
	      }
	
	      ret = gtlt + M + '.' + m + '.' + p;
	    } else if (xm) {
	      ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
	    } else if (xp) {
	      ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
	    }
	
	    debug('xRange return', ret);
	
	    return ret;
	  });
	}
	
	// Because * is AND-ed with everything else in the comparator,
	// and '' means "any version", just remove the *s entirely.
	function replaceStars(comp, loose) {
	  debug('replaceStars', comp, loose);
	  // Looseness is ignored here.  star is always as loose as it gets!
	  return comp.trim().replace(re[STAR], '');
	}
	
	// This function is passed to string.replace(re[HYPHENRANGE])
	// M, m, patch, prerelease, build
	// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
	// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
	// 1.2 - 3.4 => >=1.2.0 <3.5.0
	function hyphenReplace($0,
	                       from, fM, fm, fp, fpr, fb,
	                       to, tM, tm, tp, tpr, tb) {
	
	  if (isX(fM))
	    from = '';
	  else if (isX(fm))
	    from = '>=' + fM + '.0.0';
	  else if (isX(fp))
	    from = '>=' + fM + '.' + fm + '.0';
	  else
	    from = '>=' + from;
	
	  if (isX(tM))
	    to = '';
	  else if (isX(tm))
	    to = '<' + (+tM + 1) + '.0.0';
	  else if (isX(tp))
	    to = '<' + tM + '.' + (+tm + 1) + '.0';
	  else if (tpr)
	    to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr;
	  else
	    to = '<=' + to;
	
	  return (from + ' ' + to).trim();
	}
	
	
	// if ANY of the sets match ALL of its comparators, then pass
	Range.prototype.test = function(version) {
	  if (!version)
	    return false;
	
	  if (typeof version === 'string')
	    version = new SemVer(version, this.loose);
	
	  for (var i = 0; i < this.set.length; i++) {
	    if (testSet(this.set[i], version))
	      return true;
	  }
	  return false;
	};
	
	function testSet(set, version) {
	  for (var i = 0; i < set.length; i++) {
	    if (!set[i].test(version))
	      return false;
	  }
	
	  if (version.prerelease.length) {
	    // Find the set of versions that are allowed to have prereleases
	    // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
	    // That should allow `1.2.3-pr.2` to pass.
	    // However, `1.2.4-alpha.notready` should NOT be allowed,
	    // even though it's within the range set by the comparators.
	    for (var i = 0; i < set.length; i++) {
	      debug(set[i].semver);
	      if (set[i].semver === ANY)
	        continue;
	
	      if (set[i].semver.prerelease.length > 0) {
	        var allowed = set[i].semver;
	        if (allowed.major === version.major &&
	            allowed.minor === version.minor &&
	            allowed.patch === version.patch)
	          return true;
	      }
	    }
	
	    // Version has a -pre, but it's not one of the ones we like.
	    return false;
	  }
	
	  return true;
	}
	
	exports.satisfies = satisfies;
	function satisfies(version, range, loose) {
	  try {
	    range = new Range(range, loose);
	  } catch (er) {
	    return false;
	  }
	  return range.test(version);
	}
	
	exports.maxSatisfying = maxSatisfying;
	function maxSatisfying(versions, range, loose) {
	  return versions.filter(function(version) {
	    return satisfies(version, range, loose);
	  }).sort(function(a, b) {
	    return rcompare(a, b, loose);
	  })[0] || null;
	}
	
	exports.minSatisfying = minSatisfying;
	function minSatisfying(versions, range, loose) {
	  return versions.filter(function(version) {
	    return satisfies(version, range, loose);
	  }).sort(function(a, b) {
	    return compare(a, b, loose);
	  })[0] || null;
	}
	
	exports.validRange = validRange;
	function validRange(range, loose) {
	  try {
	    // Return '*' instead of '' so that truthiness works.
	    // This will throw if it's invalid anyway
	    return new Range(range, loose).range || '*';
	  } catch (er) {
	    return null;
	  }
	}
	
	// Determine if version is less than all the versions possible in the range
	exports.ltr = ltr;
	function ltr(version, range, loose) {
	  return outside(version, range, '<', loose);
	}
	
	// Determine if version is greater than all the versions possible in the range.
	exports.gtr = gtr;
	function gtr(version, range, loose) {
	  return outside(version, range, '>', loose);
	}
	
	exports.outside = outside;
	function outside(version, range, hilo, loose) {
	  version = new SemVer(version, loose);
	  range = new Range(range, loose);
	
	  var gtfn, ltefn, ltfn, comp, ecomp;
	  switch (hilo) {
	    case '>':
	      gtfn = gt;
	      ltefn = lte;
	      ltfn = lt;
	      comp = '>';
	      ecomp = '>=';
	      break;
	    case '<':
	      gtfn = lt;
	      ltefn = gte;
	      ltfn = gt;
	      comp = '<';
	      ecomp = '<=';
	      break;
	    default:
	      throw new TypeError('Must provide a hilo val of "<" or ">"');
	  }
	
	  // If it satisifes the range it is not outside
	  if (satisfies(version, range, loose)) {
	    return false;
	  }
	
	  // From now on, variable terms are as if we're in "gtr" mode.
	  // but note that everything is flipped for the "ltr" function.
	
	  for (var i = 0; i < range.set.length; ++i) {
	    var comparators = range.set[i];
	
	    var high = null;
	    var low = null;
	
	    comparators.forEach(function(comparator) {
	      if (comparator.semver === ANY) {
	        comparator = new Comparator('>=0.0.0')
	      }
	      high = high || comparator;
	      low = low || comparator;
	      if (gtfn(comparator.semver, high.semver, loose)) {
	        high = comparator;
	      } else if (ltfn(comparator.semver, low.semver, loose)) {
	        low = comparator;
	      }
	    });
	
	    // If the edge version comparator has a operator then our version
	    // isn't outside it
	    if (high.operator === comp || high.operator === ecomp) {
	      return false;
	    }
	
	    // If the lowest version comparator has an operator and our version
	    // is less than it then it isn't higher than the range
	    if ((!low.operator || low.operator === comp) &&
	        ltefn(version, low.semver)) {
	      return false;
	    } else if (low.operator === ecomp && ltfn(version, low.semver)) {
	      return false;
	    }
	  }
	  return true;
	}
	
	exports.prerelease = prerelease;
	function prerelease(version, loose) {
	  var parsed = parse(version, loose);
	  return (parsed && parsed.prerelease.length) ? parsed.prerelease : null;
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('process@0.11.10/browser.js')))
})
/** END DEFINE BLOCK for semver@5.3.0/semver.js **/


/** START DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/plugin.js **/
jupyter.define('@jupyterlab/nbwidgets@0.6.17/lib/plugin.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	var docregistry_1 = __jupyter_require__('@jupyterlab/docregistry@^0.3.0/lib/index.js');
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var index_1 = __jupyter_require__('@jupyterlab/nbwidgets@0.6.17/lib/index.js');
	var output_1 = __jupyter_require__('@jupyterlab/nbwidgets@0.6.17/lib/output.js');
	var widgets = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/index.js');
	widgets['OutputModel'] = output_1.OutputModel;
	widgets['OutputView'] = output_1.OutputView;
	__jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/css/widgets-base.css');
	var WIDGET_MIMETYPE = 'application/vnd.jupyter.widget-view+json';
	var NBWidgetExtension = (function () {
	    function NBWidgetExtension() {
	        this._registry = [];
	    }
	    /**
	     * Create a new extension object.
	     */
	    NBWidgetExtension.prototype.createNew = function (nb, context) {
	        var wManager = new index_1.WidgetManager(context, nb.rendermime);
	        wManager.register({
	            name: 'jupyter-js-widgets',
	            version: widgets.version,
	            exports: widgets
	        });
	        this._registry.forEach(function (data) { return wManager.register(data); });
	        var wRenderer = new index_1.WidgetRenderer(wManager);
	        nb.rendermime.addRenderer({ mimeType: WIDGET_MIMETYPE, renderer: wRenderer }, 0);
	        return new disposable_1.DisposableDelegate(function () {
	            if (nb.rendermime) {
	                nb.rendermime.removeRenderer(WIDGET_MIMETYPE);
	            }
	            wRenderer.dispose();
	            wManager.dispose();
	        });
	    };
	    /**
	     * Register a widget module.
	     */
	    NBWidgetExtension.prototype.registerWidget = function (data) {
	        this._registry.push(data);
	    };
	    return NBWidgetExtension;
	}());
	exports.NBWidgetExtension = NBWidgetExtension;
	/**
	 * The widget manager provider.
	 */
	var widgetManagerProvider = {
	    id: 'jupyter.extensions.nbWidgetManager',
	    provides: index_1.INBWidgetExtension,
	    requires: [docregistry_1.IDocumentRegistry],
	    activate: activateWidgetExtension,
	    autoStart: true
	};
	exports.default = widgetManagerProvider;
	/**
	 * Activate the widget extension.
	 */
	function activateWidgetExtension(app, registry) {
	    var extension = new NBWidgetExtension();
	    registry.addWidgetExtension('Notebook', extension);
	    return extension;
	}
	
})
/** END DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/plugin.js **/


/** START DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/index.js **/
jupyter.define('@jupyterlab/docregistry@0.3.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('@jupyterlab/docregistry@0.3.1/lib/context.js'));
	__export(__jupyter_require__('@jupyterlab/docregistry@0.3.1/lib/default.js'));
	__export(__jupyter_require__('@jupyterlab/docregistry@0.3.1/lib/registry.js'));
	
})
/** END DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/context.js **/
jupyter.define('@jupyterlab/docregistry@0.3.1/lib/context.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __assign = (this && this.__assign) || Object.assign || function(t) {
	    for (var s, i = 1, n = arguments.length; i < n; i++) {
	        s = arguments[i];
	        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
	            t[p] = s[p];
	    }
	    return t;
	};
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var apputils_1 = __jupyter_require__('@jupyterlab/apputils@^0.3.1/lib/index.js');
	var coreutils_2 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	var _1 = __jupyter_require__('@jupyterlab/docregistry@0.3.1/lib/index.js');
	/**
	 * An implementation of a document context.
	 *
	 * This class is typically instantiated by the document manger.
	 */
	var Context = (function () {
	    /**
	     * Construct a new document context.
	     */
	    function Context(options) {
	        var _this = this;
	        this._manager = null;
	        this._opener = null;
	        this._model = null;
	        this._path = '';
	        this._factory = null;
	        this._contentsModel = null;
	        this._populatedPromise = new coreutils_1.PromiseDelegate();
	        this._isPopulated = false;
	        this._isReady = false;
	        this._pathChanged = new signaling_1.Signal(this);
	        this._fileChanged = new signaling_1.Signal(this);
	        this._disposed = new signaling_1.Signal(this);
	        var manager = this._manager = options.manager;
	        this._factory = options.factory;
	        this._opener = options.opener;
	        this._path = options.path;
	        var ext = _1.DocumentRegistry.extname(this._path);
	        var lang = this._factory.preferredLanguage(ext);
	        this._model = this._factory.createNew(lang);
	        this._readyPromise = manager.ready.then(function () {
	            return _this._populatedPromise.promise;
	        });
	        this.session = new apputils_1.ClientSession({
	            manager: manager.sessions,
	            path: this._path,
	            name: this._path.split('/').pop(),
	            kernelPreference: options.kernelPreference || { shouldStart: false }
	        });
	        this.session.propertyChanged.connect(this._onSessionChanged, this);
	        manager.contents.fileChanged.connect(this._onFileChanged, this);
	    }
	    Object.defineProperty(Context.prototype, "pathChanged", {
	        /**
	         * A signal emitted when the path changes.
	         */
	        get: function () {
	            return this._pathChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "fileChanged", {
	        /**
	         * A signal emitted when the model is saved or reverted.
	         */
	        get: function () {
	            return this._fileChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "disposed", {
	        /**
	         * A signal emitted when the context is disposed.
	         */
	        get: function () {
	            return this._disposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "model", {
	        /**
	         * Get the model associated with the document.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "path", {
	        /**
	         * The current path associated with the document.
	         */
	        get: function () {
	            return this._path;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "contentsModel", {
	        /**
	         * The current contents model associated with the document
	         *
	         * #### Notes
	         * The model will have an  empty `contents` field.
	         */
	        get: function () {
	            return this._contentsModel;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "factoryName", {
	        /**
	         * Get the model factory name.
	         *
	         * #### Notes
	         * This is not part of the `IContext` API.
	         */
	        get: function () {
	            return this.isDisposed ? '' : this._factory.name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "isDisposed", {
	        /**
	         * Test whether the context is disposed.
	         */
	        get: function () {
	            return this._model === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the context.
	     */
	    Context.prototype.dispose = function () {
	        if (this._model == null) {
	            return;
	        }
	        var model = this._model;
	        this.session.dispose();
	        this._model = null;
	        this._manager = null;
	        this._factory = null;
	        model.dispose();
	        this._disposed.emit(void 0);
	        signaling_1.Signal.clearData(this);
	    };
	    Object.defineProperty(Context.prototype, "isReady", {
	        /**
	         * Whether the context is ready.
	         */
	        get: function () {
	            return this._isReady;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Context.prototype, "ready", {
	        /**
	         * A promise that is fulfilled when the context is ready.
	         */
	        get: function () {
	            return this._readyPromise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Save the document contents to disk.
	     */
	    Context.prototype.save = function () {
	        var _this = this;
	        var model = this._model;
	        var path = this._path;
	        if (model.readOnly) {
	            return Promise.reject(new Error('Read only'));
	        }
	        var content;
	        if (this._factory.fileFormat === 'json') {
	            content = model.toJSON();
	        }
	        else {
	            content = model.toString();
	        }
	        var options = {
	            type: this._factory.contentType,
	            format: this._factory.fileFormat,
	            content: content
	        };
	        return this._manager.ready.then(function () {
	            return _this._manager.contents.save(path, options);
	        }).then(function (value) {
	            if (_this.isDisposed) {
	                return;
	            }
	            model.dirty = false;
	            _this._updateContentsModel(value);
	            if (!_this._isPopulated) {
	                return _this._populate();
	            }
	        }).catch(function (err) {
	            apputils_1.showDialog({
	                title: 'File Save Error',
	                body: err.xhr.responseText,
	                buttons: [apputils_1.Dialog.okButton()]
	            });
	        });
	    };
	    /**
	     * Save the document to a different path chosen by the user.
	     */
	    Context.prototype.saveAs = function () {
	        var _this = this;
	        return Private.getSavePath(this._path).then(function (newPath) {
	            if (_this.isDisposed || !newPath) {
	                return;
	            }
	            _this._path = newPath;
	            _this.session.setName(newPath.split('/').pop());
	            return _this.session.setPath(newPath).then(function () { return _this.save(); });
	        });
	    };
	    /**
	     * Revert the document contents to disk contents.
	     */
	    Context.prototype.revert = function () {
	        var _this = this;
	        var opts = {
	            format: this._factory.fileFormat,
	            type: this._factory.contentType,
	            content: true
	        };
	        var path = this._path;
	        var model = this._model;
	        return this._manager.ready.then(function () {
	            return _this._manager.contents.get(path, opts);
	        }).then(function (contents) {
	            if (_this.isDisposed) {
	                return;
	            }
	            if (contents.format === 'json') {
	                model.fromJSON(contents.content);
	            }
	            else {
	                model.fromString(contents.content);
	            }
	            _this._updateContentsModel(contents);
	            model.dirty = false;
	            if (!_this._isPopulated) {
	                return _this._populate();
	            }
	        }).catch(function (err) {
	            apputils_1.showDialog({
	                title: 'File Load Error',
	                body: err.xhr.responseText,
	                buttons: [apputils_1.Dialog.okButton()]
	            });
	        });
	    };
	    /**
	     * Create a checkpoint for the file.
	     */
	    Context.prototype.createCheckpoint = function () {
	        var _this = this;
	        var contents = this._manager.contents;
	        return this._manager.ready.then(function () {
	            return contents.createCheckpoint(_this._path);
	        });
	    };
	    /**
	     * Delete a checkpoint for the file.
	     */
	    Context.prototype.deleteCheckpoint = function (checkpointId) {
	        var _this = this;
	        var contents = this._manager.contents;
	        return this._manager.ready.then(function () {
	            return contents.deleteCheckpoint(_this._path, checkpointId);
	        });
	    };
	    /**
	     * Restore the file to a known checkpoint state.
	     */
	    Context.prototype.restoreCheckpoint = function (checkpointId) {
	        var _this = this;
	        var contents = this._manager.contents;
	        var path = this._path;
	        return this._manager.ready.then(function () {
	            if (checkpointId) {
	                return contents.restoreCheckpoint(path, checkpointId);
	            }
	            return _this.listCheckpoints().then(function (checkpoints) {
	                if (_this.isDisposed || !checkpoints.length) {
	                    return;
	                }
	                checkpointId = checkpoints[checkpoints.length - 1].id;
	                return contents.restoreCheckpoint(path, checkpointId);
	            });
	        });
	    };
	    /**
	     * List available checkpoints for a file.
	     */
	    Context.prototype.listCheckpoints = function () {
	        var _this = this;
	        var contents = this._manager.contents;
	        return this._manager.ready.then(function () {
	            return contents.listCheckpoints(_this._path);
	        });
	    };
	    /**
	     * Resolve a relative url to a correct server path.
	     */
	    Context.prototype.resolveUrl = function (url) {
	        if (coreutils_2.URLExt.isLocal(url)) {
	            var cwd = coreutils_2.PathExt.dirname(this._path);
	            url = coreutils_2.PathExt.resolve(cwd, url);
	        }
	        return Promise.resolve(url);
	    };
	    /**
	     * Get the download url of a given absolute server path.
	     */
	    Context.prototype.getDownloadUrl = function (path) {
	        var contents = this._manager.contents;
	        if (coreutils_2.URLExt.isLocal(path)) {
	            return this._manager.ready.then(function () { return contents.getDownloadUrl(path); });
	        }
	        return Promise.resolve(path);
	    };
	    /**
	     * Add a sibling widget to the document manager.
	     */
	    Context.prototype.addSibling = function (widget) {
	        var opener = this._opener;
	        if (opener) {
	            opener(widget);
	        }
	        return new disposable_1.DisposableDelegate(function () {
	            widget.close();
	        });
	    };
	    /**
	     * Handle a change on the contents manager.
	     */
	    Context.prototype._onFileChanged = function (sender, change) {
	        if (change.type !== 'rename') {
	            return;
	        }
	        if (change.oldValue.path === this._path) {
	            var newPath = change.newValue.path;
	            this.session.setPath(newPath);
	            this.session.setName(newPath.split('/').pop());
	            this._path = newPath;
	            this._updateContentsModel(change.newValue);
	            this._pathChanged.emit(this._path);
	        }
	    };
	    /**
	     * Handle a change to a session property.
	     */
	    Context.prototype._onSessionChanged = function () {
	        var path = this.session.path;
	        if (path !== this._path) {
	            this._path = path;
	            this._pathChanged.emit(path);
	        }
	    };
	    /**
	     * Update our contents model, without the content.
	     */
	    Context.prototype._updateContentsModel = function (model) {
	        var newModel = {
	            path: model.path,
	            name: model.name,
	            type: model.type,
	            writable: model.writable,
	            created: model.created,
	            last_modified: model.last_modified,
	            mimetype: model.mimetype,
	            format: model.format
	        };
	        var mod = this._contentsModel ? this._contentsModel.last_modified : null;
	        this._contentsModel = newModel;
	        if (!mod || newModel.last_modified !== mod) {
	            this._fileChanged.emit(newModel);
	        }
	    };
	    /**
	     * Handle an initial population.
	     */
	    Context.prototype._populate = function () {
	        var _this = this;
	        this._isPopulated = true;
	        // Add a checkpoint if none exists.
	        return this.listCheckpoints().then(function (checkpoints) {
	            if (!_this.isDisposed && !checkpoints) {
	                return _this.createCheckpoint();
	            }
	        }).then(function () {
	            if (_this.isDisposed) {
	                return;
	            }
	            // Update the kernel preference.
	            var name = (_this._model.defaultKernelName || _this.session.kernelPreference.name);
	            _this.session.kernelPreference = __assign({}, _this.session.kernelPreference, { name: name, language: _this._model.defaultKernelLanguage });
	            return _this.session.initialize();
	        }).then(function () {
	            _this._isReady = true;
	            _this._populatedPromise.resolve(void 0);
	        });
	    };
	    return Context;
	}());
	exports.Context = Context;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Get a new file path from the user.
	     */
	    function getSavePath(path) {
	        var input = document.createElement('input');
	        input.value = path;
	        var saveBtn = apputils_1.Dialog.okButton({ label: 'SAVE' });
	        return apputils_1.showDialog({
	            title: 'Save File As..',
	            body: input,
	            buttons: [apputils_1.Dialog.cancelButton(), saveBtn]
	        }).then(function (result) {
	            if (result.label === 'SAVE') {
	                return input.value;
	            }
	        });
	    }
	    Private.getSavePath = getSavePath;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/context.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/index.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/clientsession.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/clipboard.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/commandlinker.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/commandpalette.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/dialog.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/domutils.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/hoverbox.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/iframe.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/instancetracker.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/layoutrestorer.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/mainmenu.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/sanitizer.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/statedb.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/styling.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/toolbar.js'));
	__export(__jupyter_require__('@jupyterlab/apputils@0.3.1/lib/vdom.js'));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/clientsession.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/clientsession.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_2 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var _1 = __jupyter_require__('@jupyterlab/apputils@0.3.1/lib/index.js');
	/**
	 * The default implementation of client session object.
	 */
	var ClientSession = (function () {
	    /**
	     * Construct a new client session.
	     */
	    function ClientSession(options) {
	        this._path = '';
	        this._name = '';
	        this._type = '';
	        this._prevKernelName = '';
	        this._isDisposed = false;
	        this._session = null;
	        this._ready = new coreutils_2.PromiseDelegate();
	        this._initializing = false;
	        this._isReady = false;
	        this._terminated = new signaling_1.Signal(this);
	        this._kernelChanged = new signaling_1.Signal(this);
	        this._statusChanged = new signaling_1.Signal(this);
	        this._iopubMessage = new signaling_1.Signal(this);
	        this._unhandledMessage = new signaling_1.Signal(this);
	        this._propertyChanged = new signaling_1.Signal(this);
	        this.manager = options.manager;
	        this._path = options.path || coreutils_1.uuid();
	        this._type = options.type || '';
	        this._name = options.name || '';
	        this._kernelPreference = options.kernelPreference || {};
	    }
	    Object.defineProperty(ClientSession.prototype, "terminated", {
	        /**
	         * A signal emitted when the session is shut down.
	         */
	        get: function () {
	            return this._terminated;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "kernelChanged", {
	        /**
	         * A signal emitted when the kernel changes.
	         */
	        get: function () {
	            return this._kernelChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "statusChanged", {
	        /**
	         * A signal emitted when the status changes.
	         */
	        get: function () {
	            return this._statusChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "iopubMessage", {
	        /**
	         * A signal emitted for iopub kernel messages.
	         */
	        get: function () {
	            return this._iopubMessage;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "unhandledMessage", {
	        /**
	         * A signal emitted for an unhandled kernel message.
	         */
	        get: function () {
	            return this._unhandledMessage;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "propertyChanged", {
	        /**
	         * A signal emitted when a session property changes.
	         */
	        get: function () {
	            return this._propertyChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "kernel", {
	        /**
	         * The current kernel of the session.
	         */
	        get: function () {
	            return this._session ? this._session.kernel : null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "path", {
	        /**
	         * The current path of the session.
	         */
	        get: function () {
	            return this._path;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "name", {
	        /**
	         * The current name of the session.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "type", {
	        /**
	         * The type of the client session.
	         */
	        get: function () {
	            return this._type;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "kernelPreference", {
	        /**
	         * The kernel preference of the session.
	         */
	        get: function () {
	            return this._kernelPreference;
	        },
	        set: function (value) {
	            this._kernelPreference = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "status", {
	        /**
	         * The current status of the session.
	         */
	        get: function () {
	            if (!this.isReady) {
	                return 'starting';
	            }
	            return this._session ? this._session.status : 'dead';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "isReady", {
	        /**
	         * Whether the session is ready.
	         */
	        get: function () {
	            return this._isReady;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "ready", {
	        /**
	         * A promise that is fulfilled when the session is ready.
	         */
	        get: function () {
	            return this._ready.promise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "kernelDisplayName", {
	        /**
	         * The display name of the current kernel.
	         */
	        get: function () {
	            var kernel = this.kernel;
	            if (!kernel) {
	                return 'No Kernel!';
	            }
	            if (!this.manager.isReady) {
	                return 'Unknown!';
	            }
	            var spec = this.manager.specs.kernelspecs[kernel.name];
	            return spec ? spec.display_name : kernel.name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ClientSession.prototype, "isDisposed", {
	        /**
	         * Test whether the context is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the context.
	     */
	    ClientSession.prototype.dispose = function () {
	        if (this._isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        if (this._session) {
	            this._session.dispose();
	            this._session = null;
	        }
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * Change the current kernel associated with the document.
	     */
	    ClientSession.prototype.changeKernel = function (options) {
	        var _this = this;
	        return this.ready.then(function () {
	            if (_this.isDisposed) {
	                return;
	            }
	            return _this._changeKernel(options);
	        });
	    };
	    /**
	     * Select a kernel for the session.
	     */
	    ClientSession.prototype.selectKernel = function () {
	        var _this = this;
	        return this.ready.then(function () {
	            if (_this.isDisposed) {
	                return;
	            }
	            return _this._selectKernel();
	        });
	    };
	    /**
	     * Kill the kernel and shutdown the session.
	     *
	     * @returns A promise that resolves when the session is shut down.
	     */
	    ClientSession.prototype.shutdown = function () {
	        if (this.isDisposed || !this._session) {
	            return Promise.resolve(void 0);
	        }
	        var session = this._session;
	        this._session = null;
	        if (session) {
	            return session.shutdown();
	        }
	    };
	    /**
	     * Restart the session.
	     *
	     * @returns A promise that resolves with the kernel model.
	     *
	     * #### Notes
	     * If there is a running kernel, present a dialog.
	     * If there is no kernel, we start a kernel with the last run
	     * kernel name.
	     * If no kernel has been started, this is a no-op.
	     */
	    ClientSession.prototype.restart = function () {
	        var _this = this;
	        return this.ready.then(function () {
	            if (_this.isDisposed) {
	                return;
	            }
	            var kernel = _this.kernel;
	            if (!kernel) {
	                if (_this._prevKernelName) {
	                    return _this.changeKernel({ name: _this._prevKernelName });
	                }
	                // Bail if there is no previous kernel to start.
	                return;
	            }
	            return ClientSession.restartKernel(kernel);
	        });
	    };
	    /**
	     * Change the session path.
	     *
	     * @param path - The new session path.
	     *
	     * @returns A promise that resolves when the session has renamed.
	     *
	     * #### Notes
	     * This uses the Jupyter REST API, and the response is validated.
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    ClientSession.prototype.setPath = function (path) {
	        if (this.isDisposed || this._path === path) {
	            return Promise.resolve(void 0);
	        }
	        this._path = path;
	        this._propertyChanged.emit('path');
	        if (this._session) {
	            return this._session.rename(path);
	        }
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Change the session name.
	     */
	    ClientSession.prototype.setName = function (name) {
	        if (this.isDisposed || this._name === name) {
	            return Promise.resolve(void 0);
	        }
	        this._name = name;
	        // no-op until supported.
	        this._propertyChanged.emit('name');
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Change the session type.
	     */
	    ClientSession.prototype.setType = function (type) {
	        if (this.isDisposed || this._type === type) {
	            return Promise.resolve(void 0);
	        }
	        this._type = type;
	        // no-op until supported.
	        this._propertyChanged.emit('type');
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Initialize the session.
	     *
	     * #### Notes
	     * If a server session exists on the current path, we will connect to it.
	     * If preferences include disabling `canStart` or `shouldStart`, no
	     * server session will be started.
	     * If a kernel id is given, we attempt to start a session with that id.
	     * If a default kernel is available, we connect to it.
	     * Otherwise we ask the user to select a kernel.
	     */
	    ClientSession.prototype.initialize = function () {
	        var _this = this;
	        if (this._initializing) {
	            return this._ready.promise;
	        }
	        this._initializing = true;
	        var manager = this.manager;
	        return manager.ready.then(function () {
	            var model = algorithm_1.find(manager.running(), function (item) {
	                return item.notebook.path === _this._path;
	            });
	            if (!model) {
	                return;
	            }
	            return manager.connectTo(model.id).then(function (session) {
	                _this._handleNewSession(session);
	            }).catch(function (err) {
	                _this._handleSessionError(err);
	            });
	        }).then(function () {
	            return _this._startIfNecessary();
	        }).then(function () {
	            _this._isReady = true;
	            _this._ready.resolve(void 0);
	        });
	    };
	    /**
	     * Start the session if necessary.
	     */
	    ClientSession.prototype._startIfNecessary = function () {
	        var _this = this;
	        var preference = this.kernelPreference;
	        if (this.isDisposed ||
	            this.kernel || preference.shouldStart === false ||
	            preference.canStart === false) {
	            return Promise.resolve(void 0);
	        }
	        // Try to use an existing kernel.
	        if (preference.id) {
	            return this._changeKernel({ id: preference.id }).then(function () { return void 0; }, function () { return _this._selectKernel(); });
	        }
	        var name = ClientSession.getDefaultKernel({
	            specs: this.manager.specs,
	            sessions: this.manager.running(),
	            preference: preference
	        });
	        if (name) {
	            return this._changeKernel({ name: name }).then(function () { return void 0; }, function () { return _this._selectKernel(); });
	        }
	        return this._selectKernel();
	    };
	    /**
	     * Change the kernel.
	     */
	    ClientSession.prototype._changeKernel = function (options) {
	        if (this.isDisposed) {
	            return Promise.resolve(void 0);
	        }
	        var session = this._session;
	        if (session) {
	            return session.changeKernel(options);
	        }
	        else {
	            return this._startSession(options);
	        }
	    };
	    /**
	     * Select a kernel.
	     */
	    ClientSession.prototype._selectKernel = function () {
	        var _this = this;
	        if (this.isDisposed) {
	            return Promise.resolve(void 0);
	        }
	        return Private.selectKernel(this).then(function (model) {
	            if (_this.isDisposed || model === void 0) {
	                return;
	            }
	            if (model === null && _this._session) {
	                return _this.shutdown();
	            }
	            return _this._changeKernel(model).then(function () { return void 0; });
	        }).then(function () { return void 0; });
	    };
	    /**
	     * Start a session and set up its signals.
	     */
	    ClientSession.prototype._startSession = function (model) {
	        var _this = this;
	        if (this.isDisposed) {
	            return Promise.resolve(void 0);
	        }
	        return this.manager.startNew({
	            path: this._path,
	            kernelName: model.name,
	            kernelId: model.id
	        }).then(function (session) { return _this._handleNewSession(session); })
	            .catch(function (err) { return _this._handleSessionError(err); });
	    };
	    /**
	     * Handle a new session object.
	     */
	    ClientSession.prototype._handleNewSession = function (session) {
	        if (this.isDisposed) {
	            return null;
	        }
	        if (this._session) {
	            this._session.dispose();
	        }
	        this._session = session;
	        this._onPathChanged(session, session.path);
	        session.terminated.connect(this._onTerminated, this);
	        session.pathChanged.connect(this._onPathChanged, this);
	        session.kernelChanged.connect(this._onKernelChanged, this);
	        session.statusChanged.connect(this._onStatusChanged, this);
	        session.iopubMessage.connect(this._onIopubMessage, this);
	        session.unhandledMessage.connect(this._onUnhandledMessage, this);
	        this._kernelChanged.emit(session.kernel);
	        this._prevKernelName = session.kernel.name;
	        return session.kernel;
	    };
	    /**
	     * Handle an error in session startup.
	     */
	    ClientSession.prototype._handleSessionError = function (err) {
	        var response = String(err.xhr.response);
	        try {
	            response = JSON.parse(err.xhr.response)['traceback'];
	        }
	        catch (err) {
	            // no-op
	        }
	        var body = document.createElement('pre');
	        body.textContent = response;
	        return _1.showDialog({
	            title: 'Error Starting Kernel',
	            body: body,
	            buttons: [_1.Dialog.okButton()]
	        }).then(function () { return void 0; });
	    };
	    /**
	     * Handle a session termination.
	     */
	    ClientSession.prototype._onTerminated = function () {
	        if (this._session) {
	            this._session.dispose();
	        }
	        this._session = null;
	        this._terminated.emit(void 0);
	    };
	    /**
	     * Handle a change to a session path.
	     */
	    ClientSession.prototype._onPathChanged = function (sender, path) {
	        if (path !== this._path) {
	            this._path = path;
	            this._propertyChanged.emit('path');
	        }
	    };
	    /**
	     * Handle a change to the kernel.
	     */
	    ClientSession.prototype._onKernelChanged = function (sender) {
	        this._kernelChanged.emit(sender.kernel);
	    };
	    /**
	     * Handle a change to the session status.
	     */
	    ClientSession.prototype._onStatusChanged = function () {
	        this._statusChanged.emit(this.status);
	    };
	    /**
	     * Handle an iopub message.
	     */
	    ClientSession.prototype._onIopubMessage = function (sender, message) {
	        this._iopubMessage.emit(message);
	    };
	    /**
	     * Handle an unhandled message.
	     */
	    ClientSession.prototype._onUnhandledMessage = function (sender, message) {
	        this._unhandledMessage.emit(message);
	    };
	    return ClientSession;
	}());
	exports.ClientSession = ClientSession;
	/**
	 * A namespace for `ClientSession` statics.
	 */
	(function (ClientSession) {
	    /**
	     * Restart a kernel if the user accepts the risk.
	     */
	    function restartKernel(kernel) {
	        var restartBtn = _1.Dialog.warnButton({ label: 'RESTART ' });
	        return _1.showDialog({
	            title: 'Restart Kernel?',
	            body: 'Do you want to restart the current kernel? All variables will be lost.',
	            buttons: [_1.Dialog.cancelButton(), restartBtn]
	        }).then(function (result) {
	            if (kernel.isDisposed) {
	                return null;
	            }
	            if (result.accept) {
	                return kernel.restart().then(function () {
	                    return kernel;
	                });
	            }
	            return kernel;
	        });
	    }
	    ClientSession.restartKernel = restartKernel;
	    /**
	     * Get the default kernel name given select options.
	     */
	    function getDefaultKernel(options) {
	        return Private.getDefaultKernel(options);
	    }
	    ClientSession.getDefaultKernel = getDefaultKernel;
	    /**
	     * Populate a kernel dropdown list.
	     *
	     * @param node - The node to populate.
	     *
	     * @param options - The options used to populate the kernels.
	     *
	     * #### Notes
	     * Populates the list with separated sections:
	     *   - Kernels matching the preferred language (display names).
	     *   - "None" signifying no kernel.
	     *   - The remaining kernels.
	     *   - Sessions matching the preferred language (file names).
	     *   - The remaining sessions.
	     * If no preferred language is given or no kernels are found using
	     * the preferred language, the default kernel is used in the first
	     * section.  Kernels are sorted by display name.  Sessions display the
	     * base name of the file with an ellipsis overflow and a tooltip with
	     * the explicit session information.
	     */
	    function populateKernelSelect(node, options) {
	        return Private.populateKernelSelect(node, options);
	    }
	    ClientSession.populateKernelSelect = populateKernelSelect;
	})(ClientSession = exports.ClientSession || (exports.ClientSession = {}));
	exports.ClientSession = ClientSession;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Select a kernel for the session.
	     */
	    function selectKernel(session) {
	        // Create the dialog body.
	        var body = document.createElement('div');
	        var text = document.createElement('label');
	        text.innerHTML = "Select kernel for: \"" + session.name + "\"";
	        body.appendChild(text);
	        var options = getKernelSearch(session);
	        var selector = document.createElement('select');
	        ClientSession.populateKernelSelect(selector, options);
	        body.appendChild(selector);
	        var select = _1.Dialog.okButton({ label: 'SELECT' });
	        return _1.showDialog({
	            title: 'Select Kernel',
	            body: body,
	            buttons: [_1.Dialog.cancelButton(), select]
	        }).then(function (result) {
	            if (!result.accept) {
	                return void 0;
	            }
	            return JSON.parse(selector.value);
	        });
	    }
	    Private.selectKernel = selectKernel;
	    /**
	     * Get the default kernel name given select options.
	     */
	    function getDefaultKernel(options) {
	        var specs = options.specs, preference = options.preference;
	        var name = preference.name, language = preference.language, shouldStart = preference.shouldStart, canStart = preference.canStart;
	        if (shouldStart === false || canStart === false) {
	            return null;
	        }
	        if (!name && !language) {
	            return null;
	        }
	        // Look for an exact match of a spec name.
	        for (var specName in specs.kernelspecs) {
	            if (specName === name) {
	                return name;
	            }
	        }
	        // Bail if there is no language.
	        if (!language) {
	            return null;
	        }
	        // Check for a single kernel matching the language.
	        var matches = [];
	        for (var specName in specs.kernelspecs) {
	            var kernelLanguage = specs.kernelspecs[specName].language;
	            if (language === kernelLanguage) {
	                matches.push(specName);
	            }
	        }
	        if (matches.length === 1) {
	            var specName = matches[0];
	            console.log('No exact match found for ' + specName +
	                ', using kernel ' + specName + ' that matches ' +
	                'language=' + language);
	            return specName;
	        }
	        // No matches found.
	        return null;
	    }
	    Private.getDefaultKernel = getDefaultKernel;
	    /**
	     * Populate a kernel select node for the session.
	     */
	    function populateKernelSelect(node, options) {
	        while (node.firstChild) {
	            node.removeChild(node.firstChild);
	        }
	        var maxLength = 10;
	        var preference = options.preference, sessions = options.sessions, specs = options.specs;
	        var name = preference.name, id = preference.id, language = preference.language, canStart = preference.canStart, shouldStart = preference.shouldStart;
	        if (canStart === false) {
	            node.appendChild(optionForNone());
	            node.value = 'null';
	            node.disabled = true;
	            return;
	        }
	        node.disabled = false;
	        // Create mappings of display names and languages for kernel name.
	        var displayNames = Object.create(null);
	        var languages = Object.create(null);
	        for (var name_1 in specs.kernelspecs) {
	            var spec = specs.kernelspecs[name_1];
	            displayNames[name_1] = spec.display_name;
	            maxLength = Math.max(maxLength, displayNames[name_1].length);
	            languages[name_1] = spec.language;
	        }
	        // Handle a kernel by name.
	        var names = [];
	        if (name && name in specs.kernelspecs) {
	            names.push(name);
	        }
	        // Then look by language.
	        if (language) {
	            for (var specName in specs.kernelspecs) {
	                if (name !== specName && languages[specName] === language) {
	                    names.push(name);
	                }
	            }
	        }
	        // Use the default kernel if no kernels were found.
	        if (!names.length) {
	            names.push(specs.default);
	        }
	        // Handle a preferred kernels in order of display name.
	        var preferred = document.createElement('optgroup');
	        preferred.label = 'Start Preferred Kernel';
	        names.sort(function (a, b) { return displayNames[a].localeCompare(displayNames[b]); });
	        for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
	            var name_2 = names_1[_i];
	            preferred.appendChild(optionForName(name_2, displayNames[name_2]));
	        }
	        if (preferred.firstChild) {
	            node.appendChild(preferred);
	        }
	        // Add an option for no kernel
	        node.appendChild(optionForNone());
	        var other = document.createElement('optgroup');
	        other.label = 'Start Other Kernel';
	        // Add the rest of the kernel names in alphabetical order.
	        var otherNames = [];
	        for (var specName in specs.kernelspecs) {
	            if (names.indexOf(specName) !== -1) {
	                continue;
	            }
	            otherNames.push(specName);
	        }
	        otherNames.sort(function (a, b) { return displayNames[a].localeCompare(displayNames[b]); });
	        for (var _a = 0, otherNames_1 = otherNames; _a < otherNames_1.length; _a++) {
	            var otherName = otherNames_1[_a];
	            other.appendChild(optionForName(otherName, displayNames[otherName]));
	        }
	        // Add a separator option if there were any other names.
	        if (otherNames.length) {
	            node.appendChild(other);
	        }
	        // Handle the default value.
	        if (shouldStart === false) {
	            node.value = 'null';
	        }
	        else {
	            node.selectedIndex = 0;
	        }
	        // Bail if there are no sessions.
	        if (!sessions) {
	            return;
	        }
	        // Add the sessions using the preferred language first.
	        var matchingSessions = [];
	        var otherSessions = [];
	        algorithm_1.each(sessions, function (session) {
	            if (language &&
	                languages[session.kernel.name] === language &&
	                session.kernel.id !== id) {
	                matchingSessions.push(session);
	            }
	            else if (session.kernel.id !== id) {
	                otherSessions.push(session);
	            }
	        });
	        var matching = document.createElement('optgroup');
	        matching.label = 'Use Kernel from Preferred Session';
	        node.appendChild(matching);
	        if (matchingSessions.length) {
	            matchingSessions.sort(function (a, b) {
	                return a.notebook.path.localeCompare(b.notebook.path);
	            });
	            algorithm_1.each(matchingSessions, function (session) {
	                var name = displayNames[session.kernel.name];
	                matching.appendChild(optionForSession(session, name, maxLength));
	            });
	        }
	        var otherSessionsNode = document.createElement('optgroup');
	        otherSessionsNode.label = 'Use Kernel from Other Session';
	        node.appendChild(otherSessionsNode);
	        if (otherSessions.length) {
	            otherSessions.sort(function (a, b) {
	                return a.notebook.path.localeCompare(b.notebook.path);
	            });
	            algorithm_1.each(otherSessions, function (session) {
	                var name = displayNames[session.kernel.name] || session.kernel.name;
	                otherSessionsNode.appendChild(optionForSession(session, name, maxLength));
	            });
	        }
	    }
	    Private.populateKernelSelect = populateKernelSelect;
	    /**
	     * Get the kernel search options given a client session and sesion manager.
	     */
	    function getKernelSearch(session) {
	        return {
	            specs: session.manager.specs,
	            sessions: session.manager.running(),
	            preference: session.kernelPreference
	        };
	    }
	    /**
	     * Create an option element for a kernel name.
	     */
	    function optionForName(name, displayName) {
	        var option = document.createElement('option');
	        option.text = displayName;
	        option.value = JSON.stringify({ name: name });
	        return option;
	    }
	    /**
	     * Create an option for no kernel.
	     */
	    function optionForNone() {
	        var group = document.createElement('optgroup');
	        group.label = 'Use No Kernel';
	        var option = document.createElement('option');
	        option.text = 'No Kernel';
	        option.value = 'null';
	        group.appendChild(option);
	        return group;
	    }
	    /**
	     * Create an option element for a session.
	     */
	    function optionForSession(session, displayName, maxLength) {
	        var option = document.createElement('option');
	        var sessionName = session.notebook.path.split('/').pop();
	        var CONSOLE_REGEX = /^console-(\d)+-[0-9a-f]+$/;
	        if (CONSOLE_REGEX.test(sessionName)) {
	            sessionName = "Console " + sessionName.match(CONSOLE_REGEX)[1];
	        }
	        if (sessionName.length > maxLength) {
	            sessionName = sessionName.slice(0, maxLength - 3) + '...';
	        }
	        option.text = sessionName;
	        option.value = JSON.stringify({ id: session.kernel.id });
	        option.title = "Path: " + session.notebook.path + "\n" +
	            ("Kernel Name: " + displayName + "\n") +
	            ("Kernel Id: " + session.kernel.id);
	        return option;
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/clientsession.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/index.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/activitymonitor.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/nbformat.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablejson.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablemap.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablestring.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablevector.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/path.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/time.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/undoablevector.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/url.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/uuid.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/vector.js'));
	__export(__jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/modeldb.js'));
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/activitymonitor.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/activitymonitor.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	/**
	 * A class that monitors activity on a signal.
	 */
	var ActivityMonitor = (function () {
	    /**
	     * Construct a new activity monitor.
	     */
	    function ActivityMonitor(options) {
	        this._timer = -1;
	        this._timeout = -1;
	        this._sender = null;
	        this._args = null;
	        this._isDisposed = false;
	        this._activityStopped = new signaling_1.Signal(this);
	        options.signal.connect(this._onSignalFired, this);
	        this._timeout = options.timeout || 1000;
	    }
	    Object.defineProperty(ActivityMonitor.prototype, "activityStopped", {
	        /**
	         * A signal emitted when activity has ceased.
	         */
	        get: function () {
	            return this._activityStopped;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ActivityMonitor.prototype, "timeout", {
	        /**
	         * The timeout associated with the monitor, in milliseconds.
	         */
	        get: function () {
	            return this._timeout;
	        },
	        set: function (value) {
	            this._timeout = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ActivityMonitor.prototype, "isDisposed", {
	        /**
	         * Test whether the monitor has been disposed.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the activity monitor.
	     */
	    ActivityMonitor.prototype.dispose = function () {
	        if (this._isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * A signal handler for the monitored signal.
	     */
	    ActivityMonitor.prototype._onSignalFired = function (sender, args) {
	        var _this = this;
	        clearTimeout(this._timer);
	        this._sender = sender;
	        this._args = args;
	        this._timer = window.setTimeout(function () {
	            _this._activityStopped.emit({
	                sender: _this._sender,
	                args: _this._args
	            });
	            _this._sender = null;
	            _this._args = null;
	        }, this._timeout);
	    };
	    return ActivityMonitor;
	}());
	exports.ActivityMonitor = ActivityMonitor;
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/activitymonitor.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/nbformat.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/nbformat.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	// Notebook format interfaces
	// https://nbformat.readthedocs.io/en/latest/format_description.html
	// https://github.com/jupyter/nbformat/blob/master/nbformat/v4/nbformat.v4.schema.json
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	/**
	 * A namespace for nbformat interfaces.
	 */
	var nbformat;
	(function (nbformat) {
	    /**
	     * The major version of the notebook format.
	     */
	    nbformat.MAJOR_VERSION = 4;
	    /**
	     * The minor version of the notebook format.
	     */
	    nbformat.MINOR_VERSION = 2;
	    /**
	     * Validate a mime type/value pair.
	     *
	     * @param type - The mimetype name.
	     *
	     * @param value - The value associated with the type.
	     *
	     * @returns Whether the type/value pair are valid.
	     */
	    function validateMimeValue(type, value) {
	        // Check if "application/json" or "application/foo+json"
	        var jsonTest = /^application\/(.*?)+\+json$/;
	        var isJSONType = type === 'application/json' || jsonTest.test(type);
	        var isString = function (x) {
	            return Object.prototype.toString.call(x) === '[object String]';
	        };
	        // If it is an array, make sure if is not a JSON type and it is an
	        // array of strings.
	        if (Array.isArray(value)) {
	            if (isJSONType) {
	                return false;
	            }
	            var valid_1 = true;
	            value.forEach(function (v) {
	                if (!isString(v)) {
	                    valid_1 = false;
	                }
	            });
	            return valid_1;
	        }
	        // If it is a string, make sure we are not a JSON type.
	        if (isString(value)) {
	            return !isJSONType;
	        }
	        // It is not a string, make sure it is a JSON type.
	        if (!isJSONType) {
	            return false;
	        }
	        // It is a JSON type, make sure it is a valid JSON object.
	        return coreutils_1.JSONExt.isObject(value);
	    }
	    nbformat.validateMimeValue = validateMimeValue;
	    /**
	     * Test whether a cell is a raw cell.
	     */
	    function isRaw(cell) {
	        return cell.cell_type === 'raw';
	    }
	    nbformat.isRaw = isRaw;
	    /**
	     * Test whether a cell is a markdown cell.
	     */
	    function isMarkdown(cell) {
	        return cell.cell_type === 'markdown';
	    }
	    nbformat.isMarkdown = isMarkdown;
	    /**
	     * Test whether a cell is a code cell.
	     */
	    function isCode(cell) {
	        return cell.cell_type === 'code';
	    }
	    nbformat.isCode = isCode;
	    /**
	     * Test whether an output is an execute result.
	     */
	    function isExecuteResult(output) {
	        return output.output_type === 'execute_result';
	    }
	    nbformat.isExecuteResult = isExecuteResult;
	    /**
	     * Test whether an output is from display data.
	     */
	    function isDisplayData(output) {
	        return output.output_type === 'display_data';
	    }
	    nbformat.isDisplayData = isDisplayData;
	    /**
	     * Test whether an output is from a stream.
	     */
	    function isStream(output) {
	        return output.output_type === 'stream';
	    }
	    nbformat.isStream = isStream;
	    /**
	     * Test whether an output is from a stream.
	     */
	    function isError(output) {
	        return output.output_type === 'error';
	    }
	    nbformat.isError = isError;
	})(nbformat = exports.nbformat || (exports.nbformat = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/nbformat.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablejson.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/observablejson.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var messaging_1 = __jupyter_require__('@phosphor/messaging@^1.0.0/lib/index.js');
	var observablemap_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablemap.js');
	/**
	 * A concrete Observable map for JSON data.
	 */
	var ObservableJSON = (function (_super) {
	    __extends(ObservableJSON, _super);
	    /**
	     * Construct a new observable JSON object.
	     */
	    function ObservableJSON(options) {
	        if (options === void 0) { options = {}; }
	        return _super.call(this, {
	            itemCmp: coreutils_1.JSONExt.deepEqual,
	            values: options.values
	        }) || this;
	    }
	    /**
	     * Serialize the model to JSON.
	     */
	    ObservableJSON.prototype.toJSON = function () {
	        var out = Object.create(null);
	        for (var _i = 0, _a = this.keys(); _i < _a.length; _i++) {
	            var key = _a[_i];
	            var value = this.get(key);
	            if (coreutils_1.JSONExt.isPrimitive(value)) {
	                out[key] = value;
	            }
	            else {
	                out[key] = JSON.parse(JSON.stringify(value));
	            }
	        }
	        return out;
	    };
	    return ObservableJSON;
	}(observablemap_1.ObservableMap));
	exports.ObservableJSON = ObservableJSON;
	/**
	 * The namespace for ObservableJSON static data.
	 */
	(function (ObservableJSON) {
	    /**
	     * An observable JSON change message.
	     */
	    var ChangeMessage = (function (_super) {
	        __extends(ChangeMessage, _super);
	        /**
	         * Create a new metadata changed message.
	         */
	        function ChangeMessage(args) {
	            var _this = _super.call(this, 'jsonvalue-changed') || this;
	            _this.args = args;
	            return _this;
	        }
	        return ChangeMessage;
	    }(messaging_1.Message));
	    ObservableJSON.ChangeMessage = ChangeMessage;
	})(ObservableJSON = exports.ObservableJSON || (exports.ObservableJSON = {}));
	exports.ObservableJSON = ObservableJSON;
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablejson.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablemap.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/observablemap.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	/**
	 * A concrete implementation of IObservbleMap<T>.
	 */
	var ObservableMap = (function () {
	    /**
	     * Construct a new observable map.
	     */
	    function ObservableMap(options) {
	        if (options === void 0) { options = {}; }
	        this._map = new Map();
	        this._changed = new signaling_1.Signal(this);
	        this._itemCmp = options.itemCmp || Private.itemCmp;
	        if (options.values) {
	            for (var key in options.values) {
	                this._map.set(key, options.values[key]);
	            }
	        }
	    }
	    Object.defineProperty(ObservableMap.prototype, "type", {
	        /**
	         * The type of the Observable.
	         */
	        get: function () {
	            return 'Map';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableMap.prototype, "changed", {
	        /**
	         * A signal emitted when the map has changed.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableMap.prototype, "isDisposed", {
	        /**
	         * Whether this map has been disposed.
	         */
	        get: function () {
	            return this._map === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableMap.prototype, "size", {
	        /**
	         * The number of key-value pairs in the map.
	         */
	        get: function () {
	            return this._map.size;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Set a key-value pair in the map
	     *
	     * @param key - The key to set.
	     *
	     * @param value - The value for the key.
	     *
	     * @returns the old value for the key, or undefined
	     *   if that did not exist.
	     *
	     * @throws if the new value is undefined.
	     *
	     * #### Notes
	     * This is a no-op if the value does not change.
	     */
	    ObservableMap.prototype.set = function (key, value) {
	        var oldVal = this._map.get(key);
	        if (value === undefined) {
	            throw Error('Cannot set an undefined value, use remove');
	        }
	        // Bail if the value does not change.
	        var itemCmp = this._itemCmp;
	        if (oldVal !== undefined && itemCmp(oldVal, value)) {
	            return;
	        }
	        this._map.set(key, value);
	        this._changed.emit({
	            type: oldVal ? 'change' : 'add',
	            key: key,
	            oldValue: oldVal,
	            newValue: value
	        });
	        return oldVal;
	    };
	    /**
	     * Get a value for a given key.
	     *
	     * @param key - the key.
	     *
	     * @returns the value for that key.
	     */
	    ObservableMap.prototype.get = function (key) {
	        return this._map.get(key);
	    };
	    /**
	     * Check whether the map has a key.
	     *
	     * @param key - the key to check.
	     *
	     * @returns `true` if the map has the key, `false` otherwise.
	     */
	    ObservableMap.prototype.has = function (key) {
	        return this._map.has(key);
	    };
	    /**
	     * Get a list of the keys in the map.
	     *
	     * @returns - a list of keys.
	     */
	    ObservableMap.prototype.keys = function () {
	        var keyList = [];
	        this._map.forEach(function (v, k) {
	            keyList.push(k);
	        });
	        return keyList;
	    };
	    /**
	     * Get a list of the values in the map.
	     *
	     * @returns - a list of values.
	     */
	    ObservableMap.prototype.values = function () {
	        var valList = [];
	        this._map.forEach(function (v, k) {
	            valList.push(v);
	        });
	        return valList;
	    };
	    /**
	     * Remove a key from the map
	     *
	     * @param key - the key to remove.
	     *
	     * @returns the value of the given key,
	     *   or undefined if that does not exist.
	     */
	    ObservableMap.prototype.delete = function (key) {
	        var oldVal = this._map.get(key);
	        this._map.delete(key);
	        this._changed.emit({
	            type: 'remove',
	            key: key,
	            oldValue: oldVal,
	            newValue: undefined
	        });
	        return oldVal;
	    };
	    /**
	     * Set the ObservableMap to an empty map.
	     */
	    ObservableMap.prototype.clear = function () {
	        // Delete one by one to emit the correct signals.
	        var keyList = this.keys();
	        for (var i = 0; i < keyList.length; i++) {
	            this.delete(keyList[i]);
	        }
	    };
	    /**
	     * Dispose of the resources held by the map.
	     */
	    ObservableMap.prototype.dispose = function () {
	        if (this._map === null) {
	            return;
	        }
	        signaling_1.Signal.clearData(this);
	        this._map.clear();
	        this._map = null;
	    };
	    return ObservableMap;
	}());
	exports.ObservableMap = ObservableMap;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The default strict equality item comparator.
	     */
	    function itemCmp(first, second) {
	        return first === second;
	    }
	    Private.itemCmp = itemCmp;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablemap.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablestring.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/observablestring.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	/**
	 * A concrete implementation of [[IObservableString]]
	 */
	var ObservableString = (function () {
	    /**
	     * Construct a new observable string.
	     */
	    function ObservableString(initialText) {
	        if (initialText === void 0) { initialText = ''; }
	        this._text = '';
	        this._isDisposed = false;
	        this._changed = new signaling_1.Signal(this);
	        this._text = initialText;
	    }
	    Object.defineProperty(ObservableString.prototype, "type", {
	        /**
	         * The type of the Observable.
	         */
	        get: function () {
	            return 'String';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableString.prototype, "changed", {
	        /**
	         * A signal emitted when the string has changed.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableString.prototype, "text", {
	        /**
	         * Get the value of the string.
	         */
	        get: function () {
	            return this._text;
	        },
	        /**
	         * Set the value of the string.
	         */
	        set: function (value) {
	            if (value.length === this._text.length && value === this._text) {
	                return;
	            }
	            this._text = value;
	            this._changed.emit({
	                type: 'set',
	                start: 0,
	                end: value.length,
	                value: value
	            });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Insert a substring.
	     *
	     * @param index - The starting index.
	     *
	     * @param text - The substring to insert.
	     */
	    ObservableString.prototype.insert = function (index, text) {
	        this._text = this._text.slice(0, index) +
	            text +
	            this._text.slice(index);
	        this._changed.emit({
	            type: 'insert',
	            start: index,
	            end: index + text.length,
	            value: text
	        });
	    };
	    /**
	     * Remove a substring.
	     *
	     * @param start - The starting index.
	     *
	     * @param end - The ending index.
	     */
	    ObservableString.prototype.remove = function (start, end) {
	        var oldValue = this._text.slice(start, end);
	        this._text = this._text.slice(0, start) +
	            this._text.slice(end);
	        this._changed.emit({
	            type: 'remove',
	            start: start,
	            end: end,
	            value: oldValue
	        });
	    };
	    /**
	     * Set the ObservableString to an empty string.
	     */
	    ObservableString.prototype.clear = function () {
	        this.text = '';
	    };
	    Object.defineProperty(ObservableString.prototype, "isDisposed", {
	        /**
	         * Test whether the string has been disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the string.
	     */
	    ObservableString.prototype.dispose = function () {
	        if (this._isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        signaling_1.Signal.clearData(this);
	        this.clear();
	    };
	    return ObservableString;
	}());
	exports.ObservableString = ObservableString;
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablestring.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablevector.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/observablevector.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var vector_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/vector.js');
	/**
	 * A concrete implementation of [[IObservableVector]].
	 */
	var ObservableVector = (function (_super) {
	    __extends(ObservableVector, _super);
	    /**
	     * Construct a new observable map.
	     */
	    function ObservableVector(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, options.values || []) || this;
	        _this._isDisposed = false;
	        _this._changed = new signaling_1.Signal(_this);
	        _this._itemCmp = options.itemCmp || Private.itemCmp;
	        return _this;
	    }
	    Object.defineProperty(ObservableVector.prototype, "type", {
	        /**
	         * The type of the Observable.
	         */
	        get: function () {
	            return 'Vector';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableVector.prototype, "changed", {
	        /**
	         * A signal emitted when the vector has changed.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableVector.prototype, "isDisposed", {
	        /**
	         * Test whether the vector has been disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the vector.
	     */
	    ObservableVector.prototype.dispose = function () {
	        if (this._isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        signaling_1.Signal.clearData(this);
	        this.clear();
	    };
	    /**
	     * Set the value at the specified index.
	     *
	     * @param index - The positive integer index of interest.
	     *
	     * @param value - The value to set at the specified index.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * No changes.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral or out of range.
	     */
	    ObservableVector.prototype.set = function (index, value) {
	        var oldValues = [this.at(index)];
	        if (value === undefined) {
	            value = null;
	        }
	        // Bail if the value does not change.
	        var itemCmp = this._itemCmp;
	        if (itemCmp(oldValues[0], value)) {
	            return;
	        }
	        _super.prototype.set.call(this, index, value);
	        this._changed.emit({
	            type: 'set',
	            oldIndex: index,
	            newIndex: index,
	            oldValues: oldValues,
	            newValues: [value]
	        });
	    };
	    /**
	     * Add a value to the back of the vector.
	     *
	     * @param value - The value to add to the back of the vector.
	     *
	     * @returns The new length of the vector.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * No changes.
	     */
	    ObservableVector.prototype.pushBack = function (value) {
	        var num = _super.prototype.pushBack.call(this, value);
	        // Bail if in the constructor.
	        if (!this._changed) {
	            return;
	        }
	        this._changed.emit({
	            type: 'add',
	            oldIndex: -1,
	            newIndex: this.length - 1,
	            oldValues: [],
	            newValues: [value]
	        });
	        return num;
	    };
	    /**
	     * Remove and return the value at the back of the vector.
	     *
	     * @returns The value at the back of the vector, or `undefined` if
	     *   the vector is empty.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * Iterators pointing at the removed value are invalidated.
	     */
	    ObservableVector.prototype.popBack = function () {
	        var value = _super.prototype.popBack.call(this);
	        this._changed.emit({
	            type: 'remove',
	            oldIndex: this.length,
	            newIndex: -1,
	            oldValues: [value],
	            newValues: []
	        });
	        return value;
	    };
	    /**
	     * Insert a value into the vector at a specific index.
	     *
	     * @param index - The index at which to insert the value.
	     *
	     * @param value - The value to set at the specified index.
	     *
	     * @returns The new length of the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * No changes.
	     *
	     * #### Notes
	     * The `index` will be clamped to the bounds of the vector.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    ObservableVector.prototype.insert = function (index, value) {
	        var num = _super.prototype.insert.call(this, index, value);
	        this._changed.emit({
	            type: 'add',
	            oldIndex: -1,
	            newIndex: index,
	            oldValues: [],
	            newValues: [value]
	        });
	        return num;
	    };
	    /**
	     * Remove the first occurrence of a value from the vector.
	     *
	     * @param value - The value of interest.
	     *
	     * @returns The index of the removed value, or `-1` if the value
	     *   is not contained in the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * Iterators pointing at the removed value and beyond are invalidated.
	     */
	    ObservableVector.prototype.remove = function (value) {
	        var itemCmp = this._itemCmp;
	        var index = algorithm_1.ArrayExt.findFirstIndex(algorithm_1.toArray(this), function (item) { return itemCmp(item, value); });
	        this.removeAt(index);
	        return index;
	    };
	    /**
	     * Remove and return the value at a specific index.
	     *
	     * @param index - The index of the value of interest.
	     *
	     * @returns The value at the specified index, or `undefined` if the
	     *   index is out of range.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * Iterators pointing at the removed value and beyond are invalidated.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    ObservableVector.prototype.removeAt = function (index) {
	        var value = _super.prototype.removeAt.call(this, index);
	        this._changed.emit({
	            type: 'remove',
	            oldIndex: index,
	            newIndex: -1,
	            oldValues: [value],
	            newValues: []
	        });
	        return value;
	    };
	    /**
	     * Remove all values from the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * All current iterators are invalidated.
	     */
	    ObservableVector.prototype.clear = function () {
	        var oldValues = algorithm_1.toArray(this);
	        _super.prototype.clear.call(this);
	        this._changed.emit({
	            type: 'remove',
	            oldIndex: 0,
	            newIndex: 0,
	            oldValues: oldValues,
	            newValues: []
	        });
	    };
	    /**
	     * Move a value from one index to another.
	     *
	     * @parm fromIndex - The index of the element to move.
	     *
	     * @param toIndex - The index to move the element to.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * Iterators pointing at the lesser of the `fromIndex` and the `toIndex`
	     * and beyond are invalidated.
	     *
	     * #### Undefined Behavior
	     * A `fromIndex` or a `toIndex` which is non-integral.
	     */
	    ObservableVector.prototype.move = function (fromIndex, toIndex) {
	        if (this.length <= 1 || fromIndex === toIndex) {
	            return;
	        }
	        var value = this.at(fromIndex);
	        var step = fromIndex < toIndex ? 1 : -1;
	        for (var i = fromIndex; i !== toIndex; i += step) {
	            _super.prototype.set.call(this, i, this.at(i + step));
	        }
	        _super.prototype.set.call(this, toIndex, value);
	        var arr = [value];
	        this._changed.emit({
	            type: 'move',
	            oldIndex: fromIndex,
	            newIndex: toIndex,
	            oldValues: arr,
	            newValues: arr
	        });
	    };
	    /**
	     * Push a set of values to the back of the vector.
	     *
	     * @param values - An iterable or array-like set of values to add.
	     *
	     * @returns The new length of the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * No changes.
	     */
	    ObservableVector.prototype.pushAll = function (values) {
	        var _this = this;
	        var newIndex = this.length;
	        var newValues = algorithm_1.toArray(values);
	        algorithm_1.each(newValues, function (value) { _super.prototype.pushBack.call(_this, value); });
	        this._changed.emit({
	            type: 'add',
	            oldIndex: -1,
	            newIndex: newIndex,
	            oldValues: [],
	            newValues: newValues
	        });
	        return this.length;
	    };
	    /**
	     * Insert a set of items into the vector at the specified index.
	     *
	     * @param index - The index at which to insert the values.
	     *
	     * @param values - The values to insert at the specified index.
	     *
	     * @returns The new length of the vector.
	     *
	     * #### Complexity.
	     * Linear.
	     *
	     * #### Iterator Validity
	     * No changes.
	     *
	     * #### Notes
	     * The `index` will be clamped to the bounds of the vector.
	     *
	     * #### Undefined Behavior.
	     * An `index` which is non-integral.
	     */
	    ObservableVector.prototype.insertAll = function (index, values) {
	        var _this = this;
	        var newIndex = index;
	        var newValues = algorithm_1.toArray(values);
	        algorithm_1.each(newValues, function (value) { _super.prototype.insert.call(_this, index++, value); });
	        this._changed.emit({
	            type: 'add',
	            oldIndex: -1,
	            newIndex: newIndex,
	            oldValues: [],
	            newValues: newValues
	        });
	        return this.length;
	    };
	    /**
	     * Remove a range of items from the vector.
	     *
	     * @param startIndex - The start index of the range to remove (inclusive).
	     *
	     * @param endIndex - The end index of the range to remove (exclusive).
	     *
	     * @returns The new length of the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * Iterators pointing to the first removed value and beyond are invalid.
	     *
	     * #### Undefined Behavior
	     * A `startIndex` or `endIndex` which is non-integral.
	     */
	    ObservableVector.prototype.removeRange = function (startIndex, endIndex) {
	        var oldValues = [];
	        for (var i = startIndex; i < endIndex; i++) {
	            oldValues.push(_super.prototype.removeAt.call(this, startIndex));
	        }
	        this._changed.emit({
	            type: 'remove',
	            oldIndex: startIndex,
	            newIndex: -1,
	            oldValues: oldValues,
	            newValues: []
	        });
	        return this.length;
	    };
	    return ObservableVector;
	}(vector_1.Vector));
	exports.ObservableVector = ObservableVector;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The default strict equality item cmp.
	     */
	    function itemCmp(first, second) {
	        return first === second;
	    }
	    Private.itemCmp = itemCmp;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/observablevector.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/vector.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/vector.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	/**
	 * A generic vector data structure.
	 */
	var Vector = (function () {
	    /**
	     * Construct a new vector.
	     *
	     * @param values - The initial values for the vector.
	     */
	    function Vector(values) {
	        var _this = this;
	        this._array = [];
	        if (values) {
	            algorithm_1.each(values, function (value) { _this.pushBack(value); });
	        }
	    }
	    Object.defineProperty(Vector.prototype, "isEmpty", {
	        /**
	         * Test whether the vector is empty.
	         *
	         * @returns `true` if the vector is empty, `false` otherwise.
	         *
	         * #### Notes
	         * This is a read-only property.
	         *
	         * #### Complexity
	         * Constant.
	         *
	         * #### Iterator Validity
	         * No changes.
	         */
	        get: function () {
	            return this._array.length === 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Vector.prototype, "length", {
	        /**
	         * Get the length of the vector.
	         *
	         * @return The number of values in the vector.
	         *
	         * #### Notes
	         * This is a read-only property.
	         *
	         * #### Complexity
	         * Constant.
	         *
	         * #### Iterator Validity
	         * No changes.
	         */
	        get: function () {
	            return this._array.length;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Vector.prototype, "front", {
	        /**
	         * Get the value at the front of the vector.
	         *
	         * @returns The value at the front of the vector, or `undefined` if
	         *   the vector is empty.
	         *
	         * #### Notes
	         * This is a read-only property.
	         *
	         * #### Complexity
	         * Constant.
	         *
	         * #### Iterator Validity
	         * No changes.
	         */
	        get: function () {
	            return this._array[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Vector.prototype, "back", {
	        /**
	         * Get the value at the back of the vector.
	         *
	         * @returns The value at the back of the vector, or `undefined` if
	         *   the vector is empty.
	         *
	         * #### Notes
	         * This is a read-only property.
	         *
	         * #### Complexity
	         * Constant.
	         *
	         * #### Iterator Validity
	         * No changes.
	         */
	        get: function () {
	            return this._array[this._array.length - 1];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the values in the vector.
	     *
	     * @returns A new iterator starting at the front of the vector.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * No changes.
	     */
	    Vector.prototype.iter = function () {
	        return new algorithm_1.ArrayIterator(this._array);
	    };
	    /**
	     * Get the value at the specified index.
	     *
	     * @param index - The positive integer index of interest.
	     *
	     * @returns The value at the specified index.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * No changes.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral or out of range.
	     */
	    Vector.prototype.at = function (index) {
	        return this._array[index];
	    };
	    /**
	     * Set the value at the specified index.
	     *
	     * @param index - The positive integer index of interest.
	     *
	     * @param value - The value to set at the specified index.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * No changes.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral or out of range.
	     */
	    Vector.prototype.set = function (index, value) {
	        this._array[index] = value;
	    };
	    /**
	     * Add a value to the back of the vector.
	     *
	     * @param value - The value to add to the back of the vector.
	     *
	     * @returns The new length of the vector.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * No changes.
	     */
	    Vector.prototype.pushBack = function (value) {
	        return this._array.push(value);
	    };
	    /**
	     * Remove and return the value at the back of the vector.
	     *
	     * @returns The value at the back of the vector, or `undefined` if
	     *   the vector is empty.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * Iterators pointing at the removed value are invalidated.
	     */
	    Vector.prototype.popBack = function () {
	        return this._array.pop();
	    };
	    /**
	     * Insert a value into the vector at a specific index.
	     *
	     * @param index - The index at which to insert the value.
	     *
	     * @param value - The value to set at the specified index.
	     *
	     * @returns The new length of the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * No changes.
	     *
	     * #### Notes
	     * The `index` will be clamped to the bounds of the vector.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    Vector.prototype.insert = function (index, value) {
	        var array = this._array;
	        var n = array.length;
	        index = Math.max(0, Math.min(index, n));
	        for (var i = n; i > index; --i) {
	            array[i] = array[i - 1];
	        }
	        array[index] = value;
	        return n + 1;
	    };
	    /**
	     * Remove the first occurrence of a value from the vector.
	     *
	     * @param value - The value of interest.
	     *
	     * @returns The index of the removed value, or `-1` if the value
	     *   is not contained in the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * Iterators pointing at the removed value and beyond are invalidated.
	     *
	     * #### Notes
	     * Comparison is performed using strict `===` equality.
	     */
	    Vector.prototype.remove = function (value) {
	        var index = this._array.indexOf(value);
	        if (index !== -1)
	            this.removeAt(index);
	        return index;
	    };
	    /**
	     * Remove and return the value at a specific index.
	     *
	     * @param index - The index of the value of interest.
	     *
	     * @returns The value at the specified index, or `undefined` if the
	     *   index is out of range.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * Iterators pointing at the removed value and beyond are invalidated.
	     *
	     * #### Undefined Behavior
	     * An `index` which is non-integral.
	     */
	    Vector.prototype.removeAt = function (index) {
	        var array = this._array;
	        var n = array.length;
	        if (index < 0 || index >= n) {
	            return void 0;
	        }
	        var value = array[index];
	        for (var i = index + 1; i < n; ++i) {
	            array[i - 1] = array[i];
	        }
	        array.length = n - 1;
	        return value;
	    };
	    /**
	     * Remove all values from the vector.
	     *
	     * #### Complexity
	     * Linear.
	     *
	     * #### Iterator Validity
	     * All current iterators are invalidated.
	     */
	    Vector.prototype.clear = function () {
	        this._array.length = 0;
	    };
	    /**
	     * Swap the contents of the vector with the contents of another.
	     *
	     * @param other - The other vector holding the contents to swap.
	     *
	     * #### Complexity
	     * Constant.
	     *
	     * #### Iterator Validity
	     * All current iterators remain valid, but will now point to the
	     * contents of the other vector involved in the swap.
	     */
	    Vector.prototype.swap = function (other) {
	        var array = other._array;
	        other._array = this._array;
	        this._array = array;
	    };
	    return Vector;
	}());
	exports.Vector = Vector;
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/vector.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/path.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/path.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var posix = __jupyter_require__('path-posix@^1.0.0/index.js');
	/**
	 * The namespace for path-related functions.
	 *
	 * Note that Jupyter server paths do not start with a leading slash.
	 */
	var PathExt;
	(function (PathExt) {
	    /**
	     * Join all arguments together and normalize the resulting path.
	     * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown.
	     *
	     * @param paths - The string paths to join.
	     */
	    function join() {
	        var paths = [];
	        for (var _i = 0; _i < arguments.length; _i++) {
	            paths[_i] = arguments[_i];
	        }
	        return removeSlash(posix.join.apply(posix, paths));
	    }
	    PathExt.join = join;
	    /**
	     * Return the last portion of a path. Similar to the Unix basename command.
	     * Often used to extract the file name from a fully qualified path.
	     *
	     * @param path - The path to evaluate.
	     *
	     * @param ext - An extension to remove from the result.
	     */
	    function basename(path, ext) {
	        return posix.basename(path, ext);
	    }
	    PathExt.basename = basename;
	    /**
	     * Get the directory name of a path, similar to the Unix dirname command.
	     *
	     * @param path - The file path.
	     */
	    function dirname(path) {
	        return removeSlash(posix.dirname(path));
	    }
	    PathExt.dirname = dirname;
	    /**
	     * Get the extension of the path.
	     *
	     * @param path - The file path.
	     *
	     * @returns the extension of the file.
	     *
	     * #### Notes
	     * The extension is the string from the last occurence of the `.`
	     * character to end of string in the last portion of the path, inclusive.
	     * If there is no `.` in the last portion of the path, or if the first
	     * character of the basename of path [[basename]] is `.`, then an
	     * empty string is returned.
	     */
	    function extname(path) {
	        return posix.extname(path);
	    }
	    PathExt.extname = extname;
	    /**
	     * Normalize a string path, reducing '..' and '.' parts.
	     * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used.
	     *
	     * @param path - The string path to normalize.
	     */
	    function normalize(path) {
	        return removeSlash(posix.normalize(path));
	    }
	    PathExt.normalize = normalize;
	    /**
	     * Resolve a sequence of paths or path segments into an absolute path.
	     * The root path in the application has no leading slash, so it is removed.
	     *
	     * @param parts - The paths to join.
	     *
	     * #### Notes
	     * The right-most parameter is considered {to}.  Other parameters are considered an array of {from}.
	     *
	     * Starting from leftmost {from} parameter, resolves {to} to an absolute path.
	     *
	     * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory.
	     */
	    function resolve() {
	        var parts = [];
	        for (var _i = 0; _i < arguments.length; _i++) {
	            parts[_i] = arguments[_i];
	        }
	        return removeSlash(posix.resolve.apply(posix, parts));
	    }
	    PathExt.resolve = resolve;
	    /**
	     * Solve the relative path from {from} to {to}.
	     *
	     * @param from - The source path.
	     *
	     * @param to - The target path.
	     *
	     * #### Notes
	     * If from and to each resolve to the same path (after calling
	     * path.resolve() on each), a zero-length string is returned.
	     * If a zero-length string is passed as from or to, `/`
	     * will be used instead of the zero-length strings.
	     */
	    function relative(from, to) {
	        return removeSlash(posix.relative(from, to));
	    }
	    PathExt.relative = relative;
	    /**
	     * Normalize a file extension to be of the type `'.foo'`.
	     *
	     * @param extension - the file extension.
	     *
	     * #### Notes
	     * Adds a leading dot if not present and converts to lower case.
	     */
	    function normalizeExtension(extension) {
	        if (extension.length > 0 && extension.indexOf('.') !== 0) {
	            extension = "." + extension;
	        }
	        return extension;
	    }
	    PathExt.normalizeExtension = normalizeExtension;
	    /**
	     * Remove the leading slash from a path.
	     */
	    function removeSlash(path) {
	        if (path.indexOf('/') === 0) {
	            path = path.slice(1);
	        }
	        return path;
	    }
	})(PathExt = exports.PathExt || (exports.PathExt = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/path.js **/


/** START DEFINE BLOCK for path-posix@1.0.0/index.js **/
jupyter.define('path-posix@1.0.0/index.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	'use strict';
	var util = __jupyter_require__('util@0.10.3/util.js');
	var isString = function (x) {
	  return typeof x === 'string';
	};
	
	
	// resolves . and .. elements in a path array with directory names there
	// must be no slashes or device names (c:\) in the array
	// (so also no leading and trailing slashes - it does not distinguish
	// relative and absolute paths)
	function normalizeArray(parts, allowAboveRoot) {
	  var res = [];
	  for (var i = 0; i < parts.length; i++) {
	    var p = parts[i];
	
	    // ignore empty parts
	    if (!p || p === '.')
	      continue;
	
	    if (p === '..') {
	      if (res.length && res[res.length - 1] !== '..') {
	        res.pop();
	      } else if (allowAboveRoot) {
	        res.push('..');
	      }
	    } else {
	      res.push(p);
	    }
	  }
	
	  return res;
	}
	
	// Split a filename into [root, dir, basename, ext], unix version
	// 'root' is just a slash, or nothing.
	var splitPathRe =
	    /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
	var posix = {};
	
	
	function posixSplitPath(filename) {
	  return splitPathRe.exec(filename).slice(1);
	}
	
	
	// path.resolve([from ...], to)
	// posix version
	posix.resolve = function() {
	  var resolvedPath = '',
	      resolvedAbsolute = false;
	
	  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
	    var path = (i >= 0) ? arguments[i] : process.cwd();
	
	    // Skip empty and invalid entries
	    if (!isString(path)) {
	      throw new TypeError('Arguments to path.resolve must be strings');
	    } else if (!path) {
	      continue;
	    }
	
	    resolvedPath = path + '/' + resolvedPath;
	    resolvedAbsolute = path.charAt(0) === '/';
	  }
	
	  // At this point the path should be resolved to a full absolute path, but
	  // handle relative paths to be safe (might happen when process.cwd() fails)
	
	  // Normalize the path
	  resolvedPath = normalizeArray(resolvedPath.split('/'),
	                                !resolvedAbsolute).join('/');
	
	  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
	};
	
	// path.normalize(path)
	// posix version
	posix.normalize = function(path) {
	  var isAbsolute = posix.isAbsolute(path),
	      trailingSlash = path.substr(-1) === '/';
	
	  // Normalize the path
	  path = normalizeArray(path.split('/'), !isAbsolute).join('/');
	
	  if (!path && !isAbsolute) {
	    path = '.';
	  }
	  if (path && trailingSlash) {
	    path += '/';
	  }
	
	  return (isAbsolute ? '/' : '') + path;
	};
	
	// posix version
	posix.isAbsolute = function(path) {
	  return path.charAt(0) === '/';
	};
	
	// posix version
	posix.join = function() {
	  var path = '';
	  for (var i = 0; i < arguments.length; i++) {
	    var segment = arguments[i];
	    if (!isString(segment)) {
	      throw new TypeError('Arguments to path.join must be strings');
	    }
	    if (segment) {
	      if (!path) {
	        path += segment;
	      } else {
	        path += '/' + segment;
	      }
	    }
	  }
	  return posix.normalize(path);
	};
	
	
	// path.relative(from, to)
	// posix version
	posix.relative = function(from, to) {
	  from = posix.resolve(from).substr(1);
	  to = posix.resolve(to).substr(1);
	
	  function trim(arr) {
	    var start = 0;
	    for (; start < arr.length; start++) {
	      if (arr[start] !== '') break;
	    }
	
	    var end = arr.length - 1;
	    for (; end >= 0; end--) {
	      if (arr[end] !== '') break;
	    }
	
	    if (start > end) return [];
	    return arr.slice(start, end + 1);
	  }
	
	  var fromParts = trim(from.split('/'));
	  var toParts = trim(to.split('/'));
	
	  var length = Math.min(fromParts.length, toParts.length);
	  var samePartsLength = length;
	  for (var i = 0; i < length; i++) {
	    if (fromParts[i] !== toParts[i]) {
	      samePartsLength = i;
	      break;
	    }
	  }
	
	  var outputParts = [];
	  for (var i = samePartsLength; i < fromParts.length; i++) {
	    outputParts.push('..');
	  }
	
	  outputParts = outputParts.concat(toParts.slice(samePartsLength));
	
	  return outputParts.join('/');
	};
	
	
	posix._makeLong = function(path) {
	  return path;
	};
	
	
	posix.dirname = function(path) {
	  var result = posixSplitPath(path),
	      root = result[0],
	      dir = result[1];
	
	  if (!root && !dir) {
	    // No dirname whatsoever
	    return '.';
	  }
	
	  if (dir) {
	    // It has a dirname, strip trailing slash
	    dir = dir.substr(0, dir.length - 1);
	  }
	
	  return root + dir;
	};
	
	
	posix.basename = function(path, ext) {
	  var f = posixSplitPath(path)[2];
	  // TODO: make this comparison case-insensitive on windows?
	  if (ext && f.substr(-1 * ext.length) === ext) {
	    f = f.substr(0, f.length - ext.length);
	  }
	  return f;
	};
	
	
	posix.extname = function(path) {
	  return posixSplitPath(path)[3];
	};
	
	
	posix.format = function(pathObject) {
	  if (!util.isObject(pathObject)) {
	    throw new TypeError(
	        "Parameter 'pathObject' must be an object, not " + typeof pathObject
	    );
	  }
	
	  var root = pathObject.root || '';
	
	  if (!isString(root)) {
	    throw new TypeError(
	        "'pathObject.root' must be a string or undefined, not " +
	        typeof pathObject.root
	    );
	  }
	
	  var dir = pathObject.dir ? pathObject.dir + posix.sep : '';
	  var base = pathObject.base || '';
	  return dir + base;
	};
	
	
	posix.parse = function(pathString) {
	  if (!isString(pathString)) {
	    throw new TypeError(
	        "Parameter 'pathString' must be a string, not " + typeof pathString
	    );
	  }
	  var allParts = posixSplitPath(pathString);
	  if (!allParts || allParts.length !== 4) {
	    throw new TypeError("Invalid path '" + pathString + "'");
	  }
	  allParts[1] = allParts[1] || '';
	  allParts[2] = allParts[2] || '';
	  allParts[3] = allParts[3] || '';
	
	  return {
	    root: allParts[0],
	    dir: allParts[0] + allParts[1].slice(0, allParts[1].length - 1),
	    base: allParts[2],
	    ext: allParts[3],
	    name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
	  };
	};
	
	
	posix.sep = '/';
	posix.delimiter = ':';
	
	  module.exports = posix;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('process@0.11.10/browser.js')))
})
/** END DEFINE BLOCK for path-posix@1.0.0/index.js **/


/** START DEFINE BLOCK for util@0.10.3/util.js **/
jupyter.define('util@0.10.3/util.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	var formatRegExp = /%[sdj%]/g;
	exports.format = function(f) {
	  if (!isString(f)) {
	    var objects = [];
	    for (var i = 0; i < arguments.length; i++) {
	      objects.push(inspect(arguments[i]));
	    }
	    return objects.join(' ');
	  }
	
	  var i = 1;
	  var args = arguments;
	  var len = args.length;
	  var str = String(f).replace(formatRegExp, function(x) {
	    if (x === '%%') return '%';
	    if (i >= len) return x;
	    switch (x) {
	      case '%s': return String(args[i++]);
	      case '%d': return Number(args[i++]);
	      case '%j':
	        try {
	          return JSON.stringify(args[i++]);
	        } catch (_) {
	          return '[Circular]';
	        }
	      default:
	        return x;
	    }
	  });
	  for (var x = args[i]; i < len; x = args[++i]) {
	    if (isNull(x) || !isObject(x)) {
	      str += ' ' + x;
	    } else {
	      str += ' ' + inspect(x);
	    }
	  }
	  return str;
	};
	
	
	// Mark that a method should not be used.
	// Returns a modified function which warns once by default.
	// If --no-deprecation is set, then it is a no-op.
	exports.deprecate = function(fn, msg) {
	  // Allow for deprecating things in the process of starting up.
	  if (isUndefined(global.process)) {
	    return function() {
	      return exports.deprecate(fn, msg).apply(this, arguments);
	    };
	  }
	
	  if (process.noDeprecation === true) {
	    return fn;
	  }
	
	  var warned = false;
	  function deprecated() {
	    if (!warned) {
	      if (process.throwDeprecation) {
	        throw new Error(msg);
	      } else if (process.traceDeprecation) {
	        console.trace(msg);
	      } else {
	        console.error(msg);
	      }
	      warned = true;
	    }
	    return fn.apply(this, arguments);
	  }
	
	  return deprecated;
	};
	
	
	var debugs = {};
	var debugEnviron;
	exports.debuglog = function(set) {
	  if (isUndefined(debugEnviron))
	    debugEnviron = process.env.NODE_DEBUG || '';
	  set = set.toUpperCase();
	  if (!debugs[set]) {
	    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
	      var pid = process.pid;
	      debugs[set] = function() {
	        var msg = exports.format.apply(exports, arguments);
	        console.error('%s %d: %s', set, pid, msg);
	      };
	    } else {
	      debugs[set] = function() {};
	    }
	  }
	  return debugs[set];
	};
	
	
	/**
	 * Echos the value of a value. Trys to print the value out
	 * in the best way possible given the different types.
	 *
	 * @param {Object} obj The object to print out.
	 * @param {Object} opts Optional options object that alters the output.
	 */
	/* legacy: obj, showHidden, depth, colors*/
	function inspect(obj, opts) {
	  // default options
	  var ctx = {
	    seen: [],
	    stylize: stylizeNoColor
	  };
	  // legacy...
	  if (arguments.length >= 3) ctx.depth = arguments[2];
	  if (arguments.length >= 4) ctx.colors = arguments[3];
	  if (isBoolean(opts)) {
	    // legacy...
	    ctx.showHidden = opts;
	  } else if (opts) {
	    // got an "options" object
	    exports._extend(ctx, opts);
	  }
	  // set default options
	  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
	  if (isUndefined(ctx.depth)) ctx.depth = 2;
	  if (isUndefined(ctx.colors)) ctx.colors = false;
	  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
	  if (ctx.colors) ctx.stylize = stylizeWithColor;
	  return formatValue(ctx, obj, ctx.depth);
	}
	exports.inspect = inspect;
	
	
	// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
	inspect.colors = {
	  'bold' : [1, 22],
	  'italic' : [3, 23],
	  'underline' : [4, 24],
	  'inverse' : [7, 27],
	  'white' : [37, 39],
	  'grey' : [90, 39],
	  'black' : [30, 39],
	  'blue' : [34, 39],
	  'cyan' : [36, 39],
	  'green' : [32, 39],
	  'magenta' : [35, 39],
	  'red' : [31, 39],
	  'yellow' : [33, 39]
	};
	
	// Don't use 'blue' not visible on cmd.exe
	inspect.styles = {
	  'special': 'cyan',
	  'number': 'yellow',
	  'boolean': 'yellow',
	  'undefined': 'grey',
	  'null': 'bold',
	  'string': 'green',
	  'date': 'magenta',
	  // "name": intentionally not styling
	  'regexp': 'red'
	};
	
	
	function stylizeWithColor(str, styleType) {
	  var style = inspect.styles[styleType];
	
	  if (style) {
	    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
	           '\u001b[' + inspect.colors[style][1] + 'm';
	  } else {
	    return str;
	  }
	}
	
	
	function stylizeNoColor(str, styleType) {
	  return str;
	}
	
	
	function arrayToHash(array) {
	  var hash = {};
	
	  array.forEach(function(val, idx) {
	    hash[val] = true;
	  });
	
	  return hash;
	}
	
	
	function formatValue(ctx, value, recurseTimes) {
	  // Provide a hook for user-specified inspect functions.
	  // Check that value is an object with an inspect function on it
	  if (ctx.customInspect &&
	      value &&
	      isFunction(value.inspect) &&
	      // Filter out the util module, it's inspect function is special
	      value.inspect !== exports.inspect &&
	      // Also filter out any prototype objects using the circular check.
	      !(value.constructor && value.constructor.prototype === value)) {
	    var ret = value.inspect(recurseTimes, ctx);
	    if (!isString(ret)) {
	      ret = formatValue(ctx, ret, recurseTimes);
	    }
	    return ret;
	  }
	
	  // Primitive types cannot have properties
	  var primitive = formatPrimitive(ctx, value);
	  if (primitive) {
	    return primitive;
	  }
	
	  // Look up the keys of the object.
	  var keys = Object.keys(value);
	  var visibleKeys = arrayToHash(keys);
	
	  if (ctx.showHidden) {
	    keys = Object.getOwnPropertyNames(value);
	  }
	
	  // IE doesn't make error fields non-enumerable
	  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
	  if (isError(value)
	      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
	    return formatError(value);
	  }
	
	  // Some type of object without properties can be shortcutted.
	  if (keys.length === 0) {
	    if (isFunction(value)) {
	      var name = value.name ? ': ' + value.name : '';
	      return ctx.stylize('[Function' + name + ']', 'special');
	    }
	    if (isRegExp(value)) {
	      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
	    }
	    if (isDate(value)) {
	      return ctx.stylize(Date.prototype.toString.call(value), 'date');
	    }
	    if (isError(value)) {
	      return formatError(value);
	    }
	  }
	
	  var base = '', array = false, braces = ['{', '}'];
	
	  // Make Array say that they are Array
	  if (isArray(value)) {
	    array = true;
	    braces = ['[', ']'];
	  }
	
	  // Make functions say that they are functions
	  if (isFunction(value)) {
	    var n = value.name ? ': ' + value.name : '';
	    base = ' [Function' + n + ']';
	  }
	
	  // Make RegExps say that they are RegExps
	  if (isRegExp(value)) {
	    base = ' ' + RegExp.prototype.toString.call(value);
	  }
	
	  // Make dates with properties first say the date
	  if (isDate(value)) {
	    base = ' ' + Date.prototype.toUTCString.call(value);
	  }
	
	  // Make error with message first say the error
	  if (isError(value)) {
	    base = ' ' + formatError(value);
	  }
	
	  if (keys.length === 0 && (!array || value.length == 0)) {
	    return braces[0] + base + braces[1];
	  }
	
	  if (recurseTimes < 0) {
	    if (isRegExp(value)) {
	      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
	    } else {
	      return ctx.stylize('[Object]', 'special');
	    }
	  }
	
	  ctx.seen.push(value);
	
	  var output;
	  if (array) {
	    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
	  } else {
	    output = keys.map(function(key) {
	      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
	    });
	  }
	
	  ctx.seen.pop();
	
	  return reduceToSingleString(output, base, braces);
	}
	
	
	function formatPrimitive(ctx, value) {
	  if (isUndefined(value))
	    return ctx.stylize('undefined', 'undefined');
	  if (isString(value)) {
	    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
	                                             .replace(/'/g, "\\'")
	                                             .replace(/\\"/g, '"') + '\'';
	    return ctx.stylize(simple, 'string');
	  }
	  if (isNumber(value))
	    return ctx.stylize('' + value, 'number');
	  if (isBoolean(value))
	    return ctx.stylize('' + value, 'boolean');
	  // For some reason typeof null is "object", so special case here.
	  if (isNull(value))
	    return ctx.stylize('null', 'null');
	}
	
	
	function formatError(value) {
	  return '[' + Error.prototype.toString.call(value) + ']';
	}
	
	
	function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
	  var output = [];
	  for (var i = 0, l = value.length; i < l; ++i) {
	    if (hasOwnProperty(value, String(i))) {
	      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
	          String(i), true));
	    } else {
	      output.push('');
	    }
	  }
	  keys.forEach(function(key) {
	    if (!key.match(/^\d+$/)) {
	      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
	          key, true));
	    }
	  });
	  return output;
	}
	
	
	function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
	  var name, str, desc;
	  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
	  if (desc.get) {
	    if (desc.set) {
	      str = ctx.stylize('[Getter/Setter]', 'special');
	    } else {
	      str = ctx.stylize('[Getter]', 'special');
	    }
	  } else {
	    if (desc.set) {
	      str = ctx.stylize('[Setter]', 'special');
	    }
	  }
	  if (!hasOwnProperty(visibleKeys, key)) {
	    name = '[' + key + ']';
	  }
	  if (!str) {
	    if (ctx.seen.indexOf(desc.value) < 0) {
	      if (isNull(recurseTimes)) {
	        str = formatValue(ctx, desc.value, null);
	      } else {
	        str = formatValue(ctx, desc.value, recurseTimes - 1);
	      }
	      if (str.indexOf('\n') > -1) {
	        if (array) {
	          str = str.split('\n').map(function(line) {
	            return '  ' + line;
	          }).join('\n').substr(2);
	        } else {
	          str = '\n' + str.split('\n').map(function(line) {
	            return '   ' + line;
	          }).join('\n');
	        }
	      }
	    } else {
	      str = ctx.stylize('[Circular]', 'special');
	    }
	  }
	  if (isUndefined(name)) {
	    if (array && key.match(/^\d+$/)) {
	      return str;
	    }
	    name = JSON.stringify('' + key);
	    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
	      name = name.substr(1, name.length - 2);
	      name = ctx.stylize(name, 'name');
	    } else {
	      name = name.replace(/'/g, "\\'")
	                 .replace(/\\"/g, '"')
	                 .replace(/(^"|"$)/g, "'");
	      name = ctx.stylize(name, 'string');
	    }
	  }
	
	  return name + ': ' + str;
	}
	
	
	function reduceToSingleString(output, base, braces) {
	  var numLinesEst = 0;
	  var length = output.reduce(function(prev, cur) {
	    numLinesEst++;
	    if (cur.indexOf('\n') >= 0) numLinesEst++;
	    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
	  }, 0);
	
	  if (length > 60) {
	    return braces[0] +
	           (base === '' ? '' : base + '\n ') +
	           ' ' +
	           output.join(',\n  ') +
	           ' ' +
	           braces[1];
	  }
	
	  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
	}
	
	
	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.
	function isArray(ar) {
	  return Array.isArray(ar);
	}
	exports.isArray = isArray;
	
	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	exports.isBoolean = isBoolean;
	
	function isNull(arg) {
	  return arg === null;
	}
	exports.isNull = isNull;
	
	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	exports.isNullOrUndefined = isNullOrUndefined;
	
	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	exports.isNumber = isNumber;
	
	function isString(arg) {
	  return typeof arg === 'string';
	}
	exports.isString = isString;
	
	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	exports.isSymbol = isSymbol;
	
	function isUndefined(arg) {
	  return arg === void 0;
	}
	exports.isUndefined = isUndefined;
	
	function isRegExp(re) {
	  return isObject(re) && objectToString(re) === '[object RegExp]';
	}
	exports.isRegExp = isRegExp;
	
	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	exports.isObject = isObject;
	
	function isDate(d) {
	  return isObject(d) && objectToString(d) === '[object Date]';
	}
	exports.isDate = isDate;
	
	function isError(e) {
	  return isObject(e) &&
	      (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	exports.isError = isError;
	
	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	exports.isFunction = isFunction;
	
	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	exports.isPrimitive = isPrimitive;
	
	exports.isBuffer = __jupyter_require__('util@0.10.3/support/isBufferBrowser.js');
	
	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}
	
	
	function pad(n) {
	  return n < 10 ? '0' + n.toString(10) : n.toString(10);
	}
	
	
	var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
	              'Oct', 'Nov', 'Dec'];
	
	// 26 Feb 16:19:34
	function timestamp() {
	  var d = new Date();
	  var time = [pad(d.getHours()),
	              pad(d.getMinutes()),
	              pad(d.getSeconds())].join(':');
	  return [d.getDate(), months[d.getMonth()], time].join(' ');
	}
	
	
	// log is just a thin wrapper to console.log that prepends a timestamp
	exports.log = function() {
	  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
	};
	
	
	/**
	 * Inherit the prototype methods from one constructor into another.
	 *
	 * The Function.prototype.inherits from lang.js rewritten as a standalone
	 * function (not on Function.prototype). NOTE: If this file is to be loaded
	 * during bootstrapping this function needs to be rewritten using some native
	 * functions as prototype setup using normal JavaScript does not work as
	 * expected during bootstrapping (see mirror.js in r114903).
	 *
	 * @param {function} ctor Constructor function which needs to inherit the
	 *     prototype.
	 * @param {function} superCtor Constructor function to inherit prototype from.
	 */
	exports.inherits = __jupyter_require__('inherits@2.0.1/inherits_browser.js');
	
	exports._extend = function(origin, add) {
	  // Don't do anything if add isn't an object
	  if (!add || !isObject(add)) return origin;
	
	  var keys = Object.keys(add);
	  var i = keys.length;
	  while (i--) {
	    origin[keys[i]] = add[keys[i]];
	  }
	  return origin;
	};
	
	function hasOwnProperty(obj, prop) {
	  return Object.prototype.hasOwnProperty.call(obj, prop);
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __jupyter_require__('process@0.11.10/browser.js')))
})
/** END DEFINE BLOCK for util@0.10.3/util.js **/


/** START DEFINE BLOCK for util@0.10.3/support/isBufferBrowser.js **/
jupyter.define('util@0.10.3/support/isBufferBrowser.js', function (module, exports, __jupyter_require__) {
	module.exports = function isBuffer(arg) {
	  return arg && typeof arg === 'object'
	    && typeof arg.copy === 'function'
	    && typeof arg.fill === 'function'
	    && typeof arg.readUInt8 === 'function';
	}
})
/** END DEFINE BLOCK for util@0.10.3/support/isBufferBrowser.js **/


/** START DEFINE BLOCK for inherits@2.0.1/inherits_browser.js **/
jupyter.define('inherits@2.0.1/inherits_browser.js', function (module, exports, __jupyter_require__) {
	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    ctor.prototype = Object.create(superCtor.prototype, {
	      constructor: {
	        value: ctor,
	        enumerable: false,
	        writable: true,
	        configurable: true
	      }
	    });
	  };
	} else {
	  // old school shim for old browsers
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    var TempCtor = function () {}
	    TempCtor.prototype = superCtor.prototype
	    ctor.prototype = new TempCtor()
	    ctor.prototype.constructor = ctor
	  }
	}
	
})
/** END DEFINE BLOCK for inherits@2.0.1/inherits_browser.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/time.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/time.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var moment = __jupyter_require__('moment@^2.17.1/moment.js');
	/**
	 * The namespace for date functions.
	 */
	var Time;
	(function (Time) {
	    /**
	     * Convert a timestring to a human readable string (e.g. 'two minutes ago').
	     *
	     * @param value - The date timestring or date object.
	     *
	     * @returns A formatted date.
	     */
	    function formatHuman(value) {
	        var time = moment(value).fromNow();
	        time = time === 'a few seconds ago' ? 'seconds ago' : time;
	        return time;
	    }
	    Time.formatHuman = formatHuman;
	    /**
	     * Convert a timestring to a date format.
	     *
	     * @param value - The date timestring or date object.
	     *
	     * @param format - The format string.
	     *
	     * @returns A formatted date.
	     */
	    function format(value, format) {
	        if (format === void 0) { format = 'YYYY-MM-DD HH:mm'; }
	        return moment(value).format(format);
	    }
	    Time.format = format;
	})(Time = exports.Time || (exports.Time = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/time.js **/


/** START DEFINE BLOCK for moment@2.18.1/moment.js **/
jupyter.define('moment@2.18.1/moment.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(module) {//! moment.js
	//! version : 2.18.1
	//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
	//! license : MIT
	//! momentjs.com
	
	;(function (global, factory) {
	     true ? module.exports = factory() :
	    typeof define === 'function' && define.amd ? define(factory) :
	    global.moment = factory()
	}(this, (function () { 'use strict';
	
	var hookCallback;
	
	function hooks () {
	    return hookCallback.apply(null, arguments);
	}
	
	// This is done to register the method called with moment()
	// without creating circular dependencies.
	function setHookCallback (callback) {
	    hookCallback = callback;
	}
	
	function isArray(input) {
	    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
	}
	
	function isObject(input) {
	    // IE8 will treat undefined and null as object if it wasn't for
	    // input != null
	    return input != null && Object.prototype.toString.call(input) === '[object Object]';
	}
	
	function isObjectEmpty(obj) {
	    var k;
	    for (k in obj) {
	        // even if its not own property I'd still call it non-empty
	        return false;
	    }
	    return true;
	}
	
	function isUndefined(input) {
	    return input === void 0;
	}
	
	function isNumber(input) {
	    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
	}
	
	function isDate(input) {
	    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
	}
	
	function map(arr, fn) {
	    var res = [], i;
	    for (i = 0; i < arr.length; ++i) {
	        res.push(fn(arr[i], i));
	    }
	    return res;
	}
	
	function hasOwnProp(a, b) {
	    return Object.prototype.hasOwnProperty.call(a, b);
	}
	
	function extend(a, b) {
	    for (var i in b) {
	        if (hasOwnProp(b, i)) {
	            a[i] = b[i];
	        }
	    }
	
	    if (hasOwnProp(b, 'toString')) {
	        a.toString = b.toString;
	    }
	
	    if (hasOwnProp(b, 'valueOf')) {
	        a.valueOf = b.valueOf;
	    }
	
	    return a;
	}
	
	function createUTC (input, format, locale, strict) {
	    return createLocalOrUTC(input, format, locale, strict, true).utc();
	}
	
	function defaultParsingFlags() {
	    // We need to deep clone this object.
	    return {
	        empty           : false,
	        unusedTokens    : [],
	        unusedInput     : [],
	        overflow        : -2,
	        charsLeftOver   : 0,
	        nullInput       : false,
	        invalidMonth    : null,
	        invalidFormat   : false,
	        userInvalidated : false,
	        iso             : false,
	        parsedDateParts : [],
	        meridiem        : null,
	        rfc2822         : false,
	        weekdayMismatch : false
	    };
	}
	
	function getParsingFlags(m) {
	    if (m._pf == null) {
	        m._pf = defaultParsingFlags();
	    }
	    return m._pf;
	}
	
	var some;
	if (Array.prototype.some) {
	    some = Array.prototype.some;
	} else {
	    some = function (fun) {
	        var t = Object(this);
	        var len = t.length >>> 0;
	
	        for (var i = 0; i < len; i++) {
	            if (i in t && fun.call(this, t[i], i, t)) {
	                return true;
	            }
	        }
	
	        return false;
	    };
	}
	
	var some$1 = some;
	
	function isValid(m) {
	    if (m._isValid == null) {
	        var flags = getParsingFlags(m);
	        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {
	            return i != null;
	        });
	        var isNowValid = !isNaN(m._d.getTime()) &&
	            flags.overflow < 0 &&
	            !flags.empty &&
	            !flags.invalidMonth &&
	            !flags.invalidWeekday &&
	            !flags.nullInput &&
	            !flags.invalidFormat &&
	            !flags.userInvalidated &&
	            (!flags.meridiem || (flags.meridiem && parsedParts));
	
	        if (m._strict) {
	            isNowValid = isNowValid &&
	                flags.charsLeftOver === 0 &&
	                flags.unusedTokens.length === 0 &&
	                flags.bigHour === undefined;
	        }
	
	        if (Object.isFrozen == null || !Object.isFrozen(m)) {
	            m._isValid = isNowValid;
	        }
	        else {
	            return isNowValid;
	        }
	    }
	    return m._isValid;
	}
	
	function createInvalid (flags) {
	    var m = createUTC(NaN);
	    if (flags != null) {
	        extend(getParsingFlags(m), flags);
	    }
	    else {
	        getParsingFlags(m).userInvalidated = true;
	    }
	
	    return m;
	}
	
	// Plugins that add properties should also add the key here (null value),
	// so we can properly clone ourselves.
	var momentProperties = hooks.momentProperties = [];
	
	function copyConfig(to, from) {
	    var i, prop, val;
	
	    if (!isUndefined(from._isAMomentObject)) {
	        to._isAMomentObject = from._isAMomentObject;
	    }
	    if (!isUndefined(from._i)) {
	        to._i = from._i;
	    }
	    if (!isUndefined(from._f)) {
	        to._f = from._f;
	    }
	    if (!isUndefined(from._l)) {
	        to._l = from._l;
	    }
	    if (!isUndefined(from._strict)) {
	        to._strict = from._strict;
	    }
	    if (!isUndefined(from._tzm)) {
	        to._tzm = from._tzm;
	    }
	    if (!isUndefined(from._isUTC)) {
	        to._isUTC = from._isUTC;
	    }
	    if (!isUndefined(from._offset)) {
	        to._offset = from._offset;
	    }
	    if (!isUndefined(from._pf)) {
	        to._pf = getParsingFlags(from);
	    }
	    if (!isUndefined(from._locale)) {
	        to._locale = from._locale;
	    }
	
	    if (momentProperties.length > 0) {
	        for (i = 0; i < momentProperties.length; i++) {
	            prop = momentProperties[i];
	            val = from[prop];
	            if (!isUndefined(val)) {
	                to[prop] = val;
	            }
	        }
	    }
	
	    return to;
	}
	
	var updateInProgress = false;
	
	// Moment prototype object
	function Moment(config) {
	    copyConfig(this, config);
	    this._d = new Date(config._d != null ? config._d.getTime() : NaN);
	    if (!this.isValid()) {
	        this._d = new Date(NaN);
	    }
	    // Prevent infinite loop in case updateOffset creates new moment
	    // objects.
	    if (updateInProgress === false) {
	        updateInProgress = true;
	        hooks.updateOffset(this);
	        updateInProgress = false;
	    }
	}
	
	function isMoment (obj) {
	    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
	}
	
	function absFloor (number) {
	    if (number < 0) {
	        // -0 -> 0
	        return Math.ceil(number) || 0;
	    } else {
	        return Math.floor(number);
	    }
	}
	
	function toInt(argumentForCoercion) {
	    var coercedNumber = +argumentForCoercion,
	        value = 0;
	
	    if (coercedNumber !== 0 && isFinite(coercedNumber)) {
	        value = absFloor(coercedNumber);
	    }
	
	    return value;
	}
	
	// compare two arrays, return the number of differences
	function compareArrays(array1, array2, dontConvert) {
	    var len = Math.min(array1.length, array2.length),
	        lengthDiff = Math.abs(array1.length - array2.length),
	        diffs = 0,
	        i;
	    for (i = 0; i < len; i++) {
	        if ((dontConvert && array1[i] !== array2[i]) ||
	            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
	            diffs++;
	        }
	    }
	    return diffs + lengthDiff;
	}
	
	function warn(msg) {
	    if (hooks.suppressDeprecationWarnings === false &&
	            (typeof console !==  'undefined') && console.warn) {
	        console.warn('Deprecation warning: ' + msg);
	    }
	}
	
	function deprecate(msg, fn) {
	    var firstTime = true;
	
	    return extend(function () {
	        if (hooks.deprecationHandler != null) {
	            hooks.deprecationHandler(null, msg);
	        }
	        if (firstTime) {
	            var args = [];
	            var arg;
	            for (var i = 0; i < arguments.length; i++) {
	                arg = '';
	                if (typeof arguments[i] === 'object') {
	                    arg += '\n[' + i + '] ';
	                    for (var key in arguments[0]) {
	                        arg += key + ': ' + arguments[0][key] + ', ';
	                    }
	                    arg = arg.slice(0, -2); // Remove trailing comma and space
	                } else {
	                    arg = arguments[i];
	                }
	                args.push(arg);
	            }
	            warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
	            firstTime = false;
	        }
	        return fn.apply(this, arguments);
	    }, fn);
	}
	
	var deprecations = {};
	
	function deprecateSimple(name, msg) {
	    if (hooks.deprecationHandler != null) {
	        hooks.deprecationHandler(name, msg);
	    }
	    if (!deprecations[name]) {
	        warn(msg);
	        deprecations[name] = true;
	    }
	}
	
	hooks.suppressDeprecationWarnings = false;
	hooks.deprecationHandler = null;
	
	function isFunction(input) {
	    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
	}
	
	function set (config) {
	    var prop, i;
	    for (i in config) {
	        prop = config[i];
	        if (isFunction(prop)) {
	            this[i] = prop;
	        } else {
	            this['_' + i] = prop;
	        }
	    }
	    this._config = config;
	    // Lenient ordinal parsing accepts just a number in addition to
	    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
	    // TODO: Remove "ordinalParse" fallback in next major release.
	    this._dayOfMonthOrdinalParseLenient = new RegExp(
	        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
	            '|' + (/\d{1,2}/).source);
	}
	
	function mergeConfigs(parentConfig, childConfig) {
	    var res = extend({}, parentConfig), prop;
	    for (prop in childConfig) {
	        if (hasOwnProp(childConfig, prop)) {
	            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
	                res[prop] = {};
	                extend(res[prop], parentConfig[prop]);
	                extend(res[prop], childConfig[prop]);
	            } else if (childConfig[prop] != null) {
	                res[prop] = childConfig[prop];
	            } else {
	                delete res[prop];
	            }
	        }
	    }
	    for (prop in parentConfig) {
	        if (hasOwnProp(parentConfig, prop) &&
	                !hasOwnProp(childConfig, prop) &&
	                isObject(parentConfig[prop])) {
	            // make sure changes to properties don't modify parent config
	            res[prop] = extend({}, res[prop]);
	        }
	    }
	    return res;
	}
	
	function Locale(config) {
	    if (config != null) {
	        this.set(config);
	    }
	}
	
	var keys;
	
	if (Object.keys) {
	    keys = Object.keys;
	} else {
	    keys = function (obj) {
	        var i, res = [];
	        for (i in obj) {
	            if (hasOwnProp(obj, i)) {
	                res.push(i);
	            }
	        }
	        return res;
	    };
	}
	
	var keys$1 = keys;
	
	var defaultCalendar = {
	    sameDay : '[Today at] LT',
	    nextDay : '[Tomorrow at] LT',
	    nextWeek : 'dddd [at] LT',
	    lastDay : '[Yesterday at] LT',
	    lastWeek : '[Last] dddd [at] LT',
	    sameElse : 'L'
	};
	
	function calendar (key, mom, now) {
	    var output = this._calendar[key] || this._calendar['sameElse'];
	    return isFunction(output) ? output.call(mom, now) : output;
	}
	
	var defaultLongDateFormat = {
	    LTS  : 'h:mm:ss A',
	    LT   : 'h:mm A',
	    L    : 'MM/DD/YYYY',
	    LL   : 'MMMM D, YYYY',
	    LLL  : 'MMMM D, YYYY h:mm A',
	    LLLL : 'dddd, MMMM D, YYYY h:mm A'
	};
	
	function longDateFormat (key) {
	    var format = this._longDateFormat[key],
	        formatUpper = this._longDateFormat[key.toUpperCase()];
	
	    if (format || !formatUpper) {
	        return format;
	    }
	
	    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
	        return val.slice(1);
	    });
	
	    return this._longDateFormat[key];
	}
	
	var defaultInvalidDate = 'Invalid date';
	
	function invalidDate () {
	    return this._invalidDate;
	}
	
	var defaultOrdinal = '%d';
	var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
	
	function ordinal (number) {
	    return this._ordinal.replace('%d', number);
	}
	
	var defaultRelativeTime = {
	    future : 'in %s',
	    past   : '%s ago',
	    s  : 'a few seconds',
	    ss : '%d seconds',
	    m  : 'a minute',
	    mm : '%d minutes',
	    h  : 'an hour',
	    hh : '%d hours',
	    d  : 'a day',
	    dd : '%d days',
	    M  : 'a month',
	    MM : '%d months',
	    y  : 'a year',
	    yy : '%d years'
	};
	
	function relativeTime (number, withoutSuffix, string, isFuture) {
	    var output = this._relativeTime[string];
	    return (isFunction(output)) ?
	        output(number, withoutSuffix, string, isFuture) :
	        output.replace(/%d/i, number);
	}
	
	function pastFuture (diff, output) {
	    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
	    return isFunction(format) ? format(output) : format.replace(/%s/i, output);
	}
	
	var aliases = {};
	
	function addUnitAlias (unit, shorthand) {
	    var lowerCase = unit.toLowerCase();
	    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
	}
	
	function normalizeUnits(units) {
	    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
	}
	
	function normalizeObjectUnits(inputObject) {
	    var normalizedInput = {},
	        normalizedProp,
	        prop;
	
	    for (prop in inputObject) {
	        if (hasOwnProp(inputObject, prop)) {
	            normalizedProp = normalizeUnits(prop);
	            if (normalizedProp) {
	                normalizedInput[normalizedProp] = inputObject[prop];
	            }
	        }
	    }
	
	    return normalizedInput;
	}
	
	var priorities = {};
	
	function addUnitPriority(unit, priority) {
	    priorities[unit] = priority;
	}
	
	function getPrioritizedUnits(unitsObj) {
	    var units = [];
	    for (var u in unitsObj) {
	        units.push({unit: u, priority: priorities[u]});
	    }
	    units.sort(function (a, b) {
	        return a.priority - b.priority;
	    });
	    return units;
	}
	
	function makeGetSet (unit, keepTime) {
	    return function (value) {
	        if (value != null) {
	            set$1(this, unit, value);
	            hooks.updateOffset(this, keepTime);
	            return this;
	        } else {
	            return get(this, unit);
	        }
	    };
	}
	
	function get (mom, unit) {
	    return mom.isValid() ?
	        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
	}
	
	function set$1 (mom, unit, value) {
	    if (mom.isValid()) {
	        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
	    }
	}
	
	// MOMENTS
	
	function stringGet (units) {
	    units = normalizeUnits(units);
	    if (isFunction(this[units])) {
	        return this[units]();
	    }
	    return this;
	}
	
	
	function stringSet (units, value) {
	    if (typeof units === 'object') {
	        units = normalizeObjectUnits(units);
	        var prioritized = getPrioritizedUnits(units);
	        for (var i = 0; i < prioritized.length; i++) {
	            this[prioritized[i].unit](units[prioritized[i].unit]);
	        }
	    } else {
	        units = normalizeUnits(units);
	        if (isFunction(this[units])) {
	            return this[units](value);
	        }
	    }
	    return this;
	}
	
	function zeroFill(number, targetLength, forceSign) {
	    var absNumber = '' + Math.abs(number),
	        zerosToFill = targetLength - absNumber.length,
	        sign = number >= 0;
	    return (sign ? (forceSign ? '+' : '') : '-') +
	        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
	}
	
	var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
	
	var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
	
	var formatFunctions = {};
	
	var formatTokenFunctions = {};
	
	// token:    'M'
	// padded:   ['MM', 2]
	// ordinal:  'Mo'
	// callback: function () { this.month() + 1 }
	function addFormatToken (token, padded, ordinal, callback) {
	    var func = callback;
	    if (typeof callback === 'string') {
	        func = function () {
	            return this[callback]();
	        };
	    }
	    if (token) {
	        formatTokenFunctions[token] = func;
	    }
	    if (padded) {
	        formatTokenFunctions[padded[0]] = function () {
	            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
	        };
	    }
	    if (ordinal) {
	        formatTokenFunctions[ordinal] = function () {
	            return this.localeData().ordinal(func.apply(this, arguments), token);
	        };
	    }
	}
	
	function removeFormattingTokens(input) {
	    if (input.match(/\[[\s\S]/)) {
	        return input.replace(/^\[|\]$/g, '');
	    }
	    return input.replace(/\\/g, '');
	}
	
	function makeFormatFunction(format) {
	    var array = format.match(formattingTokens), i, length;
	
	    for (i = 0, length = array.length; i < length; i++) {
	        if (formatTokenFunctions[array[i]]) {
	            array[i] = formatTokenFunctions[array[i]];
	        } else {
	            array[i] = removeFormattingTokens(array[i]);
	        }
	    }
	
	    return function (mom) {
	        var output = '', i;
	        for (i = 0; i < length; i++) {
	            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
	        }
	        return output;
	    };
	}
	
	// format date using native date object
	function formatMoment(m, format) {
	    if (!m.isValid()) {
	        return m.localeData().invalidDate();
	    }
	
	    format = expandFormat(format, m.localeData());
	    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
	
	    return formatFunctions[format](m);
	}
	
	function expandFormat(format, locale) {
	    var i = 5;
	
	    function replaceLongDateFormatTokens(input) {
	        return locale.longDateFormat(input) || input;
	    }
	
	    localFormattingTokens.lastIndex = 0;
	    while (i >= 0 && localFormattingTokens.test(format)) {
	        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
	        localFormattingTokens.lastIndex = 0;
	        i -= 1;
	    }
	
	    return format;
	}
	
	var match1         = /\d/;            //       0 - 9
	var match2         = /\d\d/;          //      00 - 99
	var match3         = /\d{3}/;         //     000 - 999
	var match4         = /\d{4}/;         //    0000 - 9999
	var match6         = /[+-]?\d{6}/;    // -999999 - 999999
	var match1to2      = /\d\d?/;         //       0 - 99
	var match3to4      = /\d\d\d\d?/;     //     999 - 9999
	var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
	var match1to3      = /\d{1,3}/;       //       0 - 999
	var match1to4      = /\d{1,4}/;       //       0 - 9999
	var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
	
	var matchUnsigned  = /\d+/;           //       0 - inf
	var matchSigned    = /[+-]?\d+/;      //    -inf - inf
	
	var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
	var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
	
	var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
	
	// any word (or two) characters or numbers including two/three word month in arabic.
	// includes scottish gaelic two word and hyphenated months
	var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
	
	
	var regexes = {};
	
	function addRegexToken (token, regex, strictRegex) {
	    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
	        return (isStrict && strictRegex) ? strictRegex : regex;
	    };
	}
	
	function getParseRegexForToken (token, config) {
	    if (!hasOwnProp(regexes, token)) {
	        return new RegExp(unescapeFormat(token));
	    }
	
	    return regexes[token](config._strict, config._locale);
	}
	
	// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
	function unescapeFormat(s) {
	    return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
	        return p1 || p2 || p3 || p4;
	    }));
	}
	
	function regexEscape(s) {
	    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
	}
	
	var tokens = {};
	
	function addParseToken (token, callback) {
	    var i, func = callback;
	    if (typeof token === 'string') {
	        token = [token];
	    }
	    if (isNumber(callback)) {
	        func = function (input, array) {
	            array[callback] = toInt(input);
	        };
	    }
	    for (i = 0; i < token.length; i++) {
	        tokens[token[i]] = func;
	    }
	}
	
	function addWeekParseToken (token, callback) {
	    addParseToken(token, function (input, array, config, token) {
	        config._w = config._w || {};
	        callback(input, config._w, config, token);
	    });
	}
	
	function addTimeToArrayFromToken(token, input, config) {
	    if (input != null && hasOwnProp(tokens, token)) {
	        tokens[token](input, config._a, config, token);
	    }
	}
	
	var YEAR = 0;
	var MONTH = 1;
	var DATE = 2;
	var HOUR = 3;
	var MINUTE = 4;
	var SECOND = 5;
	var MILLISECOND = 6;
	var WEEK = 7;
	var WEEKDAY = 8;
	
	var indexOf;
	
	if (Array.prototype.indexOf) {
	    indexOf = Array.prototype.indexOf;
	} else {
	    indexOf = function (o) {
	        // I know
	        var i;
	        for (i = 0; i < this.length; ++i) {
	            if (this[i] === o) {
	                return i;
	            }
	        }
	        return -1;
	    };
	}
	
	var indexOf$1 = indexOf;
	
	function daysInMonth(year, month) {
	    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
	}
	
	// FORMATTING
	
	addFormatToken('M', ['MM', 2], 'Mo', function () {
	    return this.month() + 1;
	});
	
	addFormatToken('MMM', 0, 0, function (format) {
	    return this.localeData().monthsShort(this, format);
	});
	
	addFormatToken('MMMM', 0, 0, function (format) {
	    return this.localeData().months(this, format);
	});
	
	// ALIASES
	
	addUnitAlias('month', 'M');
	
	// PRIORITY
	
	addUnitPriority('month', 8);
	
	// PARSING
	
	addRegexToken('M',    match1to2);
	addRegexToken('MM',   match1to2, match2);
	addRegexToken('MMM',  function (isStrict, locale) {
	    return locale.monthsShortRegex(isStrict);
	});
	addRegexToken('MMMM', function (isStrict, locale) {
	    return locale.monthsRegex(isStrict);
	});
	
	addParseToken(['M', 'MM'], function (input, array) {
	    array[MONTH] = toInt(input) - 1;
	});
	
	addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
	    var month = config._locale.monthsParse(input, token, config._strict);
	    // if we didn't find a month name, mark the date as invalid.
	    if (month != null) {
	        array[MONTH] = month;
	    } else {
	        getParsingFlags(config).invalidMonth = input;
	    }
	});
	
	// LOCALES
	
	var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
	var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
	function localeMonths (m, format) {
	    if (!m) {
	        return isArray(this._months) ? this._months :
	            this._months['standalone'];
	    }
	    return isArray(this._months) ? this._months[m.month()] :
	        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
	}
	
	var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
	function localeMonthsShort (m, format) {
	    if (!m) {
	        return isArray(this._monthsShort) ? this._monthsShort :
	            this._monthsShort['standalone'];
	    }
	    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
	        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
	}
	
	function handleStrictParse(monthName, format, strict) {
	    var i, ii, mom, llc = monthName.toLocaleLowerCase();
	    if (!this._monthsParse) {
	        // this is not used
	        this._monthsParse = [];
	        this._longMonthsParse = [];
	        this._shortMonthsParse = [];
	        for (i = 0; i < 12; ++i) {
	            mom = createUTC([2000, i]);
	            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
	            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
	        }
	    }
	
	    if (strict) {
	        if (format === 'MMM') {
	            ii = indexOf$1.call(this._shortMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    } else {
	        if (format === 'MMM') {
	            ii = indexOf$1.call(this._shortMonthsParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._longMonthsParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._shortMonthsParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    }
	}
	
	function localeMonthsParse (monthName, format, strict) {
	    var i, mom, regex;
	
	    if (this._monthsParseExact) {
	        return handleStrictParse.call(this, monthName, format, strict);
	    }
	
	    if (!this._monthsParse) {
	        this._monthsParse = [];
	        this._longMonthsParse = [];
	        this._shortMonthsParse = [];
	    }
	
	    // TODO: add sorting
	    // Sorting makes sure if one month (or abbr) is a prefix of another
	    // see sorting in computeMonthsParse
	    for (i = 0; i < 12; i++) {
	        // make the regex if we don't have it already
	        mom = createUTC([2000, i]);
	        if (strict && !this._longMonthsParse[i]) {
	            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
	            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
	        }
	        if (!strict && !this._monthsParse[i]) {
	            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
	            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
	        }
	        // test the regex
	        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
	            return i;
	        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
	            return i;
	        } else if (!strict && this._monthsParse[i].test(monthName)) {
	            return i;
	        }
	    }
	}
	
	// MOMENTS
	
	function setMonth (mom, value) {
	    var dayOfMonth;
	
	    if (!mom.isValid()) {
	        // No op
	        return mom;
	    }
	
	    if (typeof value === 'string') {
	        if (/^\d+$/.test(value)) {
	            value = toInt(value);
	        } else {
	            value = mom.localeData().monthsParse(value);
	            // TODO: Another silent failure?
	            if (!isNumber(value)) {
	                return mom;
	            }
	        }
	    }
	
	    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
	    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
	    return mom;
	}
	
	function getSetMonth (value) {
	    if (value != null) {
	        setMonth(this, value);
	        hooks.updateOffset(this, true);
	        return this;
	    } else {
	        return get(this, 'Month');
	    }
	}
	
	function getDaysInMonth () {
	    return daysInMonth(this.year(), this.month());
	}
	
	var defaultMonthsShortRegex = matchWord;
	function monthsShortRegex (isStrict) {
	    if (this._monthsParseExact) {
	        if (!hasOwnProp(this, '_monthsRegex')) {
	            computeMonthsParse.call(this);
	        }
	        if (isStrict) {
	            return this._monthsShortStrictRegex;
	        } else {
	            return this._monthsShortRegex;
	        }
	    } else {
	        if (!hasOwnProp(this, '_monthsShortRegex')) {
	            this._monthsShortRegex = defaultMonthsShortRegex;
	        }
	        return this._monthsShortStrictRegex && isStrict ?
	            this._monthsShortStrictRegex : this._monthsShortRegex;
	    }
	}
	
	var defaultMonthsRegex = matchWord;
	function monthsRegex (isStrict) {
	    if (this._monthsParseExact) {
	        if (!hasOwnProp(this, '_monthsRegex')) {
	            computeMonthsParse.call(this);
	        }
	        if (isStrict) {
	            return this._monthsStrictRegex;
	        } else {
	            return this._monthsRegex;
	        }
	    } else {
	        if (!hasOwnProp(this, '_monthsRegex')) {
	            this._monthsRegex = defaultMonthsRegex;
	        }
	        return this._monthsStrictRegex && isStrict ?
	            this._monthsStrictRegex : this._monthsRegex;
	    }
	}
	
	function computeMonthsParse () {
	    function cmpLenRev(a, b) {
	        return b.length - a.length;
	    }
	
	    var shortPieces = [], longPieces = [], mixedPieces = [],
	        i, mom;
	    for (i = 0; i < 12; i++) {
	        // make the regex if we don't have it already
	        mom = createUTC([2000, i]);
	        shortPieces.push(this.monthsShort(mom, ''));
	        longPieces.push(this.months(mom, ''));
	        mixedPieces.push(this.months(mom, ''));
	        mixedPieces.push(this.monthsShort(mom, ''));
	    }
	    // Sorting makes sure if one month (or abbr) is a prefix of another it
	    // will match the longer piece.
	    shortPieces.sort(cmpLenRev);
	    longPieces.sort(cmpLenRev);
	    mixedPieces.sort(cmpLenRev);
	    for (i = 0; i < 12; i++) {
	        shortPieces[i] = regexEscape(shortPieces[i]);
	        longPieces[i] = regexEscape(longPieces[i]);
	    }
	    for (i = 0; i < 24; i++) {
	        mixedPieces[i] = regexEscape(mixedPieces[i]);
	    }
	
	    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
	    this._monthsShortRegex = this._monthsRegex;
	    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
	    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
	}
	
	// FORMATTING
	
	addFormatToken('Y', 0, 0, function () {
	    var y = this.year();
	    return y <= 9999 ? '' + y : '+' + y;
	});
	
	addFormatToken(0, ['YY', 2], 0, function () {
	    return this.year() % 100;
	});
	
	addFormatToken(0, ['YYYY',   4],       0, 'year');
	addFormatToken(0, ['YYYYY',  5],       0, 'year');
	addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
	
	// ALIASES
	
	addUnitAlias('year', 'y');
	
	// PRIORITIES
	
	addUnitPriority('year', 1);
	
	// PARSING
	
	addRegexToken('Y',      matchSigned);
	addRegexToken('YY',     match1to2, match2);
	addRegexToken('YYYY',   match1to4, match4);
	addRegexToken('YYYYY',  match1to6, match6);
	addRegexToken('YYYYYY', match1to6, match6);
	
	addParseToken(['YYYYY', 'YYYYYY'], YEAR);
	addParseToken('YYYY', function (input, array) {
	    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
	});
	addParseToken('YY', function (input, array) {
	    array[YEAR] = hooks.parseTwoDigitYear(input);
	});
	addParseToken('Y', function (input, array) {
	    array[YEAR] = parseInt(input, 10);
	});
	
	// HELPERS
	
	function daysInYear(year) {
	    return isLeapYear(year) ? 366 : 365;
	}
	
	function isLeapYear(year) {
	    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
	}
	
	// HOOKS
	
	hooks.parseTwoDigitYear = function (input) {
	    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
	};
	
	// MOMENTS
	
	var getSetYear = makeGetSet('FullYear', true);
	
	function getIsLeapYear () {
	    return isLeapYear(this.year());
	}
	
	function createDate (y, m, d, h, M, s, ms) {
	    // can't just apply() to create a date:
	    // https://stackoverflow.com/q/181348
	    var date = new Date(y, m, d, h, M, s, ms);
	
	    // the date constructor remaps years 0-99 to 1900-1999
	    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
	        date.setFullYear(y);
	    }
	    return date;
	}
	
	function createUTCDate (y) {
	    var date = new Date(Date.UTC.apply(null, arguments));
	
	    // the Date.UTC function remaps years 0-99 to 1900-1999
	    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
	        date.setUTCFullYear(y);
	    }
	    return date;
	}
	
	// start-of-first-week - start-of-year
	function firstWeekOffset(year, dow, doy) {
	    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
	        fwd = 7 + dow - doy,
	        // first-week day local weekday -- which local weekday is fwd
	        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
	
	    return -fwdlw + fwd - 1;
	}
	
	// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
	function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
	    var localWeekday = (7 + weekday - dow) % 7,
	        weekOffset = firstWeekOffset(year, dow, doy),
	        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
	        resYear, resDayOfYear;
	
	    if (dayOfYear <= 0) {
	        resYear = year - 1;
	        resDayOfYear = daysInYear(resYear) + dayOfYear;
	    } else if (dayOfYear > daysInYear(year)) {
	        resYear = year + 1;
	        resDayOfYear = dayOfYear - daysInYear(year);
	    } else {
	        resYear = year;
	        resDayOfYear = dayOfYear;
	    }
	
	    return {
	        year: resYear,
	        dayOfYear: resDayOfYear
	    };
	}
	
	function weekOfYear(mom, dow, doy) {
	    var weekOffset = firstWeekOffset(mom.year(), dow, doy),
	        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
	        resWeek, resYear;
	
	    if (week < 1) {
	        resYear = mom.year() - 1;
	        resWeek = week + weeksInYear(resYear, dow, doy);
	    } else if (week > weeksInYear(mom.year(), dow, doy)) {
	        resWeek = week - weeksInYear(mom.year(), dow, doy);
	        resYear = mom.year() + 1;
	    } else {
	        resYear = mom.year();
	        resWeek = week;
	    }
	
	    return {
	        week: resWeek,
	        year: resYear
	    };
	}
	
	function weeksInYear(year, dow, doy) {
	    var weekOffset = firstWeekOffset(year, dow, doy),
	        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
	    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
	}
	
	// FORMATTING
	
	addFormatToken('w', ['ww', 2], 'wo', 'week');
	addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
	
	// ALIASES
	
	addUnitAlias('week', 'w');
	addUnitAlias('isoWeek', 'W');
	
	// PRIORITIES
	
	addUnitPriority('week', 5);
	addUnitPriority('isoWeek', 5);
	
	// PARSING
	
	addRegexToken('w',  match1to2);
	addRegexToken('ww', match1to2, match2);
	addRegexToken('W',  match1to2);
	addRegexToken('WW', match1to2, match2);
	
	addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
	    week[token.substr(0, 1)] = toInt(input);
	});
	
	// HELPERS
	
	// LOCALES
	
	function localeWeek (mom) {
	    return weekOfYear(mom, this._week.dow, this._week.doy).week;
	}
	
	var defaultLocaleWeek = {
	    dow : 0, // Sunday is the first day of the week.
	    doy : 6  // The week that contains Jan 1st is the first week of the year.
	};
	
	function localeFirstDayOfWeek () {
	    return this._week.dow;
	}
	
	function localeFirstDayOfYear () {
	    return this._week.doy;
	}
	
	// MOMENTS
	
	function getSetWeek (input) {
	    var week = this.localeData().week(this);
	    return input == null ? week : this.add((input - week) * 7, 'd');
	}
	
	function getSetISOWeek (input) {
	    var week = weekOfYear(this, 1, 4).week;
	    return input == null ? week : this.add((input - week) * 7, 'd');
	}
	
	// FORMATTING
	
	addFormatToken('d', 0, 'do', 'day');
	
	addFormatToken('dd', 0, 0, function (format) {
	    return this.localeData().weekdaysMin(this, format);
	});
	
	addFormatToken('ddd', 0, 0, function (format) {
	    return this.localeData().weekdaysShort(this, format);
	});
	
	addFormatToken('dddd', 0, 0, function (format) {
	    return this.localeData().weekdays(this, format);
	});
	
	addFormatToken('e', 0, 0, 'weekday');
	addFormatToken('E', 0, 0, 'isoWeekday');
	
	// ALIASES
	
	addUnitAlias('day', 'd');
	addUnitAlias('weekday', 'e');
	addUnitAlias('isoWeekday', 'E');
	
	// PRIORITY
	addUnitPriority('day', 11);
	addUnitPriority('weekday', 11);
	addUnitPriority('isoWeekday', 11);
	
	// PARSING
	
	addRegexToken('d',    match1to2);
	addRegexToken('e',    match1to2);
	addRegexToken('E',    match1to2);
	addRegexToken('dd',   function (isStrict, locale) {
	    return locale.weekdaysMinRegex(isStrict);
	});
	addRegexToken('ddd',   function (isStrict, locale) {
	    return locale.weekdaysShortRegex(isStrict);
	});
	addRegexToken('dddd',   function (isStrict, locale) {
	    return locale.weekdaysRegex(isStrict);
	});
	
	addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
	    var weekday = config._locale.weekdaysParse(input, token, config._strict);
	    // if we didn't get a weekday name, mark the date as invalid
	    if (weekday != null) {
	        week.d = weekday;
	    } else {
	        getParsingFlags(config).invalidWeekday = input;
	    }
	});
	
	addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
	    week[token] = toInt(input);
	});
	
	// HELPERS
	
	function parseWeekday(input, locale) {
	    if (typeof input !== 'string') {
	        return input;
	    }
	
	    if (!isNaN(input)) {
	        return parseInt(input, 10);
	    }
	
	    input = locale.weekdaysParse(input);
	    if (typeof input === 'number') {
	        return input;
	    }
	
	    return null;
	}
	
	function parseIsoWeekday(input, locale) {
	    if (typeof input === 'string') {
	        return locale.weekdaysParse(input) % 7 || 7;
	    }
	    return isNaN(input) ? null : input;
	}
	
	// LOCALES
	
	var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
	function localeWeekdays (m, format) {
	    if (!m) {
	        return isArray(this._weekdays) ? this._weekdays :
	            this._weekdays['standalone'];
	    }
	    return isArray(this._weekdays) ? this._weekdays[m.day()] :
	        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
	}
	
	var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
	function localeWeekdaysShort (m) {
	    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
	}
	
	var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
	function localeWeekdaysMin (m) {
	    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
	}
	
	function handleStrictParse$1(weekdayName, format, strict) {
	    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
	    if (!this._weekdaysParse) {
	        this._weekdaysParse = [];
	        this._shortWeekdaysParse = [];
	        this._minWeekdaysParse = [];
	
	        for (i = 0; i < 7; ++i) {
	            mom = createUTC([2000, 1]).day(i);
	            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
	            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
	            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
	        }
	    }
	
	    if (strict) {
	        if (format === 'dddd') {
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else if (format === 'ddd') {
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    } else {
	        if (format === 'dddd') {
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else if (format === 'ddd') {
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        } else {
	            ii = indexOf$1.call(this._minWeekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._weekdaysParse, llc);
	            if (ii !== -1) {
	                return ii;
	            }
	            ii = indexOf$1.call(this._shortWeekdaysParse, llc);
	            return ii !== -1 ? ii : null;
	        }
	    }
	}
	
	function localeWeekdaysParse (weekdayName, format, strict) {
	    var i, mom, regex;
	
	    if (this._weekdaysParseExact) {
	        return handleStrictParse$1.call(this, weekdayName, format, strict);
	    }
	
	    if (!this._weekdaysParse) {
	        this._weekdaysParse = [];
	        this._minWeekdaysParse = [];
	        this._shortWeekdaysParse = [];
	        this._fullWeekdaysParse = [];
	    }
	
	    for (i = 0; i < 7; i++) {
	        // make the regex if we don't have it already
	
	        mom = createUTC([2000, 1]).day(i);
	        if (strict && !this._fullWeekdaysParse[i]) {
	            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
	            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
	            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
	        }
	        if (!this._weekdaysParse[i]) {
	            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
	            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
	        }
	        // test the regex
	        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
	            return i;
	        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
	            return i;
	        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
	            return i;
	        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
	            return i;
	        }
	    }
	}
	
	// MOMENTS
	
	function getSetDayOfWeek (input) {
	    if (!this.isValid()) {
	        return input != null ? this : NaN;
	    }
	    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
	    if (input != null) {
	        input = parseWeekday(input, this.localeData());
	        return this.add(input - day, 'd');
	    } else {
	        return day;
	    }
	}
	
	function getSetLocaleDayOfWeek (input) {
	    if (!this.isValid()) {
	        return input != null ? this : NaN;
	    }
	    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
	    return input == null ? weekday : this.add(input - weekday, 'd');
	}
	
	function getSetISODayOfWeek (input) {
	    if (!this.isValid()) {
	        return input != null ? this : NaN;
	    }
	
	    // behaves the same as moment#day except
	    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
	    // as a setter, sunday should belong to the previous week.
	
	    if (input != null) {
	        var weekday = parseIsoWeekday(input, this.localeData());
	        return this.day(this.day() % 7 ? weekday : weekday - 7);
	    } else {
	        return this.day() || 7;
	    }
	}
	
	var defaultWeekdaysRegex = matchWord;
	function weekdaysRegex (isStrict) {
	    if (this._weekdaysParseExact) {
	        if (!hasOwnProp(this, '_weekdaysRegex')) {
	            computeWeekdaysParse.call(this);
	        }
	        if (isStrict) {
	            return this._weekdaysStrictRegex;
	        } else {
	            return this._weekdaysRegex;
	        }
	    } else {
	        if (!hasOwnProp(this, '_weekdaysRegex')) {
	            this._weekdaysRegex = defaultWeekdaysRegex;
	        }
	        return this._weekdaysStrictRegex && isStrict ?
	            this._weekdaysStrictRegex : this._weekdaysRegex;
	    }
	}
	
	var defaultWeekdaysShortRegex = matchWord;
	function weekdaysShortRegex (isStrict) {
	    if (this._weekdaysParseExact) {
	        if (!hasOwnProp(this, '_weekdaysRegex')) {
	            computeWeekdaysParse.call(this);
	        }
	        if (isStrict) {
	            return this._weekdaysShortStrictRegex;
	        } else {
	            return this._weekdaysShortRegex;
	        }
	    } else {
	        if (!hasOwnProp(this, '_weekdaysShortRegex')) {
	            this._weekdaysShortRegex = defaultWeekdaysShortRegex;
	        }
	        return this._weekdaysShortStrictRegex && isStrict ?
	            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
	    }
	}
	
	var defaultWeekdaysMinRegex = matchWord;
	function weekdaysMinRegex (isStrict) {
	    if (this._weekdaysParseExact) {
	        if (!hasOwnProp(this, '_weekdaysRegex')) {
	            computeWeekdaysParse.call(this);
	        }
	        if (isStrict) {
	            return this._weekdaysMinStrictRegex;
	        } else {
	            return this._weekdaysMinRegex;
	        }
	    } else {
	        if (!hasOwnProp(this, '_weekdaysMinRegex')) {
	            this._weekdaysMinRegex = defaultWeekdaysMinRegex;
	        }
	        return this._weekdaysMinStrictRegex && isStrict ?
	            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
	    }
	}
	
	
	function computeWeekdaysParse () {
	    function cmpLenRev(a, b) {
	        return b.length - a.length;
	    }
	
	    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
	        i, mom, minp, shortp, longp;
	    for (i = 0; i < 7; i++) {
	        // make the regex if we don't have it already
	        mom = createUTC([2000, 1]).day(i);
	        minp = this.weekdaysMin(mom, '');
	        shortp = this.weekdaysShort(mom, '');
	        longp = this.weekdays(mom, '');
	        minPieces.push(minp);
	        shortPieces.push(shortp);
	        longPieces.push(longp);
	        mixedPieces.push(minp);
	        mixedPieces.push(shortp);
	        mixedPieces.push(longp);
	    }
	    // Sorting makes sure if one weekday (or abbr) is a prefix of another it
	    // will match the longer piece.
	    minPieces.sort(cmpLenRev);
	    shortPieces.sort(cmpLenRev);
	    longPieces.sort(cmpLenRev);
	    mixedPieces.sort(cmpLenRev);
	    for (i = 0; i < 7; i++) {
	        shortPieces[i] = regexEscape(shortPieces[i]);
	        longPieces[i] = regexEscape(longPieces[i]);
	        mixedPieces[i] = regexEscape(mixedPieces[i]);
	    }
	
	    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
	    this._weekdaysShortRegex = this._weekdaysRegex;
	    this._weekdaysMinRegex = this._weekdaysRegex;
	
	    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
	    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
	    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
	}
	
	// FORMATTING
	
	function hFormat() {
	    return this.hours() % 12 || 12;
	}
	
	function kFormat() {
	    return this.hours() || 24;
	}
	
	addFormatToken('H', ['HH', 2], 0, 'hour');
	addFormatToken('h', ['hh', 2], 0, hFormat);
	addFormatToken('k', ['kk', 2], 0, kFormat);
	
	addFormatToken('hmm', 0, 0, function () {
	    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
	});
	
	addFormatToken('hmmss', 0, 0, function () {
	    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
	        zeroFill(this.seconds(), 2);
	});
	
	addFormatToken('Hmm', 0, 0, function () {
	    return '' + this.hours() + zeroFill(this.minutes(), 2);
	});
	
	addFormatToken('Hmmss', 0, 0, function () {
	    return '' + this.hours() + zeroFill(this.minutes(), 2) +
	        zeroFill(this.seconds(), 2);
	});
	
	function meridiem (token, lowercase) {
	    addFormatToken(token, 0, 0, function () {
	        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
	    });
	}
	
	meridiem('a', true);
	meridiem('A', false);
	
	// ALIASES
	
	addUnitAlias('hour', 'h');
	
	// PRIORITY
	addUnitPriority('hour', 13);
	
	// PARSING
	
	function matchMeridiem (isStrict, locale) {
	    return locale._meridiemParse;
	}
	
	addRegexToken('a',  matchMeridiem);
	addRegexToken('A',  matchMeridiem);
	addRegexToken('H',  match1to2);
	addRegexToken('h',  match1to2);
	addRegexToken('k',  match1to2);
	addRegexToken('HH', match1to2, match2);
	addRegexToken('hh', match1to2, match2);
	addRegexToken('kk', match1to2, match2);
	
	addRegexToken('hmm', match3to4);
	addRegexToken('hmmss', match5to6);
	addRegexToken('Hmm', match3to4);
	addRegexToken('Hmmss', match5to6);
	
	addParseToken(['H', 'HH'], HOUR);
	addParseToken(['k', 'kk'], function (input, array, config) {
	    var kInput = toInt(input);
	    array[HOUR] = kInput === 24 ? 0 : kInput;
	});
	addParseToken(['a', 'A'], function (input, array, config) {
	    config._isPm = config._locale.isPM(input);
	    config._meridiem = input;
	});
	addParseToken(['h', 'hh'], function (input, array, config) {
	    array[HOUR] = toInt(input);
	    getParsingFlags(config).bigHour = true;
	});
	addParseToken('hmm', function (input, array, config) {
	    var pos = input.length - 2;
	    array[HOUR] = toInt(input.substr(0, pos));
	    array[MINUTE] = toInt(input.substr(pos));
	    getParsingFlags(config).bigHour = true;
	});
	addParseToken('hmmss', function (input, array, config) {
	    var pos1 = input.length - 4;
	    var pos2 = input.length - 2;
	    array[HOUR] = toInt(input.substr(0, pos1));
	    array[MINUTE] = toInt(input.substr(pos1, 2));
	    array[SECOND] = toInt(input.substr(pos2));
	    getParsingFlags(config).bigHour = true;
	});
	addParseToken('Hmm', function (input, array, config) {
	    var pos = input.length - 2;
	    array[HOUR] = toInt(input.substr(0, pos));
	    array[MINUTE] = toInt(input.substr(pos));
	});
	addParseToken('Hmmss', function (input, array, config) {
	    var pos1 = input.length - 4;
	    var pos2 = input.length - 2;
	    array[HOUR] = toInt(input.substr(0, pos1));
	    array[MINUTE] = toInt(input.substr(pos1, 2));
	    array[SECOND] = toInt(input.substr(pos2));
	});
	
	// LOCALES
	
	function localeIsPM (input) {
	    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
	    // Using charAt should be more compatible.
	    return ((input + '').toLowerCase().charAt(0) === 'p');
	}
	
	var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
	function localeMeridiem (hours, minutes, isLower) {
	    if (hours > 11) {
	        return isLower ? 'pm' : 'PM';
	    } else {
	        return isLower ? 'am' : 'AM';
	    }
	}
	
	
	// MOMENTS
	
	// Setting the hour should keep the time, because the user explicitly
	// specified which hour he wants. So trying to maintain the same hour (in
	// a new timezone) makes sense. Adding/subtracting hours does not follow
	// this rule.
	var getSetHour = makeGetSet('Hours', true);
	
	// months
	// week
	// weekdays
	// meridiem
	var baseConfig = {
	    calendar: defaultCalendar,
	    longDateFormat: defaultLongDateFormat,
	    invalidDate: defaultInvalidDate,
	    ordinal: defaultOrdinal,
	    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
	    relativeTime: defaultRelativeTime,
	
	    months: defaultLocaleMonths,
	    monthsShort: defaultLocaleMonthsShort,
	
	    week: defaultLocaleWeek,
	
	    weekdays: defaultLocaleWeekdays,
	    weekdaysMin: defaultLocaleWeekdaysMin,
	    weekdaysShort: defaultLocaleWeekdaysShort,
	
	    meridiemParse: defaultLocaleMeridiemParse
	};
	
	// internal storage for locale config files
	var locales = {};
	var localeFamilies = {};
	var globalLocale;
	
	function normalizeLocale(key) {
	    return key ? key.toLowerCase().replace('_', '-') : key;
	}
	
	// pick the locale from the array
	// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
	// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
	function chooseLocale(names) {
	    var i = 0, j, next, locale, split;
	
	    while (i < names.length) {
	        split = normalizeLocale(names[i]).split('-');
	        j = split.length;
	        next = normalizeLocale(names[i + 1]);
	        next = next ? next.split('-') : null;
	        while (j > 0) {
	            locale = loadLocale(split.slice(0, j).join('-'));
	            if (locale) {
	                return locale;
	            }
	            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
	                //the next array item is better than a shallower substring of this one
	                break;
	            }
	            j--;
	        }
	        i++;
	    }
	    return null;
	}
	
	function loadLocale(name) {
	    var oldLocale = null;
	    // TODO: Find a better way to register and load all the locales in Node
	    if (!locales[name] && (typeof module !== 'undefined') &&
	            module && module.exports) {
	        try {
	            oldLocale = globalLocale._abbr;
	            __jupyter_require__('moment@2.18.1/locale')("./" + name);
	            // because defineLocale currently also sets the global locale, we
	            // want to undo that for lazy loaded locales
	            getSetGlobalLocale(oldLocale);
	        } catch (e) { }
	    }
	    return locales[name];
	}
	
	// This function will load locale and then set the global locale.  If
	// no arguments are passed in, it will simply return the current global
	// locale key.
	function getSetGlobalLocale (key, values) {
	    var data;
	    if (key) {
	        if (isUndefined(values)) {
	            data = getLocale(key);
	        }
	        else {
	            data = defineLocale(key, values);
	        }
	
	        if (data) {
	            // moment.duration._locale = moment._locale = data;
	            globalLocale = data;
	        }
	    }
	
	    return globalLocale._abbr;
	}
	
	function defineLocale (name, config) {
	    if (config !== null) {
	        var parentConfig = baseConfig;
	        config.abbr = name;
	        if (locales[name] != null) {
	            deprecateSimple('defineLocaleOverride',
	                    'use moment.updateLocale(localeName, config) to change ' +
	                    'an existing locale. moment.defineLocale(localeName, ' +
	                    'config) should only be used for creating a new locale ' +
	                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
	            parentConfig = locales[name]._config;
	        } else if (config.parentLocale != null) {
	            if (locales[config.parentLocale] != null) {
	                parentConfig = locales[config.parentLocale]._config;
	            } else {
	                if (!localeFamilies[config.parentLocale]) {
	                    localeFamilies[config.parentLocale] = [];
	                }
	                localeFamilies[config.parentLocale].push({
	                    name: name,
	                    config: config
	                });
	                return null;
	            }
	        }
	        locales[name] = new Locale(mergeConfigs(parentConfig, config));
	
	        if (localeFamilies[name]) {
	            localeFamilies[name].forEach(function (x) {
	                defineLocale(x.name, x.config);
	            });
	        }
	
	        // backwards compat for now: also set the locale
	        // make sure we set the locale AFTER all child locales have been
	        // created, so we won't end up with the child locale set.
	        getSetGlobalLocale(name);
	
	
	        return locales[name];
	    } else {
	        // useful for testing
	        delete locales[name];
	        return null;
	    }
	}
	
	function updateLocale(name, config) {
	    if (config != null) {
	        var locale, parentConfig = baseConfig;
	        // MERGE
	        if (locales[name] != null) {
	            parentConfig = locales[name]._config;
	        }
	        config = mergeConfigs(parentConfig, config);
	        locale = new Locale(config);
	        locale.parentLocale = locales[name];
	        locales[name] = locale;
	
	        // backwards compat for now: also set the locale
	        getSetGlobalLocale(name);
	    } else {
	        // pass null for config to unupdate, useful for tests
	        if (locales[name] != null) {
	            if (locales[name].parentLocale != null) {
	                locales[name] = locales[name].parentLocale;
	            } else if (locales[name] != null) {
	                delete locales[name];
	            }
	        }
	    }
	    return locales[name];
	}
	
	// returns locale data
	function getLocale (key) {
	    var locale;
	
	    if (key && key._locale && key._locale._abbr) {
	        key = key._locale._abbr;
	    }
	
	    if (!key) {
	        return globalLocale;
	    }
	
	    if (!isArray(key)) {
	        //short-circuit everything else
	        locale = loadLocale(key);
	        if (locale) {
	            return locale;
	        }
	        key = [key];
	    }
	
	    return chooseLocale(key);
	}
	
	function listLocales() {
	    return keys$1(locales);
	}
	
	function checkOverflow (m) {
	    var overflow;
	    var a = m._a;
	
	    if (a && getParsingFlags(m).overflow === -2) {
	        overflow =
	            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
	            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
	            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
	            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
	            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
	            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
	            -1;
	
	        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
	            overflow = DATE;
	        }
	        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
	            overflow = WEEK;
	        }
	        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
	            overflow = WEEKDAY;
	        }
	
	        getParsingFlags(m).overflow = overflow;
	    }
	
	    return m;
	}
	
	// iso 8601 regex
	// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
	var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
	var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
	
	var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
	
	var isoDates = [
	    ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
	    ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
	    ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
	    ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
	    ['YYYY-DDD', /\d{4}-\d{3}/],
	    ['YYYY-MM', /\d{4}-\d\d/, false],
	    ['YYYYYYMMDD', /[+-]\d{10}/],
	    ['YYYYMMDD', /\d{8}/],
	    // YYYYMM is NOT allowed by the standard
	    ['GGGG[W]WWE', /\d{4}W\d{3}/],
	    ['GGGG[W]WW', /\d{4}W\d{2}/, false],
	    ['YYYYDDD', /\d{7}/]
	];
	
	// iso time formats and regexes
	var isoTimes = [
	    ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
	    ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
	    ['HH:mm:ss', /\d\d:\d\d:\d\d/],
	    ['HH:mm', /\d\d:\d\d/],
	    ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
	    ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
	    ['HHmmss', /\d\d\d\d\d\d/],
	    ['HHmm', /\d\d\d\d/],
	    ['HH', /\d\d/]
	];
	
	var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
	
	// date from iso format
	function configFromISO(config) {
	    var i, l,
	        string = config._i,
	        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
	        allowTime, dateFormat, timeFormat, tzFormat;
	
	    if (match) {
	        getParsingFlags(config).iso = true;
	
	        for (i = 0, l = isoDates.length; i < l; i++) {
	            if (isoDates[i][1].exec(match[1])) {
	                dateFormat = isoDates[i][0];
	                allowTime = isoDates[i][2] !== false;
	                break;
	            }
	        }
	        if (dateFormat == null) {
	            config._isValid = false;
	            return;
	        }
	        if (match[3]) {
	            for (i = 0, l = isoTimes.length; i < l; i++) {
	                if (isoTimes[i][1].exec(match[3])) {
	                    // match[2] should be 'T' or space
	                    timeFormat = (match[2] || ' ') + isoTimes[i][0];
	                    break;
	                }
	            }
	            if (timeFormat == null) {
	                config._isValid = false;
	                return;
	            }
	        }
	        if (!allowTime && timeFormat != null) {
	            config._isValid = false;
	            return;
	        }
	        if (match[4]) {
	            if (tzRegex.exec(match[4])) {
	                tzFormat = 'Z';
	            } else {
	                config._isValid = false;
	                return;
	            }
	        }
	        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
	        configFromStringAndFormat(config);
	    } else {
	        config._isValid = false;
	    }
	}
	
	// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
	var basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;
	
	// date and time from ref 2822 format
	function configFromRFC2822(config) {
	    var string, match, dayFormat,
	        dateFormat, timeFormat, tzFormat;
	    var timezones = {
	        ' GMT': ' +0000',
	        ' EDT': ' -0400',
	        ' EST': ' -0500',
	        ' CDT': ' -0500',
	        ' CST': ' -0600',
	        ' MDT': ' -0600',
	        ' MST': ' -0700',
	        ' PDT': ' -0700',
	        ' PST': ' -0800'
	    };
	    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';
	    var timezone, timezoneIndex;
	
	    string = config._i
	        .replace(/\([^\)]*\)|[\n\t]/g, ' ') // Remove comments and folding whitespace
	        .replace(/(\s\s+)/g, ' ') // Replace multiple-spaces with a single space
	        .replace(/^\s|\s$/g, ''); // Remove leading and trailing spaces
	    match = basicRfcRegex.exec(string);
	
	    if (match) {
	        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';
	        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');
	        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');
	
	        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
	        if (match[1]) { // day of week given
	            var momentDate = new Date(match[2]);
	            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];
	
	            if (match[1].substr(0,3) !== momentDay) {
	                getParsingFlags(config).weekdayMismatch = true;
	                config._isValid = false;
	                return;
	            }
	        }
	
	        switch (match[5].length) {
	            case 2: // military
	                if (timezoneIndex === 0) {
	                    timezone = ' +0000';
	                } else {
	                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;
	                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +
	                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';
	                }
	                break;
	            case 4: // Zone
	                timezone = timezones[match[5]];
	                break;
	            default: // UT or +/-9999
	                timezone = timezones[' GMT'];
	        }
	        match[5] = timezone;
	        config._i = match.splice(1).join('');
	        tzFormat = ' ZZ';
	        config._f = dayFormat + dateFormat + timeFormat + tzFormat;
	        configFromStringAndFormat(config);
	        getParsingFlags(config).rfc2822 = true;
	    } else {
	        config._isValid = false;
	    }
	}
	
	// date from iso format or fallback
	function configFromString(config) {
	    var matched = aspNetJsonRegex.exec(config._i);
	
	    if (matched !== null) {
	        config._d = new Date(+matched[1]);
	        return;
	    }
	
	    configFromISO(config);
	    if (config._isValid === false) {
	        delete config._isValid;
	    } else {
	        return;
	    }
	
	    configFromRFC2822(config);
	    if (config._isValid === false) {
	        delete config._isValid;
	    } else {
	        return;
	    }
	
	    // Final attempt, use Input Fallback
	    hooks.createFromInputFallback(config);
	}
	
	hooks.createFromInputFallback = deprecate(
	    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
	    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
	    'discouraged and will be removed in an upcoming major release. Please refer to ' +
	    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
	    function (config) {
	        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
	    }
	);
	
	// Pick the first defined of two or three arguments.
	function defaults(a, b, c) {
	    if (a != null) {
	        return a;
	    }
	    if (b != null) {
	        return b;
	    }
	    return c;
	}
	
	function currentDateArray(config) {
	    // hooks is actually the exported moment object
	    var nowValue = new Date(hooks.now());
	    if (config._useUTC) {
	        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
	    }
	    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
	}
	
	// convert an array to a date.
	// the array should mirror the parameters below
	// note: all values past the year are optional and will default to the lowest possible value.
	// [year, month, day , hour, minute, second, millisecond]
	function configFromArray (config) {
	    var i, date, input = [], currentDate, yearToUse;
	
	    if (config._d) {
	        return;
	    }
	
	    currentDate = currentDateArray(config);
	
	    //compute day of the year from weeks and weekdays
	    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
	        dayOfYearFromWeekInfo(config);
	    }
	
	    //if the day of the year is set, figure out what it is
	    if (config._dayOfYear != null) {
	        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
	
	        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
	            getParsingFlags(config)._overflowDayOfYear = true;
	        }
	
	        date = createUTCDate(yearToUse, 0, config._dayOfYear);
	        config._a[MONTH] = date.getUTCMonth();
	        config._a[DATE] = date.getUTCDate();
	    }
	
	    // Default to current date.
	    // * if no year, month, day of month are given, default to today
	    // * if day of month is given, default month and year
	    // * if month is given, default only year
	    // * if year is given, don't default anything
	    for (i = 0; i < 3 && config._a[i] == null; ++i) {
	        config._a[i] = input[i] = currentDate[i];
	    }
	
	    // Zero out whatever was not defaulted, including time
	    for (; i < 7; i++) {
	        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
	    }
	
	    // Check for 24:00:00.000
	    if (config._a[HOUR] === 24 &&
	            config._a[MINUTE] === 0 &&
	            config._a[SECOND] === 0 &&
	            config._a[MILLISECOND] === 0) {
	        config._nextDay = true;
	        config._a[HOUR] = 0;
	    }
	
	    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
	    // Apply timezone offset from input. The actual utcOffset can be changed
	    // with parseZone.
	    if (config._tzm != null) {
	        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
	    }
	
	    if (config._nextDay) {
	        config._a[HOUR] = 24;
	    }
	}
	
	function dayOfYearFromWeekInfo(config) {
	    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
	
	    w = config._w;
	    if (w.GG != null || w.W != null || w.E != null) {
	        dow = 1;
	        doy = 4;
	
	        // TODO: We need to take the current isoWeekYear, but that depends on
	        // how we interpret now (local, utc, fixed offset). So create
	        // a now version of current config (take local/utc/offset flags, and
	        // create now).
	        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
	        week = defaults(w.W, 1);
	        weekday = defaults(w.E, 1);
	        if (weekday < 1 || weekday > 7) {
	            weekdayOverflow = true;
	        }
	    } else {
	        dow = config._locale._week.dow;
	        doy = config._locale._week.doy;
	
	        var curWeek = weekOfYear(createLocal(), dow, doy);
	
	        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
	
	        // Default to current week.
	        week = defaults(w.w, curWeek.week);
	
	        if (w.d != null) {
	            // weekday -- low day numbers are considered next week
	            weekday = w.d;
	            if (weekday < 0 || weekday > 6) {
	                weekdayOverflow = true;
	            }
	        } else if (w.e != null) {
	            // local weekday -- counting starts from begining of week
	            weekday = w.e + dow;
	            if (w.e < 0 || w.e > 6) {
	                weekdayOverflow = true;
	            }
	        } else {
	            // default to begining of week
	            weekday = dow;
	        }
	    }
	    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
	        getParsingFlags(config)._overflowWeeks = true;
	    } else if (weekdayOverflow != null) {
	        getParsingFlags(config)._overflowWeekday = true;
	    } else {
	        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
	        config._a[YEAR] = temp.year;
	        config._dayOfYear = temp.dayOfYear;
	    }
	}
	
	// constant that refers to the ISO standard
	hooks.ISO_8601 = function () {};
	
	// constant that refers to the RFC 2822 form
	hooks.RFC_2822 = function () {};
	
	// date from string and format string
	function configFromStringAndFormat(config) {
	    // TODO: Move this to another part of the creation flow to prevent circular deps
	    if (config._f === hooks.ISO_8601) {
	        configFromISO(config);
	        return;
	    }
	    if (config._f === hooks.RFC_2822) {
	        configFromRFC2822(config);
	        return;
	    }
	    config._a = [];
	    getParsingFlags(config).empty = true;
	
	    // This array is used to make a Date, either with `new Date` or `Date.UTC`
	    var string = '' + config._i,
	        i, parsedInput, tokens, token, skipped,
	        stringLength = string.length,
	        totalParsedInputLength = 0;
	
	    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
	
	    for (i = 0; i < tokens.length; i++) {
	        token = tokens[i];
	        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
	        // console.log('token', token, 'parsedInput', parsedInput,
	        //         'regex', getParseRegexForToken(token, config));
	        if (parsedInput) {
	            skipped = string.substr(0, string.indexOf(parsedInput));
	            if (skipped.length > 0) {
	                getParsingFlags(config).unusedInput.push(skipped);
	            }
	            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
	            totalParsedInputLength += parsedInput.length;
	        }
	        // don't parse if it's not a known token
	        if (formatTokenFunctions[token]) {
	            if (parsedInput) {
	                getParsingFlags(config).empty = false;
	            }
	            else {
	                getParsingFlags(config).unusedTokens.push(token);
	            }
	            addTimeToArrayFromToken(token, parsedInput, config);
	        }
	        else if (config._strict && !parsedInput) {
	            getParsingFlags(config).unusedTokens.push(token);
	        }
	    }
	
	    // add remaining unparsed input length to the string
	    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
	    if (string.length > 0) {
	        getParsingFlags(config).unusedInput.push(string);
	    }
	
	    // clear _12h flag if hour is <= 12
	    if (config._a[HOUR] <= 12 &&
	        getParsingFlags(config).bigHour === true &&
	        config._a[HOUR] > 0) {
	        getParsingFlags(config).bigHour = undefined;
	    }
	
	    getParsingFlags(config).parsedDateParts = config._a.slice(0);
	    getParsingFlags(config).meridiem = config._meridiem;
	    // handle meridiem
	    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
	
	    configFromArray(config);
	    checkOverflow(config);
	}
	
	
	function meridiemFixWrap (locale, hour, meridiem) {
	    var isPm;
	
	    if (meridiem == null) {
	        // nothing to do
	        return hour;
	    }
	    if (locale.meridiemHour != null) {
	        return locale.meridiemHour(hour, meridiem);
	    } else if (locale.isPM != null) {
	        // Fallback
	        isPm = locale.isPM(meridiem);
	        if (isPm && hour < 12) {
	            hour += 12;
	        }
	        if (!isPm && hour === 12) {
	            hour = 0;
	        }
	        return hour;
	    } else {
	        // this is not supposed to happen
	        return hour;
	    }
	}
	
	// date from string and array of format strings
	function configFromStringAndArray(config) {
	    var tempConfig,
	        bestMoment,
	
	        scoreToBeat,
	        i,
	        currentScore;
	
	    if (config._f.length === 0) {
	        getParsingFlags(config).invalidFormat = true;
	        config._d = new Date(NaN);
	        return;
	    }
	
	    for (i = 0; i < config._f.length; i++) {
	        currentScore = 0;
	        tempConfig = copyConfig({}, config);
	        if (config._useUTC != null) {
	            tempConfig._useUTC = config._useUTC;
	        }
	        tempConfig._f = config._f[i];
	        configFromStringAndFormat(tempConfig);
	
	        if (!isValid(tempConfig)) {
	            continue;
	        }
	
	        // if there is any input that was not parsed add a penalty for that format
	        currentScore += getParsingFlags(tempConfig).charsLeftOver;
	
	        //or tokens
	        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
	
	        getParsingFlags(tempConfig).score = currentScore;
	
	        if (scoreToBeat == null || currentScore < scoreToBeat) {
	            scoreToBeat = currentScore;
	            bestMoment = tempConfig;
	        }
	    }
	
	    extend(config, bestMoment || tempConfig);
	}
	
	function configFromObject(config) {
	    if (config._d) {
	        return;
	    }
	
	    var i = normalizeObjectUnits(config._i);
	    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
	        return obj && parseInt(obj, 10);
	    });
	
	    configFromArray(config);
	}
	
	function createFromConfig (config) {
	    var res = new Moment(checkOverflow(prepareConfig(config)));
	    if (res._nextDay) {
	        // Adding is smart enough around DST
	        res.add(1, 'd');
	        res._nextDay = undefined;
	    }
	
	    return res;
	}
	
	function prepareConfig (config) {
	    var input = config._i,
	        format = config._f;
	
	    config._locale = config._locale || getLocale(config._l);
	
	    if (input === null || (format === undefined && input === '')) {
	        return createInvalid({nullInput: true});
	    }
	
	    if (typeof input === 'string') {
	        config._i = input = config._locale.preparse(input);
	    }
	
	    if (isMoment(input)) {
	        return new Moment(checkOverflow(input));
	    } else if (isDate(input)) {
	        config._d = input;
	    } else if (isArray(format)) {
	        configFromStringAndArray(config);
	    } else if (format) {
	        configFromStringAndFormat(config);
	    }  else {
	        configFromInput(config);
	    }
	
	    if (!isValid(config)) {
	        config._d = null;
	    }
	
	    return config;
	}
	
	function configFromInput(config) {
	    var input = config._i;
	    if (isUndefined(input)) {
	        config._d = new Date(hooks.now());
	    } else if (isDate(input)) {
	        config._d = new Date(input.valueOf());
	    } else if (typeof input === 'string') {
	        configFromString(config);
	    } else if (isArray(input)) {
	        config._a = map(input.slice(0), function (obj) {
	            return parseInt(obj, 10);
	        });
	        configFromArray(config);
	    } else if (isObject(input)) {
	        configFromObject(config);
	    } else if (isNumber(input)) {
	        // from milliseconds
	        config._d = new Date(input);
	    } else {
	        hooks.createFromInputFallback(config);
	    }
	}
	
	function createLocalOrUTC (input, format, locale, strict, isUTC) {
	    var c = {};
	
	    if (locale === true || locale === false) {
	        strict = locale;
	        locale = undefined;
	    }
	
	    if ((isObject(input) && isObjectEmpty(input)) ||
	            (isArray(input) && input.length === 0)) {
	        input = undefined;
	    }
	    // object construction must be done this way.
	    // https://github.com/moment/moment/issues/1423
	    c._isAMomentObject = true;
	    c._useUTC = c._isUTC = isUTC;
	    c._l = locale;
	    c._i = input;
	    c._f = format;
	    c._strict = strict;
	
	    return createFromConfig(c);
	}
	
	function createLocal (input, format, locale, strict) {
	    return createLocalOrUTC(input, format, locale, strict, false);
	}
	
	var prototypeMin = deprecate(
	    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
	    function () {
	        var other = createLocal.apply(null, arguments);
	        if (this.isValid() && other.isValid()) {
	            return other < this ? this : other;
	        } else {
	            return createInvalid();
	        }
	    }
	);
	
	var prototypeMax = deprecate(
	    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
	    function () {
	        var other = createLocal.apply(null, arguments);
	        if (this.isValid() && other.isValid()) {
	            return other > this ? this : other;
	        } else {
	            return createInvalid();
	        }
	    }
	);
	
	// Pick a moment m from moments so that m[fn](other) is true for all
	// other. This relies on the function fn to be transitive.
	//
	// moments should either be an array of moment objects or an array, whose
	// first element is an array of moment objects.
	function pickBy(fn, moments) {
	    var res, i;
	    if (moments.length === 1 && isArray(moments[0])) {
	        moments = moments[0];
	    }
	    if (!moments.length) {
	        return createLocal();
	    }
	    res = moments[0];
	    for (i = 1; i < moments.length; ++i) {
	        if (!moments[i].isValid() || moments[i][fn](res)) {
	            res = moments[i];
	        }
	    }
	    return res;
	}
	
	// TODO: Use [].sort instead?
	function min () {
	    var args = [].slice.call(arguments, 0);
	
	    return pickBy('isBefore', args);
	}
	
	function max () {
	    var args = [].slice.call(arguments, 0);
	
	    return pickBy('isAfter', args);
	}
	
	var now = function () {
	    return Date.now ? Date.now() : +(new Date());
	};
	
	var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
	
	function isDurationValid(m) {
	    for (var key in m) {
	        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
	            return false;
	        }
	    }
	
	    var unitHasDecimal = false;
	    for (var i = 0; i < ordering.length; ++i) {
	        if (m[ordering[i]]) {
	            if (unitHasDecimal) {
	                return false; // only allow non-integers for smallest unit
	            }
	            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
	                unitHasDecimal = true;
	            }
	        }
	    }
	
	    return true;
	}
	
	function isValid$1() {
	    return this._isValid;
	}
	
	function createInvalid$1() {
	    return createDuration(NaN);
	}
	
	function Duration (duration) {
	    var normalizedInput = normalizeObjectUnits(duration),
	        years = normalizedInput.year || 0,
	        quarters = normalizedInput.quarter || 0,
	        months = normalizedInput.month || 0,
	        weeks = normalizedInput.week || 0,
	        days = normalizedInput.day || 0,
	        hours = normalizedInput.hour || 0,
	        minutes = normalizedInput.minute || 0,
	        seconds = normalizedInput.second || 0,
	        milliseconds = normalizedInput.millisecond || 0;
	
	    this._isValid = isDurationValid(normalizedInput);
	
	    // representation for dateAddRemove
	    this._milliseconds = +milliseconds +
	        seconds * 1e3 + // 1000
	        minutes * 6e4 + // 1000 * 60
	        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
	    // Because of dateAddRemove treats 24 hours as different from a
	    // day when working around DST, we need to store them separately
	    this._days = +days +
	        weeks * 7;
	    // It is impossible translate months into days without knowing
	    // which months you are are talking about, so we have to store
	    // it separately.
	    this._months = +months +
	        quarters * 3 +
	        years * 12;
	
	    this._data = {};
	
	    this._locale = getLocale();
	
	    this._bubble();
	}
	
	function isDuration (obj) {
	    return obj instanceof Duration;
	}
	
	function absRound (number) {
	    if (number < 0) {
	        return Math.round(-1 * number) * -1;
	    } else {
	        return Math.round(number);
	    }
	}
	
	// FORMATTING
	
	function offset (token, separator) {
	    addFormatToken(token, 0, 0, function () {
	        var offset = this.utcOffset();
	        var sign = '+';
	        if (offset < 0) {
	            offset = -offset;
	            sign = '-';
	        }
	        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
	    });
	}
	
	offset('Z', ':');
	offset('ZZ', '');
	
	// PARSING
	
	addRegexToken('Z',  matchShortOffset);
	addRegexToken('ZZ', matchShortOffset);
	addParseToken(['Z', 'ZZ'], function (input, array, config) {
	    config._useUTC = true;
	    config._tzm = offsetFromString(matchShortOffset, input);
	});
	
	// HELPERS
	
	// timezone chunker
	// '+10:00' > ['10',  '00']
	// '-1530'  > ['-15', '30']
	var chunkOffset = /([\+\-]|\d\d)/gi;
	
	function offsetFromString(matcher, string) {
	    var matches = (string || '').match(matcher);
	
	    if (matches === null) {
	        return null;
	    }
	
	    var chunk   = matches[matches.length - 1] || [];
	    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
	    var minutes = +(parts[1] * 60) + toInt(parts[2]);
	
	    return minutes === 0 ?
	      0 :
	      parts[0] === '+' ? minutes : -minutes;
	}
	
	// Return a moment from input, that is local/utc/zone equivalent to model.
	function cloneWithOffset(input, model) {
	    var res, diff;
	    if (model._isUTC) {
	        res = model.clone();
	        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
	        // Use low-level api, because this fn is low-level api.
	        res._d.setTime(res._d.valueOf() + diff);
	        hooks.updateOffset(res, false);
	        return res;
	    } else {
	        return createLocal(input).local();
	    }
	}
	
	function getDateOffset (m) {
	    // On Firefox.24 Date#getTimezoneOffset returns a floating point.
	    // https://github.com/moment/moment/pull/1871
	    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
	}
	
	// HOOKS
	
	// This function will be called whenever a moment is mutated.
	// It is intended to keep the offset in sync with the timezone.
	hooks.updateOffset = function () {};
	
	// MOMENTS
	
	// keepLocalTime = true means only change the timezone, without
	// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
	// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
	// +0200, so we adjust the time as needed, to be valid.
	//
	// Keeping the time actually adds/subtracts (one hour)
	// from the actual represented time. That is why we call updateOffset
	// a second time. In case it wants us to change the offset again
	// _changeInProgress == true case, then we have to adjust, because
	// there is no such time in the given timezone.
	function getSetOffset (input, keepLocalTime, keepMinutes) {
	    var offset = this._offset || 0,
	        localAdjust;
	    if (!this.isValid()) {
	        return input != null ? this : NaN;
	    }
	    if (input != null) {
	        if (typeof input === 'string') {
	            input = offsetFromString(matchShortOffset, input);
	            if (input === null) {
	                return this;
	            }
	        } else if (Math.abs(input) < 16 && !keepMinutes) {
	            input = input * 60;
	        }
	        if (!this._isUTC && keepLocalTime) {
	            localAdjust = getDateOffset(this);
	        }
	        this._offset = input;
	        this._isUTC = true;
	        if (localAdjust != null) {
	            this.add(localAdjust, 'm');
	        }
	        if (offset !== input) {
	            if (!keepLocalTime || this._changeInProgress) {
	                addSubtract(this, createDuration(input - offset, 'm'), 1, false);
	            } else if (!this._changeInProgress) {
	                this._changeInProgress = true;
	                hooks.updateOffset(this, true);
	                this._changeInProgress = null;
	            }
	        }
	        return this;
	    } else {
	        return this._isUTC ? offset : getDateOffset(this);
	    }
	}
	
	function getSetZone (input, keepLocalTime) {
	    if (input != null) {
	        if (typeof input !== 'string') {
	            input = -input;
	        }
	
	        this.utcOffset(input, keepLocalTime);
	
	        return this;
	    } else {
	        return -this.utcOffset();
	    }
	}
	
	function setOffsetToUTC (keepLocalTime) {
	    return this.utcOffset(0, keepLocalTime);
	}
	
	function setOffsetToLocal (keepLocalTime) {
	    if (this._isUTC) {
	        this.utcOffset(0, keepLocalTime);
	        this._isUTC = false;
	
	        if (keepLocalTime) {
	            this.subtract(getDateOffset(this), 'm');
	        }
	    }
	    return this;
	}
	
	function setOffsetToParsedOffset () {
	    if (this._tzm != null) {
	        this.utcOffset(this._tzm, false, true);
	    } else if (typeof this._i === 'string') {
	        var tZone = offsetFromString(matchOffset, this._i);
	        if (tZone != null) {
	            this.utcOffset(tZone);
	        }
	        else {
	            this.utcOffset(0, true);
	        }
	    }
	    return this;
	}
	
	function hasAlignedHourOffset (input) {
	    if (!this.isValid()) {
	        return false;
	    }
	    input = input ? createLocal(input).utcOffset() : 0;
	
	    return (this.utcOffset() - input) % 60 === 0;
	}
	
	function isDaylightSavingTime () {
	    return (
	        this.utcOffset() > this.clone().month(0).utcOffset() ||
	        this.utcOffset() > this.clone().month(5).utcOffset()
	    );
	}
	
	function isDaylightSavingTimeShifted () {
	    if (!isUndefined(this._isDSTShifted)) {
	        return this._isDSTShifted;
	    }
	
	    var c = {};
	
	    copyConfig(c, this);
	    c = prepareConfig(c);
	
	    if (c._a) {
	        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
	        this._isDSTShifted = this.isValid() &&
	            compareArrays(c._a, other.toArray()) > 0;
	    } else {
	        this._isDSTShifted = false;
	    }
	
	    return this._isDSTShifted;
	}
	
	function isLocal () {
	    return this.isValid() ? !this._isUTC : false;
	}
	
	function isUtcOffset () {
	    return this.isValid() ? this._isUTC : false;
	}
	
	function isUtc () {
	    return this.isValid() ? this._isUTC && this._offset === 0 : false;
	}
	
	// ASP.NET json date format regex
	var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
	
	// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
	// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
	// and further modified to allow for strings containing both week and day
	var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
	
	function createDuration (input, key) {
	    var duration = input,
	        // matching against regexp is expensive, do it on demand
	        match = null,
	        sign,
	        ret,
	        diffRes;
	
	    if (isDuration(input)) {
	        duration = {
	            ms : input._milliseconds,
	            d  : input._days,
	            M  : input._months
	        };
	    } else if (isNumber(input)) {
	        duration = {};
	        if (key) {
	            duration[key] = input;
	        } else {
	            duration.milliseconds = input;
	        }
	    } else if (!!(match = aspNetRegex.exec(input))) {
	        sign = (match[1] === '-') ? -1 : 1;
	        duration = {
	            y  : 0,
	            d  : toInt(match[DATE])                         * sign,
	            h  : toInt(match[HOUR])                         * sign,
	            m  : toInt(match[MINUTE])                       * sign,
	            s  : toInt(match[SECOND])                       * sign,
	            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
	        };
	    } else if (!!(match = isoRegex.exec(input))) {
	        sign = (match[1] === '-') ? -1 : 1;
	        duration = {
	            y : parseIso(match[2], sign),
	            M : parseIso(match[3], sign),
	            w : parseIso(match[4], sign),
	            d : parseIso(match[5], sign),
	            h : parseIso(match[6], sign),
	            m : parseIso(match[7], sign),
	            s : parseIso(match[8], sign)
	        };
	    } else if (duration == null) {// checks for null or undefined
	        duration = {};
	    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
	        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
	
	        duration = {};
	        duration.ms = diffRes.milliseconds;
	        duration.M = diffRes.months;
	    }
	
	    ret = new Duration(duration);
	
	    if (isDuration(input) && hasOwnProp(input, '_locale')) {
	        ret._locale = input._locale;
	    }
	
	    return ret;
	}
	
	createDuration.fn = Duration.prototype;
	createDuration.invalid = createInvalid$1;
	
	function parseIso (inp, sign) {
	    // We'd normally use ~~inp for this, but unfortunately it also
	    // converts floats to ints.
	    // inp may be undefined, so careful calling replace on it.
	    var res = inp && parseFloat(inp.replace(',', '.'));
	    // apply sign while we're at it
	    return (isNaN(res) ? 0 : res) * sign;
	}
	
	function positiveMomentsDifference(base, other) {
	    var res = {milliseconds: 0, months: 0};
	
	    res.months = other.month() - base.month() +
	        (other.year() - base.year()) * 12;
	    if (base.clone().add(res.months, 'M').isAfter(other)) {
	        --res.months;
	    }
	
	    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
	
	    return res;
	}
	
	function momentsDifference(base, other) {
	    var res;
	    if (!(base.isValid() && other.isValid())) {
	        return {milliseconds: 0, months: 0};
	    }
	
	    other = cloneWithOffset(other, base);
	    if (base.isBefore(other)) {
	        res = positiveMomentsDifference(base, other);
	    } else {
	        res = positiveMomentsDifference(other, base);
	        res.milliseconds = -res.milliseconds;
	        res.months = -res.months;
	    }
	
	    return res;
	}
	
	// TODO: remove 'name' arg after deprecation is removed
	function createAdder(direction, name) {
	    return function (val, period) {
	        var dur, tmp;
	        //invert the arguments, but complain about it
	        if (period !== null && !isNaN(+period)) {
	            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
	            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
	            tmp = val; val = period; period = tmp;
	        }
	
	        val = typeof val === 'string' ? +val : val;
	        dur = createDuration(val, period);
	        addSubtract(this, dur, direction);
	        return this;
	    };
	}
	
	function addSubtract (mom, duration, isAdding, updateOffset) {
	    var milliseconds = duration._milliseconds,
	        days = absRound(duration._days),
	        months = absRound(duration._months);
	
	    if (!mom.isValid()) {
	        // No op
	        return;
	    }
	
	    updateOffset = updateOffset == null ? true : updateOffset;
	
	    if (milliseconds) {
	        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
	    }
	    if (days) {
	        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
	    }
	    if (months) {
	        setMonth(mom, get(mom, 'Month') + months * isAdding);
	    }
	    if (updateOffset) {
	        hooks.updateOffset(mom, days || months);
	    }
	}
	
	var add      = createAdder(1, 'add');
	var subtract = createAdder(-1, 'subtract');
	
	function getCalendarFormat(myMoment, now) {
	    var diff = myMoment.diff(now, 'days', true);
	    return diff < -6 ? 'sameElse' :
	            diff < -1 ? 'lastWeek' :
	            diff < 0 ? 'lastDay' :
	            diff < 1 ? 'sameDay' :
	            diff < 2 ? 'nextDay' :
	            diff < 7 ? 'nextWeek' : 'sameElse';
	}
	
	function calendar$1 (time, formats) {
	    // We want to compare the start of today, vs this.
	    // Getting start-of-today depends on whether we're local/utc/offset or not.
	    var now = time || createLocal(),
	        sod = cloneWithOffset(now, this).startOf('day'),
	        format = hooks.calendarFormat(this, sod) || 'sameElse';
	
	    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
	
	    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
	}
	
	function clone () {
	    return new Moment(this);
	}
	
	function isAfter (input, units) {
	    var localInput = isMoment(input) ? input : createLocal(input);
	    if (!(this.isValid() && localInput.isValid())) {
	        return false;
	    }
	    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
	    if (units === 'millisecond') {
	        return this.valueOf() > localInput.valueOf();
	    } else {
	        return localInput.valueOf() < this.clone().startOf(units).valueOf();
	    }
	}
	
	function isBefore (input, units) {
	    var localInput = isMoment(input) ? input : createLocal(input);
	    if (!(this.isValid() && localInput.isValid())) {
	        return false;
	    }
	    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
	    if (units === 'millisecond') {
	        return this.valueOf() < localInput.valueOf();
	    } else {
	        return this.clone().endOf(units).valueOf() < localInput.valueOf();
	    }
	}
	
	function isBetween (from, to, units, inclusivity) {
	    inclusivity = inclusivity || '()';
	    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
	        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
	}
	
	function isSame (input, units) {
	    var localInput = isMoment(input) ? input : createLocal(input),
	        inputMs;
	    if (!(this.isValid() && localInput.isValid())) {
	        return false;
	    }
	    units = normalizeUnits(units || 'millisecond');
	    if (units === 'millisecond') {
	        return this.valueOf() === localInput.valueOf();
	    } else {
	        inputMs = localInput.valueOf();
	        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
	    }
	}
	
	function isSameOrAfter (input, units) {
	    return this.isSame(input, units) || this.isAfter(input,units);
	}
	
	function isSameOrBefore (input, units) {
	    return this.isSame(input, units) || this.isBefore(input,units);
	}
	
	function diff (input, units, asFloat) {
	    var that,
	        zoneDelta,
	        delta, output;
	
	    if (!this.isValid()) {
	        return NaN;
	    }
	
	    that = cloneWithOffset(input, this);
	
	    if (!that.isValid()) {
	        return NaN;
	    }
	
	    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
	
	    units = normalizeUnits(units);
	
	    if (units === 'year' || units === 'month' || units === 'quarter') {
	        output = monthDiff(this, that);
	        if (units === 'quarter') {
	            output = output / 3;
	        } else if (units === 'year') {
	            output = output / 12;
	        }
	    } else {
	        delta = this - that;
	        output = units === 'second' ? delta / 1e3 : // 1000
	            units === 'minute' ? delta / 6e4 : // 1000 * 60
	            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
	            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
	            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
	            delta;
	    }
	    return asFloat ? output : absFloor(output);
	}
	
	function monthDiff (a, b) {
	    // difference in months
	    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
	        // b is in (anchor - 1 month, anchor + 1 month)
	        anchor = a.clone().add(wholeMonthDiff, 'months'),
	        anchor2, adjust;
	
	    if (b - anchor < 0) {
	        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
	        // linear across the month
	        adjust = (b - anchor) / (anchor - anchor2);
	    } else {
	        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
	        // linear across the month
	        adjust = (b - anchor) / (anchor2 - anchor);
	    }
	
	    //check for negative zero, return zero if negative zero
	    return -(wholeMonthDiff + adjust) || 0;
	}
	
	hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
	hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
	
	function toString () {
	    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
	}
	
	function toISOString() {
	    if (!this.isValid()) {
	        return null;
	    }
	    var m = this.clone().utc();
	    if (m.year() < 0 || m.year() > 9999) {
	        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	    }
	    if (isFunction(Date.prototype.toISOString)) {
	        // native implementation is ~50x faster, use it when we can
	        return this.toDate().toISOString();
	    }
	    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
	}
	
	/**
	 * Return a human readable representation of a moment that can
	 * also be evaluated to get a new moment which is the same
	 *
	 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
	 */
	function inspect () {
	    if (!this.isValid()) {
	        return 'moment.invalid(/* ' + this._i + ' */)';
	    }
	    var func = 'moment';
	    var zone = '';
	    if (!this.isLocal()) {
	        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
	        zone = 'Z';
	    }
	    var prefix = '[' + func + '("]';
	    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
	    var datetime = '-MM-DD[T]HH:mm:ss.SSS';
	    var suffix = zone + '[")]';
	
	    return this.format(prefix + year + datetime + suffix);
	}
	
	function format (inputString) {
	    if (!inputString) {
	        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
	    }
	    var output = formatMoment(this, inputString);
	    return this.localeData().postformat(output);
	}
	
	function from (time, withoutSuffix) {
	    if (this.isValid() &&
	            ((isMoment(time) && time.isValid()) ||
	             createLocal(time).isValid())) {
	        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
	    } else {
	        return this.localeData().invalidDate();
	    }
	}
	
	function fromNow (withoutSuffix) {
	    return this.from(createLocal(), withoutSuffix);
	}
	
	function to (time, withoutSuffix) {
	    if (this.isValid() &&
	            ((isMoment(time) && time.isValid()) ||
	             createLocal(time).isValid())) {
	        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
	    } else {
	        return this.localeData().invalidDate();
	    }
	}
	
	function toNow (withoutSuffix) {
	    return this.to(createLocal(), withoutSuffix);
	}
	
	// If passed a locale key, it will set the locale for this
	// instance.  Otherwise, it will return the locale configuration
	// variables for this instance.
	function locale (key) {
	    var newLocaleData;
	
	    if (key === undefined) {
	        return this._locale._abbr;
	    } else {
	        newLocaleData = getLocale(key);
	        if (newLocaleData != null) {
	            this._locale = newLocaleData;
	        }
	        return this;
	    }
	}
	
	var lang = deprecate(
	    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
	    function (key) {
	        if (key === undefined) {
	            return this.localeData();
	        } else {
	            return this.locale(key);
	        }
	    }
	);
	
	function localeData () {
	    return this._locale;
	}
	
	function startOf (units) {
	    units = normalizeUnits(units);
	    // the following switch intentionally omits break keywords
	    // to utilize falling through the cases.
	    switch (units) {
	        case 'year':
	            this.month(0);
	            /* falls through */
	        case 'quarter':
	        case 'month':
	            this.date(1);
	            /* falls through */
	        case 'week':
	        case 'isoWeek':
	        case 'day':
	        case 'date':
	            this.hours(0);
	            /* falls through */
	        case 'hour':
	            this.minutes(0);
	            /* falls through */
	        case 'minute':
	            this.seconds(0);
	            /* falls through */
	        case 'second':
	            this.milliseconds(0);
	    }
	
	    // weeks are a special case
	    if (units === 'week') {
	        this.weekday(0);
	    }
	    if (units === 'isoWeek') {
	        this.isoWeekday(1);
	    }
	
	    // quarters are also special
	    if (units === 'quarter') {
	        this.month(Math.floor(this.month() / 3) * 3);
	    }
	
	    return this;
	}
	
	function endOf (units) {
	    units = normalizeUnits(units);
	    if (units === undefined || units === 'millisecond') {
	        return this;
	    }
	
	    // 'date' is an alias for 'day', so it should be considered as such.
	    if (units === 'date') {
	        units = 'day';
	    }
	
	    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
	}
	
	function valueOf () {
	    return this._d.valueOf() - ((this._offset || 0) * 60000);
	}
	
	function unix () {
	    return Math.floor(this.valueOf() / 1000);
	}
	
	function toDate () {
	    return new Date(this.valueOf());
	}
	
	function toArray () {
	    var m = this;
	    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
	}
	
	function toObject () {
	    var m = this;
	    return {
	        years: m.year(),
	        months: m.month(),
	        date: m.date(),
	        hours: m.hours(),
	        minutes: m.minutes(),
	        seconds: m.seconds(),
	        milliseconds: m.milliseconds()
	    };
	}
	
	function toJSON () {
	    // new Date(NaN).toJSON() === null
	    return this.isValid() ? this.toISOString() : null;
	}
	
	function isValid$2 () {
	    return isValid(this);
	}
	
	function parsingFlags () {
	    return extend({}, getParsingFlags(this));
	}
	
	function invalidAt () {
	    return getParsingFlags(this).overflow;
	}
	
	function creationData() {
	    return {
	        input: this._i,
	        format: this._f,
	        locale: this._locale,
	        isUTC: this._isUTC,
	        strict: this._strict
	    };
	}
	
	// FORMATTING
	
	addFormatToken(0, ['gg', 2], 0, function () {
	    return this.weekYear() % 100;
	});
	
	addFormatToken(0, ['GG', 2], 0, function () {
	    return this.isoWeekYear() % 100;
	});
	
	function addWeekYearFormatToken (token, getter) {
	    addFormatToken(0, [token, token.length], 0, getter);
	}
	
	addWeekYearFormatToken('gggg',     'weekYear');
	addWeekYearFormatToken('ggggg',    'weekYear');
	addWeekYearFormatToken('GGGG',  'isoWeekYear');
	addWeekYearFormatToken('GGGGG', 'isoWeekYear');
	
	// ALIASES
	
	addUnitAlias('weekYear', 'gg');
	addUnitAlias('isoWeekYear', 'GG');
	
	// PRIORITY
	
	addUnitPriority('weekYear', 1);
	addUnitPriority('isoWeekYear', 1);
	
	
	// PARSING
	
	addRegexToken('G',      matchSigned);
	addRegexToken('g',      matchSigned);
	addRegexToken('GG',     match1to2, match2);
	addRegexToken('gg',     match1to2, match2);
	addRegexToken('GGGG',   match1to4, match4);
	addRegexToken('gggg',   match1to4, match4);
	addRegexToken('GGGGG',  match1to6, match6);
	addRegexToken('ggggg',  match1to6, match6);
	
	addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
	    week[token.substr(0, 2)] = toInt(input);
	});
	
	addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
	    week[token] = hooks.parseTwoDigitYear(input);
	});
	
	// MOMENTS
	
	function getSetWeekYear (input) {
	    return getSetWeekYearHelper.call(this,
	            input,
	            this.week(),
	            this.weekday(),
	            this.localeData()._week.dow,
	            this.localeData()._week.doy);
	}
	
	function getSetISOWeekYear (input) {
	    return getSetWeekYearHelper.call(this,
	            input, this.isoWeek(), this.isoWeekday(), 1, 4);
	}
	
	function getISOWeeksInYear () {
	    return weeksInYear(this.year(), 1, 4);
	}
	
	function getWeeksInYear () {
	    var weekInfo = this.localeData()._week;
	    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
	}
	
	function getSetWeekYearHelper(input, week, weekday, dow, doy) {
	    var weeksTarget;
	    if (input == null) {
	        return weekOfYear(this, dow, doy).year;
	    } else {
	        weeksTarget = weeksInYear(input, dow, doy);
	        if (week > weeksTarget) {
	            week = weeksTarget;
	        }
	        return setWeekAll.call(this, input, week, weekday, dow, doy);
	    }
	}
	
	function setWeekAll(weekYear, week, weekday, dow, doy) {
	    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
	        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
	
	    this.year(date.getUTCFullYear());
	    this.month(date.getUTCMonth());
	    this.date(date.getUTCDate());
	    return this;
	}
	
	// FORMATTING
	
	addFormatToken('Q', 0, 'Qo', 'quarter');
	
	// ALIASES
	
	addUnitAlias('quarter', 'Q');
	
	// PRIORITY
	
	addUnitPriority('quarter', 7);
	
	// PARSING
	
	addRegexToken('Q', match1);
	addParseToken('Q', function (input, array) {
	    array[MONTH] = (toInt(input) - 1) * 3;
	});
	
	// MOMENTS
	
	function getSetQuarter (input) {
	    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
	}
	
	// FORMATTING
	
	addFormatToken('D', ['DD', 2], 'Do', 'date');
	
	// ALIASES
	
	addUnitAlias('date', 'D');
	
	// PRIOROITY
	addUnitPriority('date', 9);
	
	// PARSING
	
	addRegexToken('D',  match1to2);
	addRegexToken('DD', match1to2, match2);
	addRegexToken('Do', function (isStrict, locale) {
	    // TODO: Remove "ordinalParse" fallback in next major release.
	    return isStrict ?
	      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
	      locale._dayOfMonthOrdinalParseLenient;
	});
	
	addParseToken(['D', 'DD'], DATE);
	addParseToken('Do', function (input, array) {
	    array[DATE] = toInt(input.match(match1to2)[0], 10);
	});
	
	// MOMENTS
	
	var getSetDayOfMonth = makeGetSet('Date', true);
	
	// FORMATTING
	
	addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
	
	// ALIASES
	
	addUnitAlias('dayOfYear', 'DDD');
	
	// PRIORITY
	addUnitPriority('dayOfYear', 4);
	
	// PARSING
	
	addRegexToken('DDD',  match1to3);
	addRegexToken('DDDD', match3);
	addParseToken(['DDD', 'DDDD'], function (input, array, config) {
	    config._dayOfYear = toInt(input);
	});
	
	// HELPERS
	
	// MOMENTS
	
	function getSetDayOfYear (input) {
	    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
	    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
	}
	
	// FORMATTING
	
	addFormatToken('m', ['mm', 2], 0, 'minute');
	
	// ALIASES
	
	addUnitAlias('minute', 'm');
	
	// PRIORITY
	
	addUnitPriority('minute', 14);
	
	// PARSING
	
	addRegexToken('m',  match1to2);
	addRegexToken('mm', match1to2, match2);
	addParseToken(['m', 'mm'], MINUTE);
	
	// MOMENTS
	
	var getSetMinute = makeGetSet('Minutes', false);
	
	// FORMATTING
	
	addFormatToken('s', ['ss', 2], 0, 'second');
	
	// ALIASES
	
	addUnitAlias('second', 's');
	
	// PRIORITY
	
	addUnitPriority('second', 15);
	
	// PARSING
	
	addRegexToken('s',  match1to2);
	addRegexToken('ss', match1to2, match2);
	addParseToken(['s', 'ss'], SECOND);
	
	// MOMENTS
	
	var getSetSecond = makeGetSet('Seconds', false);
	
	// FORMATTING
	
	addFormatToken('S', 0, 0, function () {
	    return ~~(this.millisecond() / 100);
	});
	
	addFormatToken(0, ['SS', 2], 0, function () {
	    return ~~(this.millisecond() / 10);
	});
	
	addFormatToken(0, ['SSS', 3], 0, 'millisecond');
	addFormatToken(0, ['SSSS', 4], 0, function () {
	    return this.millisecond() * 10;
	});
	addFormatToken(0, ['SSSSS', 5], 0, function () {
	    return this.millisecond() * 100;
	});
	addFormatToken(0, ['SSSSSS', 6], 0, function () {
	    return this.millisecond() * 1000;
	});
	addFormatToken(0, ['SSSSSSS', 7], 0, function () {
	    return this.millisecond() * 10000;
	});
	addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
	    return this.millisecond() * 100000;
	});
	addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
	    return this.millisecond() * 1000000;
	});
	
	
	// ALIASES
	
	addUnitAlias('millisecond', 'ms');
	
	// PRIORITY
	
	addUnitPriority('millisecond', 16);
	
	// PARSING
	
	addRegexToken('S',    match1to3, match1);
	addRegexToken('SS',   match1to3, match2);
	addRegexToken('SSS',  match1to3, match3);
	
	var token;
	for (token = 'SSSS'; token.length <= 9; token += 'S') {
	    addRegexToken(token, matchUnsigned);
	}
	
	function parseMs(input, array) {
	    array[MILLISECOND] = toInt(('0.' + input) * 1000);
	}
	
	for (token = 'S'; token.length <= 9; token += 'S') {
	    addParseToken(token, parseMs);
	}
	// MOMENTS
	
	var getSetMillisecond = makeGetSet('Milliseconds', false);
	
	// FORMATTING
	
	addFormatToken('z',  0, 0, 'zoneAbbr');
	addFormatToken('zz', 0, 0, 'zoneName');
	
	// MOMENTS
	
	function getZoneAbbr () {
	    return this._isUTC ? 'UTC' : '';
	}
	
	function getZoneName () {
	    return this._isUTC ? 'Coordinated Universal Time' : '';
	}
	
	var proto = Moment.prototype;
	
	proto.add               = add;
	proto.calendar          = calendar$1;
	proto.clone             = clone;
	proto.diff              = diff;
	proto.endOf             = endOf;
	proto.format            = format;
	proto.from              = from;
	proto.fromNow           = fromNow;
	proto.to                = to;
	proto.toNow             = toNow;
	proto.get               = stringGet;
	proto.invalidAt         = invalidAt;
	proto.isAfter           = isAfter;
	proto.isBefore          = isBefore;
	proto.isBetween         = isBetween;
	proto.isSame            = isSame;
	proto.isSameOrAfter     = isSameOrAfter;
	proto.isSameOrBefore    = isSameOrBefore;
	proto.isValid           = isValid$2;
	proto.lang              = lang;
	proto.locale            = locale;
	proto.localeData        = localeData;
	proto.max               = prototypeMax;
	proto.min               = prototypeMin;
	proto.parsingFlags      = parsingFlags;
	proto.set               = stringSet;
	proto.startOf           = startOf;
	proto.subtract          = subtract;
	proto.toArray           = toArray;
	proto.toObject          = toObject;
	proto.toDate            = toDate;
	proto.toISOString       = toISOString;
	proto.inspect           = inspect;
	proto.toJSON            = toJSON;
	proto.toString          = toString;
	proto.unix              = unix;
	proto.valueOf           = valueOf;
	proto.creationData      = creationData;
	
	// Year
	proto.year       = getSetYear;
	proto.isLeapYear = getIsLeapYear;
	
	// Week Year
	proto.weekYear    = getSetWeekYear;
	proto.isoWeekYear = getSetISOWeekYear;
	
	// Quarter
	proto.quarter = proto.quarters = getSetQuarter;
	
	// Month
	proto.month       = getSetMonth;
	proto.daysInMonth = getDaysInMonth;
	
	// Week
	proto.week           = proto.weeks        = getSetWeek;
	proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
	proto.weeksInYear    = getWeeksInYear;
	proto.isoWeeksInYear = getISOWeeksInYear;
	
	// Day
	proto.date       = getSetDayOfMonth;
	proto.day        = proto.days             = getSetDayOfWeek;
	proto.weekday    = getSetLocaleDayOfWeek;
	proto.isoWeekday = getSetISODayOfWeek;
	proto.dayOfYear  = getSetDayOfYear;
	
	// Hour
	proto.hour = proto.hours = getSetHour;
	
	// Minute
	proto.minute = proto.minutes = getSetMinute;
	
	// Second
	proto.second = proto.seconds = getSetSecond;
	
	// Millisecond
	proto.millisecond = proto.milliseconds = getSetMillisecond;
	
	// Offset
	proto.utcOffset            = getSetOffset;
	proto.utc                  = setOffsetToUTC;
	proto.local                = setOffsetToLocal;
	proto.parseZone            = setOffsetToParsedOffset;
	proto.hasAlignedHourOffset = hasAlignedHourOffset;
	proto.isDST                = isDaylightSavingTime;
	proto.isLocal              = isLocal;
	proto.isUtcOffset          = isUtcOffset;
	proto.isUtc                = isUtc;
	proto.isUTC                = isUtc;
	
	// Timezone
	proto.zoneAbbr = getZoneAbbr;
	proto.zoneName = getZoneName;
	
	// Deprecations
	proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
	proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
	proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
	proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
	proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
	
	function createUnix (input) {
	    return createLocal(input * 1000);
	}
	
	function createInZone () {
	    return createLocal.apply(null, arguments).parseZone();
	}
	
	function preParsePostFormat (string) {
	    return string;
	}
	
	var proto$1 = Locale.prototype;
	
	proto$1.calendar        = calendar;
	proto$1.longDateFormat  = longDateFormat;
	proto$1.invalidDate     = invalidDate;
	proto$1.ordinal         = ordinal;
	proto$1.preparse        = preParsePostFormat;
	proto$1.postformat      = preParsePostFormat;
	proto$1.relativeTime    = relativeTime;
	proto$1.pastFuture      = pastFuture;
	proto$1.set             = set;
	
	// Month
	proto$1.months            =        localeMonths;
	proto$1.monthsShort       =        localeMonthsShort;
	proto$1.monthsParse       =        localeMonthsParse;
	proto$1.monthsRegex       = monthsRegex;
	proto$1.monthsShortRegex  = monthsShortRegex;
	
	// Week
	proto$1.week = localeWeek;
	proto$1.firstDayOfYear = localeFirstDayOfYear;
	proto$1.firstDayOfWeek = localeFirstDayOfWeek;
	
	// Day of Week
	proto$1.weekdays       =        localeWeekdays;
	proto$1.weekdaysMin    =        localeWeekdaysMin;
	proto$1.weekdaysShort  =        localeWeekdaysShort;
	proto$1.weekdaysParse  =        localeWeekdaysParse;
	
	proto$1.weekdaysRegex       =        weekdaysRegex;
	proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
	proto$1.weekdaysMinRegex    =        weekdaysMinRegex;
	
	// Hours
	proto$1.isPM = localeIsPM;
	proto$1.meridiem = localeMeridiem;
	
	function get$1 (format, index, field, setter) {
	    var locale = getLocale();
	    var utc = createUTC().set(setter, index);
	    return locale[field](utc, format);
	}
	
	function listMonthsImpl (format, index, field) {
	    if (isNumber(format)) {
	        index = format;
	        format = undefined;
	    }
	
	    format = format || '';
	
	    if (index != null) {
	        return get$1(format, index, field, 'month');
	    }
	
	    var i;
	    var out = [];
	    for (i = 0; i < 12; i++) {
	        out[i] = get$1(format, i, field, 'month');
	    }
	    return out;
	}
	
	// ()
	// (5)
	// (fmt, 5)
	// (fmt)
	// (true)
	// (true, 5)
	// (true, fmt, 5)
	// (true, fmt)
	function listWeekdaysImpl (localeSorted, format, index, field) {
	    if (typeof localeSorted === 'boolean') {
	        if (isNumber(format)) {
	            index = format;
	            format = undefined;
	        }
	
	        format = format || '';
	    } else {
	        format = localeSorted;
	        index = format;
	        localeSorted = false;
	
	        if (isNumber(format)) {
	            index = format;
	            format = undefined;
	        }
	
	        format = format || '';
	    }
	
	    var locale = getLocale(),
	        shift = localeSorted ? locale._week.dow : 0;
	
	    if (index != null) {
	        return get$1(format, (index + shift) % 7, field, 'day');
	    }
	
	    var i;
	    var out = [];
	    for (i = 0; i < 7; i++) {
	        out[i] = get$1(format, (i + shift) % 7, field, 'day');
	    }
	    return out;
	}
	
	function listMonths (format, index) {
	    return listMonthsImpl(format, index, 'months');
	}
	
	function listMonthsShort (format, index) {
	    return listMonthsImpl(format, index, 'monthsShort');
	}
	
	function listWeekdays (localeSorted, format, index) {
	    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
	}
	
	function listWeekdaysShort (localeSorted, format, index) {
	    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
	}
	
	function listWeekdaysMin (localeSorted, format, index) {
	    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
	}
	
	getSetGlobalLocale('en', {
	    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (toInt(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    }
	});
	
	// Side effect imports
	hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
	hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
	
	var mathAbs = Math.abs;
	
	function abs () {
	    var data           = this._data;
	
	    this._milliseconds = mathAbs(this._milliseconds);
	    this._days         = mathAbs(this._days);
	    this._months       = mathAbs(this._months);
	
	    data.milliseconds  = mathAbs(data.milliseconds);
	    data.seconds       = mathAbs(data.seconds);
	    data.minutes       = mathAbs(data.minutes);
	    data.hours         = mathAbs(data.hours);
	    data.months        = mathAbs(data.months);
	    data.years         = mathAbs(data.years);
	
	    return this;
	}
	
	function addSubtract$1 (duration, input, value, direction) {
	    var other = createDuration(input, value);
	
	    duration._milliseconds += direction * other._milliseconds;
	    duration._days         += direction * other._days;
	    duration._months       += direction * other._months;
	
	    return duration._bubble();
	}
	
	// supports only 2.0-style add(1, 's') or add(duration)
	function add$1 (input, value) {
	    return addSubtract$1(this, input, value, 1);
	}
	
	// supports only 2.0-style subtract(1, 's') or subtract(duration)
	function subtract$1 (input, value) {
	    return addSubtract$1(this, input, value, -1);
	}
	
	function absCeil (number) {
	    if (number < 0) {
	        return Math.floor(number);
	    } else {
	        return Math.ceil(number);
	    }
	}
	
	function bubble () {
	    var milliseconds = this._milliseconds;
	    var days         = this._days;
	    var months       = this._months;
	    var data         = this._data;
	    var seconds, minutes, hours, years, monthsFromDays;
	
	    // if we have a mix of positive and negative values, bubble down first
	    // check: https://github.com/moment/moment/issues/2166
	    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
	            (milliseconds <= 0 && days <= 0 && months <= 0))) {
	        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
	        days = 0;
	        months = 0;
	    }
	
	    // The following code bubbles up values, see the tests for
	    // examples of what that means.
	    data.milliseconds = milliseconds % 1000;
	
	    seconds           = absFloor(milliseconds / 1000);
	    data.seconds      = seconds % 60;
	
	    minutes           = absFloor(seconds / 60);
	    data.minutes      = minutes % 60;
	
	    hours             = absFloor(minutes / 60);
	    data.hours        = hours % 24;
	
	    days += absFloor(hours / 24);
	
	    // convert days to months
	    monthsFromDays = absFloor(daysToMonths(days));
	    months += monthsFromDays;
	    days -= absCeil(monthsToDays(monthsFromDays));
	
	    // 12 months -> 1 year
	    years = absFloor(months / 12);
	    months %= 12;
	
	    data.days   = days;
	    data.months = months;
	    data.years  = years;
	
	    return this;
	}
	
	function daysToMonths (days) {
	    // 400 years have 146097 days (taking into account leap year rules)
	    // 400 years have 12 months === 4800
	    return days * 4800 / 146097;
	}
	
	function monthsToDays (months) {
	    // the reverse of daysToMonths
	    return months * 146097 / 4800;
	}
	
	function as (units) {
	    if (!this.isValid()) {
	        return NaN;
	    }
	    var days;
	    var months;
	    var milliseconds = this._milliseconds;
	
	    units = normalizeUnits(units);
	
	    if (units === 'month' || units === 'year') {
	        days   = this._days   + milliseconds / 864e5;
	        months = this._months + daysToMonths(days);
	        return units === 'month' ? months : months / 12;
	    } else {
	        // handle milliseconds separately because of floating point math errors (issue #1867)
	        days = this._days + Math.round(monthsToDays(this._months));
	        switch (units) {
	            case 'week'   : return days / 7     + milliseconds / 6048e5;
	            case 'day'    : return days         + milliseconds / 864e5;
	            case 'hour'   : return days * 24    + milliseconds / 36e5;
	            case 'minute' : return days * 1440  + milliseconds / 6e4;
	            case 'second' : return days * 86400 + milliseconds / 1000;
	            // Math.floor prevents floating point math errors here
	            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
	            default: throw new Error('Unknown unit ' + units);
	        }
	    }
	}
	
	// TODO: Use this.as('ms')?
	function valueOf$1 () {
	    if (!this.isValid()) {
	        return NaN;
	    }
	    return (
	        this._milliseconds +
	        this._days * 864e5 +
	        (this._months % 12) * 2592e6 +
	        toInt(this._months / 12) * 31536e6
	    );
	}
	
	function makeAs (alias) {
	    return function () {
	        return this.as(alias);
	    };
	}
	
	var asMilliseconds = makeAs('ms');
	var asSeconds      = makeAs('s');
	var asMinutes      = makeAs('m');
	var asHours        = makeAs('h');
	var asDays         = makeAs('d');
	var asWeeks        = makeAs('w');
	var asMonths       = makeAs('M');
	var asYears        = makeAs('y');
	
	function get$2 (units) {
	    units = normalizeUnits(units);
	    return this.isValid() ? this[units + 's']() : NaN;
	}
	
	function makeGetter(name) {
	    return function () {
	        return this.isValid() ? this._data[name] : NaN;
	    };
	}
	
	var milliseconds = makeGetter('milliseconds');
	var seconds      = makeGetter('seconds');
	var minutes      = makeGetter('minutes');
	var hours        = makeGetter('hours');
	var days         = makeGetter('days');
	var months       = makeGetter('months');
	var years        = makeGetter('years');
	
	function weeks () {
	    return absFloor(this.days() / 7);
	}
	
	var round = Math.round;
	var thresholds = {
	    ss: 44,         // a few seconds to seconds
	    s : 45,         // seconds to minute
	    m : 45,         // minutes to hour
	    h : 22,         // hours to day
	    d : 26,         // days to month
	    M : 11          // months to year
	};
	
	// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
	function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
	    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
	}
	
	function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
	    var duration = createDuration(posNegDuration).abs();
	    var seconds  = round(duration.as('s'));
	    var minutes  = round(duration.as('m'));
	    var hours    = round(duration.as('h'));
	    var days     = round(duration.as('d'));
	    var months   = round(duration.as('M'));
	    var years    = round(duration.as('y'));
	
	    var a = seconds <= thresholds.ss && ['s', seconds]  ||
	            seconds < thresholds.s   && ['ss', seconds] ||
	            minutes <= 1             && ['m']           ||
	            minutes < thresholds.m   && ['mm', minutes] ||
	            hours   <= 1             && ['h']           ||
	            hours   < thresholds.h   && ['hh', hours]   ||
	            days    <= 1             && ['d']           ||
	            days    < thresholds.d   && ['dd', days]    ||
	            months  <= 1             && ['M']           ||
	            months  < thresholds.M   && ['MM', months]  ||
	            years   <= 1             && ['y']           || ['yy', years];
	
	    a[2] = withoutSuffix;
	    a[3] = +posNegDuration > 0;
	    a[4] = locale;
	    return substituteTimeAgo.apply(null, a);
	}
	
	// This function allows you to set the rounding function for relative time strings
	function getSetRelativeTimeRounding (roundingFunction) {
	    if (roundingFunction === undefined) {
	        return round;
	    }
	    if (typeof(roundingFunction) === 'function') {
	        round = roundingFunction;
	        return true;
	    }
	    return false;
	}
	
	// This function allows you to set a threshold for relative time strings
	function getSetRelativeTimeThreshold (threshold, limit) {
	    if (thresholds[threshold] === undefined) {
	        return false;
	    }
	    if (limit === undefined) {
	        return thresholds[threshold];
	    }
	    thresholds[threshold] = limit;
	    if (threshold === 's') {
	        thresholds.ss = limit - 1;
	    }
	    return true;
	}
	
	function humanize (withSuffix) {
	    if (!this.isValid()) {
	        return this.localeData().invalidDate();
	    }
	
	    var locale = this.localeData();
	    var output = relativeTime$1(this, !withSuffix, locale);
	
	    if (withSuffix) {
	        output = locale.pastFuture(+this, output);
	    }
	
	    return locale.postformat(output);
	}
	
	var abs$1 = Math.abs;
	
	function toISOString$1() {
	    // for ISO strings we do not use the normal bubbling rules:
	    //  * milliseconds bubble up until they become hours
	    //  * days do not bubble at all
	    //  * months bubble up until they become years
	    // This is because there is no context-free conversion between hours and days
	    // (think of clock changes)
	    // and also not between days and months (28-31 days per month)
	    if (!this.isValid()) {
	        return this.localeData().invalidDate();
	    }
	
	    var seconds = abs$1(this._milliseconds) / 1000;
	    var days         = abs$1(this._days);
	    var months       = abs$1(this._months);
	    var minutes, hours, years;
	
	    // 3600 seconds -> 60 minutes -> 1 hour
	    minutes           = absFloor(seconds / 60);
	    hours             = absFloor(minutes / 60);
	    seconds %= 60;
	    minutes %= 60;
	
	    // 12 months -> 1 year
	    years  = absFloor(months / 12);
	    months %= 12;
	
	
	    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
	    var Y = years;
	    var M = months;
	    var D = days;
	    var h = hours;
	    var m = minutes;
	    var s = seconds;
	    var total = this.asSeconds();
	
	    if (!total) {
	        // this is the same as C#'s (Noda) and python (isodate)...
	        // but not other JS (goog.date)
	        return 'P0D';
	    }
	
	    return (total < 0 ? '-' : '') +
	        'P' +
	        (Y ? Y + 'Y' : '') +
	        (M ? M + 'M' : '') +
	        (D ? D + 'D' : '') +
	        ((h || m || s) ? 'T' : '') +
	        (h ? h + 'H' : '') +
	        (m ? m + 'M' : '') +
	        (s ? s + 'S' : '');
	}
	
	var proto$2 = Duration.prototype;
	
	proto$2.isValid        = isValid$1;
	proto$2.abs            = abs;
	proto$2.add            = add$1;
	proto$2.subtract       = subtract$1;
	proto$2.as             = as;
	proto$2.asMilliseconds = asMilliseconds;
	proto$2.asSeconds      = asSeconds;
	proto$2.asMinutes      = asMinutes;
	proto$2.asHours        = asHours;
	proto$2.asDays         = asDays;
	proto$2.asWeeks        = asWeeks;
	proto$2.asMonths       = asMonths;
	proto$2.asYears        = asYears;
	proto$2.valueOf        = valueOf$1;
	proto$2._bubble        = bubble;
	proto$2.get            = get$2;
	proto$2.milliseconds   = milliseconds;
	proto$2.seconds        = seconds;
	proto$2.minutes        = minutes;
	proto$2.hours          = hours;
	proto$2.days           = days;
	proto$2.weeks          = weeks;
	proto$2.months         = months;
	proto$2.years          = years;
	proto$2.humanize       = humanize;
	proto$2.toISOString    = toISOString$1;
	proto$2.toString       = toISOString$1;
	proto$2.toJSON         = toISOString$1;
	proto$2.locale         = locale;
	proto$2.localeData     = localeData;
	
	// Deprecations
	proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
	proto$2.lang = lang;
	
	// Side effect imports
	
	// FORMATTING
	
	addFormatToken('X', 0, 0, 'unix');
	addFormatToken('x', 0, 0, 'valueOf');
	
	// PARSING
	
	addRegexToken('x', matchSigned);
	addRegexToken('X', matchTimestamp);
	addParseToken('X', function (input, array, config) {
	    config._d = new Date(parseFloat(input, 10) * 1000);
	});
	addParseToken('x', function (input, array, config) {
	    config._d = new Date(toInt(input));
	});
	
	// Side effect imports
	
	
	hooks.version = '2.18.1';
	
	setHookCallback(createLocal);
	
	hooks.fn                    = proto;
	hooks.min                   = min;
	hooks.max                   = max;
	hooks.now                   = now;
	hooks.utc                   = createUTC;
	hooks.unix                  = createUnix;
	hooks.months                = listMonths;
	hooks.isDate                = isDate;
	hooks.locale                = getSetGlobalLocale;
	hooks.invalid               = createInvalid;
	hooks.duration              = createDuration;
	hooks.isMoment              = isMoment;
	hooks.weekdays              = listWeekdays;
	hooks.parseZone             = createInZone;
	hooks.localeData            = getLocale;
	hooks.isDuration            = isDuration;
	hooks.monthsShort           = listMonthsShort;
	hooks.weekdaysMin           = listWeekdaysMin;
	hooks.defineLocale          = defineLocale;
	hooks.updateLocale          = updateLocale;
	hooks.locales               = listLocales;
	hooks.weekdaysShort         = listWeekdaysShort;
	hooks.normalizeUnits        = normalizeUnits;
	hooks.relativeTimeRounding = getSetRelativeTimeRounding;
	hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
	hooks.calendarFormat        = getCalendarFormat;
	hooks.prototype             = proto;
	
	return hooks;
	
	})));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('webpack@1.15.0/buildin/module.js')(module)))
})
/** END DEFINE BLOCK for moment@2.18.1/moment.js **/


/** START DEFINE BLOCK for webpack@1.15.0/buildin/module.js **/
jupyter.define('webpack@1.15.0/buildin/module.js', function (module, exports, __jupyter_require__) {
	module.exports = function(module) {
		if(!module.webpackPolyfill) {
			module.deprecate = function() {};
			module.paths = [];
			// module.parent = undefined by default
			module.children = [];
			module.webpackPolyfill = 1;
		}
		return module;
	}
	
})
/** END DEFINE BLOCK for webpack@1.15.0/buildin/module.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale **/
jupyter.define('moment@2.18.1/locale', function (module, exports, __jupyter_require__) {
	
	      var map = {
		"./af": "moment@2.18.1/locale/af.js",
		"./af.js": "moment@2.18.1/locale/af.js",
		"./ar": "moment@2.18.1/locale/ar.js",
		"./ar-dz": "moment@2.18.1/locale/ar-dz.js",
		"./ar-dz.js": "moment@2.18.1/locale/ar-dz.js",
		"./ar-kw": "moment@2.18.1/locale/ar-kw.js",
		"./ar-kw.js": "moment@2.18.1/locale/ar-kw.js",
		"./ar-ly": "moment@2.18.1/locale/ar-ly.js",
		"./ar-ly.js": "moment@2.18.1/locale/ar-ly.js",
		"./ar-ma": "moment@2.18.1/locale/ar-ma.js",
		"./ar-ma.js": "moment@2.18.1/locale/ar-ma.js",
		"./ar-sa": "moment@2.18.1/locale/ar-sa.js",
		"./ar-sa.js": "moment@2.18.1/locale/ar-sa.js",
		"./ar-tn": "moment@2.18.1/locale/ar-tn.js",
		"./ar-tn.js": "moment@2.18.1/locale/ar-tn.js",
		"./ar.js": "moment@2.18.1/locale/ar.js",
		"./az": "moment@2.18.1/locale/az.js",
		"./az.js": "moment@2.18.1/locale/az.js",
		"./be": "moment@2.18.1/locale/be.js",
		"./be.js": "moment@2.18.1/locale/be.js",
		"./bg": "moment@2.18.1/locale/bg.js",
		"./bg.js": "moment@2.18.1/locale/bg.js",
		"./bn": "moment@2.18.1/locale/bn.js",
		"./bn.js": "moment@2.18.1/locale/bn.js",
		"./bo": "moment@2.18.1/locale/bo.js",
		"./bo.js": "moment@2.18.1/locale/bo.js",
		"./br": "moment@2.18.1/locale/br.js",
		"./br.js": "moment@2.18.1/locale/br.js",
		"./bs": "moment@2.18.1/locale/bs.js",
		"./bs.js": "moment@2.18.1/locale/bs.js",
		"./ca": "moment@2.18.1/locale/ca.js",
		"./ca.js": "moment@2.18.1/locale/ca.js",
		"./cs": "moment@2.18.1/locale/cs.js",
		"./cs.js": "moment@2.18.1/locale/cs.js",
		"./cv": "moment@2.18.1/locale/cv.js",
		"./cv.js": "moment@2.18.1/locale/cv.js",
		"./cy": "moment@2.18.1/locale/cy.js",
		"./cy.js": "moment@2.18.1/locale/cy.js",
		"./da": "moment@2.18.1/locale/da.js",
		"./da.js": "moment@2.18.1/locale/da.js",
		"./de": "moment@2.18.1/locale/de.js",
		"./de-at": "moment@2.18.1/locale/de-at.js",
		"./de-at.js": "moment@2.18.1/locale/de-at.js",
		"./de-ch": "moment@2.18.1/locale/de-ch.js",
		"./de-ch.js": "moment@2.18.1/locale/de-ch.js",
		"./de.js": "moment@2.18.1/locale/de.js",
		"./dv": "moment@2.18.1/locale/dv.js",
		"./dv.js": "moment@2.18.1/locale/dv.js",
		"./el": "moment@2.18.1/locale/el.js",
		"./el.js": "moment@2.18.1/locale/el.js",
		"./en-au": "moment@2.18.1/locale/en-au.js",
		"./en-au.js": "moment@2.18.1/locale/en-au.js",
		"./en-ca": "moment@2.18.1/locale/en-ca.js",
		"./en-ca.js": "moment@2.18.1/locale/en-ca.js",
		"./en-gb": "moment@2.18.1/locale/en-gb.js",
		"./en-gb.js": "moment@2.18.1/locale/en-gb.js",
		"./en-ie": "moment@2.18.1/locale/en-ie.js",
		"./en-ie.js": "moment@2.18.1/locale/en-ie.js",
		"./en-nz": "moment@2.18.1/locale/en-nz.js",
		"./en-nz.js": "moment@2.18.1/locale/en-nz.js",
		"./eo": "moment@2.18.1/locale/eo.js",
		"./eo.js": "moment@2.18.1/locale/eo.js",
		"./es": "moment@2.18.1/locale/es.js",
		"./es-do": "moment@2.18.1/locale/es-do.js",
		"./es-do.js": "moment@2.18.1/locale/es-do.js",
		"./es.js": "moment@2.18.1/locale/es.js",
		"./et": "moment@2.18.1/locale/et.js",
		"./et.js": "moment@2.18.1/locale/et.js",
		"./eu": "moment@2.18.1/locale/eu.js",
		"./eu.js": "moment@2.18.1/locale/eu.js",
		"./fa": "moment@2.18.1/locale/fa.js",
		"./fa.js": "moment@2.18.1/locale/fa.js",
		"./fi": "moment@2.18.1/locale/fi.js",
		"./fi.js": "moment@2.18.1/locale/fi.js",
		"./fo": "moment@2.18.1/locale/fo.js",
		"./fo.js": "moment@2.18.1/locale/fo.js",
		"./fr": "moment@2.18.1/locale/fr.js",
		"./fr-ca": "moment@2.18.1/locale/fr-ca.js",
		"./fr-ca.js": "moment@2.18.1/locale/fr-ca.js",
		"./fr-ch": "moment@2.18.1/locale/fr-ch.js",
		"./fr-ch.js": "moment@2.18.1/locale/fr-ch.js",
		"./fr.js": "moment@2.18.1/locale/fr.js",
		"./fy": "moment@2.18.1/locale/fy.js",
		"./fy.js": "moment@2.18.1/locale/fy.js",
		"./gd": "moment@2.18.1/locale/gd.js",
		"./gd.js": "moment@2.18.1/locale/gd.js",
		"./gl": "moment@2.18.1/locale/gl.js",
		"./gl.js": "moment@2.18.1/locale/gl.js",
		"./gom-latn": "moment@2.18.1/locale/gom-latn.js",
		"./gom-latn.js": "moment@2.18.1/locale/gom-latn.js",
		"./he": "moment@2.18.1/locale/he.js",
		"./he.js": "moment@2.18.1/locale/he.js",
		"./hi": "moment@2.18.1/locale/hi.js",
		"./hi.js": "moment@2.18.1/locale/hi.js",
		"./hr": "moment@2.18.1/locale/hr.js",
		"./hr.js": "moment@2.18.1/locale/hr.js",
		"./hu": "moment@2.18.1/locale/hu.js",
		"./hu.js": "moment@2.18.1/locale/hu.js",
		"./hy-am": "moment@2.18.1/locale/hy-am.js",
		"./hy-am.js": "moment@2.18.1/locale/hy-am.js",
		"./id": "moment@2.18.1/locale/id.js",
		"./id.js": "moment@2.18.1/locale/id.js",
		"./is": "moment@2.18.1/locale/is.js",
		"./is.js": "moment@2.18.1/locale/is.js",
		"./it": "moment@2.18.1/locale/it.js",
		"./it.js": "moment@2.18.1/locale/it.js",
		"./ja": "moment@2.18.1/locale/ja.js",
		"./ja.js": "moment@2.18.1/locale/ja.js",
		"./jv": "moment@2.18.1/locale/jv.js",
		"./jv.js": "moment@2.18.1/locale/jv.js",
		"./ka": "moment@2.18.1/locale/ka.js",
		"./ka.js": "moment@2.18.1/locale/ka.js",
		"./kk": "moment@2.18.1/locale/kk.js",
		"./kk.js": "moment@2.18.1/locale/kk.js",
		"./km": "moment@2.18.1/locale/km.js",
		"./km.js": "moment@2.18.1/locale/km.js",
		"./kn": "moment@2.18.1/locale/kn.js",
		"./kn.js": "moment@2.18.1/locale/kn.js",
		"./ko": "moment@2.18.1/locale/ko.js",
		"./ko.js": "moment@2.18.1/locale/ko.js",
		"./ky": "moment@2.18.1/locale/ky.js",
		"./ky.js": "moment@2.18.1/locale/ky.js",
		"./lb": "moment@2.18.1/locale/lb.js",
		"./lb.js": "moment@2.18.1/locale/lb.js",
		"./lo": "moment@2.18.1/locale/lo.js",
		"./lo.js": "moment@2.18.1/locale/lo.js",
		"./lt": "moment@2.18.1/locale/lt.js",
		"./lt.js": "moment@2.18.1/locale/lt.js",
		"./lv": "moment@2.18.1/locale/lv.js",
		"./lv.js": "moment@2.18.1/locale/lv.js",
		"./me": "moment@2.18.1/locale/me.js",
		"./me.js": "moment@2.18.1/locale/me.js",
		"./mi": "moment@2.18.1/locale/mi.js",
		"./mi.js": "moment@2.18.1/locale/mi.js",
		"./mk": "moment@2.18.1/locale/mk.js",
		"./mk.js": "moment@2.18.1/locale/mk.js",
		"./ml": "moment@2.18.1/locale/ml.js",
		"./ml.js": "moment@2.18.1/locale/ml.js",
		"./mr": "moment@2.18.1/locale/mr.js",
		"./mr.js": "moment@2.18.1/locale/mr.js",
		"./ms": "moment@2.18.1/locale/ms.js",
		"./ms-my": "moment@2.18.1/locale/ms-my.js",
		"./ms-my.js": "moment@2.18.1/locale/ms-my.js",
		"./ms.js": "moment@2.18.1/locale/ms.js",
		"./my": "moment@2.18.1/locale/my.js",
		"./my.js": "moment@2.18.1/locale/my.js",
		"./nb": "moment@2.18.1/locale/nb.js",
		"./nb.js": "moment@2.18.1/locale/nb.js",
		"./ne": "moment@2.18.1/locale/ne.js",
		"./ne.js": "moment@2.18.1/locale/ne.js",
		"./nl": "moment@2.18.1/locale/nl.js",
		"./nl-be": "moment@2.18.1/locale/nl-be.js",
		"./nl-be.js": "moment@2.18.1/locale/nl-be.js",
		"./nl.js": "moment@2.18.1/locale/nl.js",
		"./nn": "moment@2.18.1/locale/nn.js",
		"./nn.js": "moment@2.18.1/locale/nn.js",
		"./pa-in": "moment@2.18.1/locale/pa-in.js",
		"./pa-in.js": "moment@2.18.1/locale/pa-in.js",
		"./pl": "moment@2.18.1/locale/pl.js",
		"./pl.js": "moment@2.18.1/locale/pl.js",
		"./pt": "moment@2.18.1/locale/pt.js",
		"./pt-br": "moment@2.18.1/locale/pt-br.js",
		"./pt-br.js": "moment@2.18.1/locale/pt-br.js",
		"./pt.js": "moment@2.18.1/locale/pt.js",
		"./ro": "moment@2.18.1/locale/ro.js",
		"./ro.js": "moment@2.18.1/locale/ro.js",
		"./ru": "moment@2.18.1/locale/ru.js",
		"./ru.js": "moment@2.18.1/locale/ru.js",
		"./sd": "moment@2.18.1/locale/sd.js",
		"./sd.js": "moment@2.18.1/locale/sd.js",
		"./se": "moment@2.18.1/locale/se.js",
		"./se.js": "moment@2.18.1/locale/se.js",
		"./si": "moment@2.18.1/locale/si.js",
		"./si.js": "moment@2.18.1/locale/si.js",
		"./sk": "moment@2.18.1/locale/sk.js",
		"./sk.js": "moment@2.18.1/locale/sk.js",
		"./sl": "moment@2.18.1/locale/sl.js",
		"./sl.js": "moment@2.18.1/locale/sl.js",
		"./sq": "moment@2.18.1/locale/sq.js",
		"./sq.js": "moment@2.18.1/locale/sq.js",
		"./sr": "moment@2.18.1/locale/sr.js",
		"./sr-cyrl": "moment@2.18.1/locale/sr-cyrl.js",
		"./sr-cyrl.js": "moment@2.18.1/locale/sr-cyrl.js",
		"./sr.js": "moment@2.18.1/locale/sr.js",
		"./ss": "moment@2.18.1/locale/ss.js",
		"./ss.js": "moment@2.18.1/locale/ss.js",
		"./sv": "moment@2.18.1/locale/sv.js",
		"./sv.js": "moment@2.18.1/locale/sv.js",
		"./sw": "moment@2.18.1/locale/sw.js",
		"./sw.js": "moment@2.18.1/locale/sw.js",
		"./ta": "moment@2.18.1/locale/ta.js",
		"./ta.js": "moment@2.18.1/locale/ta.js",
		"./te": "moment@2.18.1/locale/te.js",
		"./te.js": "moment@2.18.1/locale/te.js",
		"./tet": "moment@2.18.1/locale/tet.js",
		"./tet.js": "moment@2.18.1/locale/tet.js",
		"./th": "moment@2.18.1/locale/th.js",
		"./th.js": "moment@2.18.1/locale/th.js",
		"./tl-ph": "moment@2.18.1/locale/tl-ph.js",
		"./tl-ph.js": "moment@2.18.1/locale/tl-ph.js",
		"./tlh": "moment@2.18.1/locale/tlh.js",
		"./tlh.js": "moment@2.18.1/locale/tlh.js",
		"./tr": "moment@2.18.1/locale/tr.js",
		"./tr.js": "moment@2.18.1/locale/tr.js",
		"./tzl": "moment@2.18.1/locale/tzl.js",
		"./tzl.js": "moment@2.18.1/locale/tzl.js",
		"./tzm": "moment@2.18.1/locale/tzm.js",
		"./tzm-latn": "moment@2.18.1/locale/tzm-latn.js",
		"./tzm-latn.js": "moment@2.18.1/locale/tzm-latn.js",
		"./tzm.js": "moment@2.18.1/locale/tzm.js",
		"./uk": "moment@2.18.1/locale/uk.js",
		"./uk.js": "moment@2.18.1/locale/uk.js",
		"./ur": "moment@2.18.1/locale/ur.js",
		"./ur.js": "moment@2.18.1/locale/ur.js",
		"./uz": "moment@2.18.1/locale/uz.js",
		"./uz-latn": "moment@2.18.1/locale/uz-latn.js",
		"./uz-latn.js": "moment@2.18.1/locale/uz-latn.js",
		"./uz.js": "moment@2.18.1/locale/uz.js",
		"./vi": "moment@2.18.1/locale/vi.js",
		"./vi.js": "moment@2.18.1/locale/vi.js",
		"./x-pseudo": "moment@2.18.1/locale/x-pseudo.js",
		"./x-pseudo.js": "moment@2.18.1/locale/x-pseudo.js",
		"./yo": "moment@2.18.1/locale/yo.js",
		"./yo.js": "moment@2.18.1/locale/yo.js",
		"./zh-cn": "moment@2.18.1/locale/zh-cn.js",
		"./zh-cn.js": "moment@2.18.1/locale/zh-cn.js",
		"./zh-hk": "moment@2.18.1/locale/zh-hk.js",
		"./zh-hk.js": "moment@2.18.1/locale/zh-hk.js",
		"./zh-tw": "moment@2.18.1/locale/zh-tw.js",
		"./zh-tw.js": "moment@2.18.1/locale/zh-tw.js"
	};
	      function jupyterContext(req) {
	        return __jupyter_require__(jupyterContextResolve(req));
	      };
	      function jupyterContextResolve(req) {
	        return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
	      };
	      jupyterContext.keys = function jupyterContextKeys() {
	        return Object.keys(map);
	      };
	      jupyterContext.resolve = jupyterContextResolve;
	      module.exports = jupyterContext;
	      jupyterContext.id = "moment@2.18.1/locale";
	    
})
/** END DEFINE BLOCK for moment@2.18.1/locale **/


/** START DEFINE BLOCK for moment@2.18.1/locale/af.js **/
jupyter.define('moment@2.18.1/locale/af.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Afrikaans [af]
	//! author : Werner Mollentze : https://github.com/wernerm
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var af = moment.defineLocale('af', {
	    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),
	    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
	    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
	    meridiemParse: /vm|nm/i,
	    isPM : function (input) {
	        return /^nm$/i.test(input);
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower ? 'vm' : 'VM';
	        } else {
	            return isLower ? 'nm' : 'NM';
	        }
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Vandag om] LT',
	        nextDay : '[Môre om] LT',
	        nextWeek : 'dddd [om] LT',
	        lastDay : '[Gister om] LT',
	        lastWeek : '[Laas] dddd [om] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'oor %s',
	        past : '%s gelede',
	        s : '\'n paar sekondes',
	        m : '\'n minuut',
	        mm : '%d minute',
	        h : '\'n uur',
	        hh : '%d ure',
	        d : '\'n dag',
	        dd : '%d dae',
	        M : '\'n maand',
	        MM : '%d maande',
	        y : '\'n jaar',
	        yy : '%d jaar'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter
	    },
	    week : {
	        dow : 1, // Maandag is die eerste dag van die week.
	        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
	    }
	});
	
	return af;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/af.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ar.js **/
jupyter.define('moment@2.18.1/locale/ar.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Arabic [ar]
	//! author : Abdel Said: https://github.com/abdelsaid
	//! author : Ahmed Elkhatib
	//! author : forabi https://github.com/forabi
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '١',
	    '2': '٢',
	    '3': '٣',
	    '4': '٤',
	    '5': '٥',
	    '6': '٦',
	    '7': '٧',
	    '8': '٨',
	    '9': '٩',
	    '0': '٠'
	};
	var numberMap = {
	    '١': '1',
	    '٢': '2',
	    '٣': '3',
	    '٤': '4',
	    '٥': '5',
	    '٦': '6',
	    '٧': '7',
	    '٨': '8',
	    '٩': '9',
	    '٠': '0'
	};
	var pluralForm = function (n) {
	    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
	};
	var plurals = {
	    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
	    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
	    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
	    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
	    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
	    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
	};
	var pluralize = function (u) {
	    return function (number, withoutSuffix, string, isFuture) {
	        var f = pluralForm(number),
	            str = plurals[u][pluralForm(number)];
	        if (f === 2) {
	            str = str[withoutSuffix ? 0 : 1];
	        }
	        return str.replace(/%d/i, number);
	    };
	};
	var months = [
	    'كانون الثاني يناير',
	    'شباط فبراير',
	    'آذار مارس',
	    'نيسان أبريل',
	    'أيار مايو',
	    'حزيران يونيو',
	    'تموز يوليو',
	    'آب أغسطس',
	    'أيلول سبتمبر',
	    'تشرين الأول أكتوبر',
	    'تشرين الثاني نوفمبر',
	    'كانون الأول ديسمبر'
	];
	
	var ar = moment.defineLocale('ar', {
	    months : months,
	    monthsShort : months,
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/\u200FM/\u200FYYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم عند الساعة] LT',
	        nextDay: '[غدًا عند الساعة] LT',
	        nextWeek: 'dddd [عند الساعة] LT',
	        lastDay: '[أمس عند الساعة] LT',
	        lastWeek: 'dddd [عند الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'بعد %s',
	        past : 'منذ %s',
	        s : pluralize('s'),
	        m : pluralize('m'),
	        mm : pluralize('m'),
	        h : pluralize('h'),
	        hh : pluralize('h'),
	        d : pluralize('d'),
	        dd : pluralize('d'),
	        M : pluralize('M'),
	        MM : pluralize('M'),
	        y : pluralize('y'),
	        yy : pluralize('y')
	    },
	    preparse: function (string) {
	        return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ar;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ar.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ar-dz.js **/
jupyter.define('moment@2.18.1/locale/ar-dz.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Arabic (Algeria) [ar-dz]
	//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arDz = moment.defineLocale('ar-dz', {
	    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 4  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arDz;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ar-dz.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ar-kw.js **/
jupyter.define('moment@2.18.1/locale/ar-kw.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Arabic (Kuwait) [ar-kw]
	//! author : Nusret Parlak: https://github.com/nusretparlak
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arKw = moment.defineLocale('ar-kw', {
	    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arKw;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ar-kw.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ar-ly.js **/
jupyter.define('moment@2.18.1/locale/ar-ly.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Arabic (Lybia) [ar-ly]
	//! author : Ali Hmer: https://github.com/kikoanis
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '1',
	    '2': '2',
	    '3': '3',
	    '4': '4',
	    '5': '5',
	    '6': '6',
	    '7': '7',
	    '8': '8',
	    '9': '9',
	    '0': '0'
	};
	var pluralForm = function (n) {
	    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
	};
	var plurals = {
	    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
	    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
	    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
	    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
	    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
	    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
	};
	var pluralize = function (u) {
	    return function (number, withoutSuffix, string, isFuture) {
	        var f = pluralForm(number),
	            str = plurals[u][pluralForm(number)];
	        if (f === 2) {
	            str = str[withoutSuffix ? 0 : 1];
	        }
	        return str.replace(/%d/i, number);
	    };
	};
	var months = [
	    'يناير',
	    'فبراير',
	    'مارس',
	    'أبريل',
	    'مايو',
	    'يونيو',
	    'يوليو',
	    'أغسطس',
	    'سبتمبر',
	    'أكتوبر',
	    'نوفمبر',
	    'ديسمبر'
	];
	
	var arLy = moment.defineLocale('ar-ly', {
	    months : months,
	    monthsShort : months,
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/\u200FM/\u200FYYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم عند الساعة] LT',
	        nextDay: '[غدًا عند الساعة] LT',
	        nextWeek: 'dddd [عند الساعة] LT',
	        lastDay: '[أمس عند الساعة] LT',
	        lastWeek: 'dddd [عند الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'بعد %s',
	        past : 'منذ %s',
	        s : pluralize('s'),
	        m : pluralize('m'),
	        mm : pluralize('m'),
	        h : pluralize('h'),
	        hh : pluralize('h'),
	        d : pluralize('d'),
	        dd : pluralize('d'),
	        M : pluralize('M'),
	        MM : pluralize('M'),
	        y : pluralize('y'),
	        yy : pluralize('y')
	    },
	    preparse: function (string) {
	        return string.replace(/\u200f/g, '').replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arLy;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ar-ly.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ar-ma.js **/
jupyter.define('moment@2.18.1/locale/ar-ma.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Arabic (Morocco) [ar-ma]
	//! author : ElFadili Yassine : https://github.com/ElFadiliY
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arMa = moment.defineLocale('ar-ma', {
	    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
	    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arMa;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ar-ma.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ar-sa.js **/
jupyter.define('moment@2.18.1/locale/ar-sa.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Arabic (Saudi Arabia) [ar-sa]
	//! author : Suhail Alkowaileet : https://github.com/xsoh
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '١',
	    '2': '٢',
	    '3': '٣',
	    '4': '٤',
	    '5': '٥',
	    '6': '٦',
	    '7': '٧',
	    '8': '٨',
	    '9': '٩',
	    '0': '٠'
	};
	var numberMap = {
	    '١': '1',
	    '٢': '2',
	    '٣': '3',
	    '٤': '4',
	    '٥': '5',
	    '٦': '6',
	    '٧': '7',
	    '٨': '8',
	    '٩': '9',
	    '٠': '0'
	};
	
	var arSa = moment.defineLocale('ar-sa', {
	    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ص|م/,
	    isPM : function (input) {
	        return 'م' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ص';
	        } else {
	            return 'م';
	        }
	    },
	    calendar : {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'في %s',
	        past : 'منذ %s',
	        s : 'ثوان',
	        m : 'دقيقة',
	        mm : '%d دقائق',
	        h : 'ساعة',
	        hh : '%d ساعات',
	        d : 'يوم',
	        dd : '%d أيام',
	        M : 'شهر',
	        MM : '%d أشهر',
	        y : 'سنة',
	        yy : '%d سنوات'
	    },
	    preparse: function (string) {
	        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return arSa;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ar-sa.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ar-tn.js **/
jupyter.define('moment@2.18.1/locale/ar-tn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale  :  Arabic (Tunisia) [ar-tn]
	//! author : Nader Toukabri : https://github.com/naderio
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var arTn = moment.defineLocale('ar-tn', {
	    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
	    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
	    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
	    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[اليوم على الساعة] LT',
	        nextDay: '[غدا على الساعة] LT',
	        nextWeek: 'dddd [على الساعة] LT',
	        lastDay: '[أمس على الساعة] LT',
	        lastWeek: 'dddd [على الساعة] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'في %s',
	        past: 'منذ %s',
	        s: 'ثوان',
	        m: 'دقيقة',
	        mm: '%d دقائق',
	        h: 'ساعة',
	        hh: '%d ساعات',
	        d: 'يوم',
	        dd: '%d أيام',
	        M: 'شهر',
	        MM: '%d أشهر',
	        y: 'سنة',
	        yy: '%d سنوات'
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return arTn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ar-tn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/az.js **/
jupyter.define('moment@2.18.1/locale/az.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Azerbaijani [az]
	//! author : topchiyev : https://github.com/topchiyev
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    1: '-inci',
	    5: '-inci',
	    8: '-inci',
	    70: '-inci',
	    80: '-inci',
	    2: '-nci',
	    7: '-nci',
	    20: '-nci',
	    50: '-nci',
	    3: '-üncü',
	    4: '-üncü',
	    100: '-üncü',
	    6: '-ncı',
	    9: '-uncu',
	    10: '-uncu',
	    30: '-uncu',
	    60: '-ıncı',
	    90: '-ıncı'
	};
	
	var az = moment.defineLocale('az', {
	    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),
	    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
	    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),
	    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
	    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[bugün saat] LT',
	        nextDay : '[sabah saat] LT',
	        nextWeek : '[gələn həftə] dddd [saat] LT',
	        lastDay : '[dünən] LT',
	        lastWeek : '[keçən həftə] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s sonra',
	        past : '%s əvvəl',
	        s : 'birneçə saniyyə',
	        m : 'bir dəqiqə',
	        mm : '%d dəqiqə',
	        h : 'bir saat',
	        hh : '%d saat',
	        d : 'bir gün',
	        dd : '%d gün',
	        M : 'bir ay',
	        MM : '%d ay',
	        y : 'bir il',
	        yy : '%d il'
	    },
	    meridiemParse: /gecə|səhər|gündüz|axşam/,
	    isPM : function (input) {
	        return /^(gündüz|axşam)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'gecə';
	        } else if (hour < 12) {
	            return 'səhər';
	        } else if (hour < 17) {
	            return 'gündüz';
	        } else {
	            return 'axşam';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
	    ordinal : function (number) {
	        if (number === 0) {  // special case for zero
	            return number + '-ıncı';
	        }
	        var a = number % 10,
	            b = number % 100 - a,
	            c = number >= 100 ? 100 : null;
	        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return az;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/az.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/be.js **/
jupyter.define('moment@2.18.1/locale/be.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Belarusian [be]
	//! author : Dmitry Demidov : https://github.com/demidov91
	//! author: Praleska: http://praleska.pro/
	//! Author : Menelion Elensúle : https://github.com/Oire
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
	        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
	        'dd': 'дзень_дні_дзён',
	        'MM': 'месяц_месяцы_месяцаў',
	        'yy': 'год_гады_гадоў'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'хвіліна' : 'хвіліну';
	    }
	    else if (key === 'h') {
	        return withoutSuffix ? 'гадзіна' : 'гадзіну';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	
	var be = moment.defineLocale('be', {
	    months : {
	        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),
	        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')
	    },
	    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),
	    weekdays : {
	        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),
	        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),
	        isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/
	    },
	    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
	    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY г.',
	        LLL : 'D MMMM YYYY г., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY г., HH:mm'
	    },
	    calendar : {
	        sameDay: '[Сёння ў] LT',
	        nextDay: '[Заўтра ў] LT',
	        lastDay: '[Учора ў] LT',
	        nextWeek: function () {
	            return '[У] dddd [ў] LT';
	        },
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 5:
	                case 6:
	                    return '[У мінулую] dddd [ў] LT';
	                case 1:
	                case 2:
	                case 4:
	                    return '[У мінулы] dddd [ў] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'праз %s',
	        past : '%s таму',
	        s : 'некалькі секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : relativeTimeWithPlural,
	        hh : relativeTimeWithPlural,
	        d : 'дзень',
	        dd : relativeTimeWithPlural,
	        M : 'месяц',
	        MM : relativeTimeWithPlural,
	        y : 'год',
	        yy : relativeTimeWithPlural
	    },
	    meridiemParse: /ночы|раніцы|дня|вечара/,
	    isPM : function (input) {
	        return /^(дня|вечара)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночы';
	        } else if (hour < 12) {
	            return 'раніцы';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечара';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	            case 'w':
	            case 'W':
	                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';
	            case 'D':
	                return number + '-га';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return be;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/be.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/bg.js **/
jupyter.define('moment@2.18.1/locale/bg.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Bulgarian [bg]
	//! author : Krasen Borisov : https://github.com/kraz
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var bg = moment.defineLocale('bg', {
	    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
	    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
	    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),
	    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
	    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'D.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay : '[Днес в] LT',
	        nextDay : '[Утре в] LT',
	        nextWeek : 'dddd [в] LT',
	        lastDay : '[Вчера в] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 6:
	                    return '[В изминалата] dddd [в] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[В изминалия] dddd [в] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'след %s',
	        past : 'преди %s',
	        s : 'няколко секунди',
	        m : 'минута',
	        mm : '%d минути',
	        h : 'час',
	        hh : '%d часа',
	        d : 'ден',
	        dd : '%d дни',
	        M : 'месец',
	        MM : '%d месеца',
	        y : 'година',
	        yy : '%d години'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
	    ordinal : function (number) {
	        var lastDigit = number % 10,
	            last2Digits = number % 100;
	        if (number === 0) {
	            return number + '-ев';
	        } else if (last2Digits === 0) {
	            return number + '-ен';
	        } else if (last2Digits > 10 && last2Digits < 20) {
	            return number + '-ти';
	        } else if (lastDigit === 1) {
	            return number + '-ви';
	        } else if (lastDigit === 2) {
	            return number + '-ри';
	        } else if (lastDigit === 7 || lastDigit === 8) {
	            return number + '-ми';
	        } else {
	            return number + '-ти';
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bg;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/bg.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/bn.js **/
jupyter.define('moment@2.18.1/locale/bn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Bengali [bn]
	//! author : Kaushik Gandhi : https://github.com/kaushikgandhi
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '১',
	    '2': '২',
	    '3': '৩',
	    '4': '৪',
	    '5': '৫',
	    '6': '৬',
	    '7': '৭',
	    '8': '৮',
	    '9': '৯',
	    '0': '০'
	};
	var numberMap = {
	    '১': '1',
	    '২': '2',
	    '৩': '3',
	    '৪': '4',
	    '৫': '5',
	    '৬': '6',
	    '৭': '7',
	    '৮': '8',
	    '৯': '9',
	    '০': '0'
	};
	
	var bn = moment.defineLocale('bn', {
	    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),
	    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),
	    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),
	    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
	    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm সময়',
	        LTS : 'A h:mm:ss সময়',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm সময়',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
	    },
	    calendar : {
	        sameDay : '[আজ] LT',
	        nextDay : '[আগামীকাল] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[গতকাল] LT',
	        lastWeek : '[গত] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s পরে',
	        past : '%s আগে',
	        s : 'কয়েক সেকেন্ড',
	        m : 'এক মিনিট',
	        mm : '%d মিনিট',
	        h : 'এক ঘন্টা',
	        hh : '%d ঘন্টা',
	        d : 'এক দিন',
	        dd : '%d দিন',
	        M : 'এক মাস',
	        MM : '%d মাস',
	        y : 'এক বছর',
	        yy : '%d বছর'
	    },
	    preparse: function (string) {
	        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'রাত' && hour >= 4) ||
	                (meridiem === 'দুপুর' && hour < 5) ||
	                meridiem === 'বিকাল') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'রাত';
	        } else if (hour < 10) {
	            return 'সকাল';
	        } else if (hour < 17) {
	            return 'দুপুর';
	        } else if (hour < 20) {
	            return 'বিকাল';
	        } else {
	            return 'রাত';
	        }
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/bn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/bo.js **/
jupyter.define('moment@2.18.1/locale/bo.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Tibetan [bo]
	//! author : Thupten N. Chakrishar : https://github.com/vajradog
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '༡',
	    '2': '༢',
	    '3': '༣',
	    '4': '༤',
	    '5': '༥',
	    '6': '༦',
	    '7': '༧',
	    '8': '༨',
	    '9': '༩',
	    '0': '༠'
	};
	var numberMap = {
	    '༡': '1',
	    '༢': '2',
	    '༣': '3',
	    '༤': '4',
	    '༥': '5',
	    '༦': '6',
	    '༧': '7',
	    '༨': '8',
	    '༩': '9',
	    '༠': '0'
	};
	
	var bo = moment.defineLocale('bo', {
	    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
	    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
	    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),
	    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
	    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[དི་རིང] LT',
	        nextDay : '[སང་ཉིན] LT',
	        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',
	        lastDay : '[ཁ་སང] LT',
	        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ལ་',
	        past : '%s སྔན་ལ',
	        s : 'ལམ་སང',
	        m : 'སྐར་མ་གཅིག',
	        mm : '%d སྐར་མ',
	        h : 'ཆུ་ཚོད་གཅིག',
	        hh : '%d ཆུ་ཚོད',
	        d : 'ཉིན་གཅིག',
	        dd : '%d ཉིན་',
	        M : 'ཟླ་བ་གཅིག',
	        MM : '%d ཟླ་བ',
	        y : 'ལོ་གཅིག',
	        yy : '%d ལོ'
	    },
	    preparse: function (string) {
	        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||
	                (meridiem === 'ཉིན་གུང' && hour < 5) ||
	                meridiem === 'དགོང་དག') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'མཚན་མོ';
	        } else if (hour < 10) {
	            return 'ཞོགས་ཀས';
	        } else if (hour < 17) {
	            return 'ཉིན་གུང';
	        } else if (hour < 20) {
	            return 'དགོང་དག';
	        } else {
	            return 'མཚན་མོ';
	        }
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bo;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/bo.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/br.js **/
jupyter.define('moment@2.18.1/locale/br.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Breton [br]
	//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function relativeTimeWithMutation(number, withoutSuffix, key) {
	    var format = {
	        'mm': 'munutenn',
	        'MM': 'miz',
	        'dd': 'devezh'
	    };
	    return number + ' ' + mutation(format[key], number);
	}
	function specialMutationForYears(number) {
	    switch (lastNumber(number)) {
	        case 1:
	        case 3:
	        case 4:
	        case 5:
	        case 9:
	            return number + ' bloaz';
	        default:
	            return number + ' vloaz';
	    }
	}
	function lastNumber(number) {
	    if (number > 9) {
	        return lastNumber(number % 10);
	    }
	    return number;
	}
	function mutation(text, number) {
	    if (number === 2) {
	        return softMutation(text);
	    }
	    return text;
	}
	function softMutation(text) {
	    var mutationTable = {
	        'm': 'v',
	        'b': 'v',
	        'd': 'z'
	    };
	    if (mutationTable[text.charAt(0)] === undefined) {
	        return text;
	    }
	    return mutationTable[text.charAt(0)] + text.substring(1);
	}
	
	var br = moment.defineLocale('br', {
	    months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),
	    monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
	    weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'),
	    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
	    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h[e]mm A',
	        LTS : 'h[e]mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D [a viz] MMMM YYYY',
	        LLL : 'D [a viz] MMMM YYYY h[e]mm A',
	        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
	    },
	    calendar : {
	        sameDay : '[Hiziv da] LT',
	        nextDay : '[Warc\'hoazh da] LT',
	        nextWeek : 'dddd [da] LT',
	        lastDay : '[Dec\'h da] LT',
	        lastWeek : 'dddd [paset da] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'a-benn %s',
	        past : '%s \'zo',
	        s : 'un nebeud segondennoù',
	        m : 'ur vunutenn',
	        mm : relativeTimeWithMutation,
	        h : 'un eur',
	        hh : '%d eur',
	        d : 'un devezh',
	        dd : relativeTimeWithMutation,
	        M : 'ur miz',
	        MM : relativeTimeWithMutation,
	        y : 'ur bloaz',
	        yy : specialMutationForYears
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/,
	    ordinal : function (number) {
	        var output = (number === 1) ? 'añ' : 'vet';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return br;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/br.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/bs.js **/
jupyter.define('moment@2.18.1/locale/bs.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Bosnian [bs]
	//! author : Nedim Cholich : https://github.com/frontyard
	//! based on (hr) translation by Bojan Marković
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
	        case 'mm':
	            if (number === 1) {
	                result += 'minuta';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'minute';
	            } else {
	                result += 'minuta';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'jedan sat' : 'jednog sata';
	        case 'hh':
	            if (number === 1) {
	                result += 'sat';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'sata';
	            } else {
	                result += 'sati';
	            }
	            return result;
	        case 'dd':
	            if (number === 1) {
	                result += 'dan';
	            } else {
	                result += 'dana';
	            }
	            return result;
	        case 'MM':
	            if (number === 1) {
	                result += 'mjesec';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'mjeseca';
	            } else {
	                result += 'mjeseci';
	            }
	            return result;
	        case 'yy':
	            if (number === 1) {
	                result += 'godina';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'godine';
	            } else {
	                result += 'godina';
	            }
	            return result;
	    }
	}
	
	var bs = moment.defineLocale('bs', {
	    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danas u] LT',
	        nextDay  : '[sutra u] LT',
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[jučer u] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                    return '[prošlu] dddd [u] LT';
	                case 6:
	                    return '[prošle] [subote] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prošli] dddd [u] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'par sekundi',
	        m      : translate,
	        mm     : translate,
	        h      : translate,
	        hh     : translate,
	        d      : 'dan',
	        dd     : translate,
	        M      : 'mjesec',
	        MM     : translate,
	        y      : 'godinu',
	        yy     : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return bs;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/bs.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ca.js **/
jupyter.define('moment@2.18.1/locale/ca.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Catalan [ca]
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ca = moment.defineLocale('ca', {
	    months : {
	        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
	        format: 'de gener_de febrer_de març_d\'abril_de maig_de juny_de juliol_d\'agost_de setembre_d\'octubre_de novembre_de desembre'.split('_'),
	        isFormat: /D[oD]?(\s)+MMMM/
	    },
	    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),
	    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
	    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : '[el] D MMMM [de] YYYY',
	        ll : 'D MMM YYYY',
	        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',
	        lll : 'D MMM YYYY, H:mm',
	        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',
	        llll : 'ddd D MMM YYYY, H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        nextDay : function () {
	            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        lastDay : function () {
	            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'd\'aquí %s',
	        past : 'fa %s',
	        s : 'uns segons',
	        m : 'un minut',
	        mm : '%d minuts',
	        h : 'una hora',
	        hh : '%d hores',
	        d : 'un dia',
	        dd : '%d dies',
	        M : 'un mes',
	        MM : '%d mesos',
	        y : 'un any',
	        yy : '%d anys'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/,
	    ordinal : function (number, period) {
	        var output = (number === 1) ? 'r' :
	            (number === 2) ? 'n' :
	            (number === 3) ? 'r' :
	            (number === 4) ? 't' : 'è';
	        if (period === 'w' || period === 'W') {
	            output = 'a';
	        }
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ca;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ca.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/cs.js **/
jupyter.define('moment@2.18.1/locale/cs.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Czech [cs]
	//! author : petrbela : https://github.com/petrbela
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');
	var monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');
	function plural(n) {
	    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':  // a few seconds / in a few seconds / a few seconds ago
	            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
	        case 'm':  // a minute / in a minute / a minute ago
	            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
	        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'minuty' : 'minut');
	            } else {
	                return result + 'minutami';
	            }
	            break;
	        case 'h':  // an hour / in an hour / an hour ago
	            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
	        case 'hh': // 9 hours / in 9 hours / 9 hours ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'hodiny' : 'hodin');
	            } else {
	                return result + 'hodinami';
	            }
	            break;
	        case 'd':  // a day / in a day / a day ago
	            return (withoutSuffix || isFuture) ? 'den' : 'dnem';
	        case 'dd': // 9 days / in 9 days / 9 days ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'dny' : 'dní');
	            } else {
	                return result + 'dny';
	            }
	            break;
	        case 'M':  // a month / in a month / a month ago
	            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
	        case 'MM': // 9 months / in 9 months / 9 months ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'měsíce' : 'měsíců');
	            } else {
	                return result + 'měsíci';
	            }
	            break;
	        case 'y':  // a year / in a year / a year ago
	            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
	        case 'yy': // 9 years / in 9 years / 9 years ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'roky' : 'let');
	            } else {
	                return result + 'lety';
	            }
	            break;
	    }
	}
	
	var cs = moment.defineLocale('cs', {
	    months : months,
	    monthsShort : monthsShort,
	    monthsParse : (function (months, monthsShort) {
	        var i, _monthsParse = [];
	        for (i = 0; i < 12; i++) {
	            // use custom parser to solve problem with July (červenec)
	            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
	        }
	        return _monthsParse;
	    }(months, monthsShort)),
	    shortMonthsParse : (function (monthsShort) {
	        var i, _shortMonthsParse = [];
	        for (i = 0; i < 12; i++) {
	            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');
	        }
	        return _shortMonthsParse;
	    }(monthsShort)),
	    longMonthsParse : (function (months) {
	        var i, _longMonthsParse = [];
	        for (i = 0; i < 12; i++) {
	            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');
	        }
	        return _longMonthsParse;
	    }(months)),
	    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
	    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),
	    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
	    longDateFormat : {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd D. MMMM YYYY H:mm',
	        l : 'D. M. YYYY'
	    },
	    calendar : {
	        sameDay: '[dnes v] LT',
	        nextDay: '[zítra v] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v neděli v] LT';
	                case 1:
	                case 2:
	                    return '[v] dddd [v] LT';
	                case 3:
	                    return '[ve středu v] LT';
	                case 4:
	                    return '[ve čtvrtek v] LT';
	                case 5:
	                    return '[v pátek v] LT';
	                case 6:
	                    return '[v sobotu v] LT';
	            }
	        },
	        lastDay: '[včera v] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[minulou neděli v] LT';
	                case 1:
	                case 2:
	                    return '[minulé] dddd [v] LT';
	                case 3:
	                    return '[minulou středu v] LT';
	                case 4:
	                case 5:
	                    return '[minulý] dddd [v] LT';
	                case 6:
	                    return '[minulou sobotu v] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : 'před %s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return cs;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/cs.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/cv.js **/
jupyter.define('moment@2.18.1/locale/cv.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Chuvash [cv]
	//! author : Anatoly Mironov : https://github.com/mirontoli
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var cv = moment.defineLocale('cv', {
	    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),
	    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
	    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),
	    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
	    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
	        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
	        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
	    },
	    calendar : {
	        sameDay: '[Паян] LT [сехетре]',
	        nextDay: '[Ыран] LT [сехетре]',
	        lastDay: '[Ӗнер] LT [сехетре]',
	        nextWeek: '[Ҫитес] dddd LT [сехетре]',
	        lastWeek: '[Иртнӗ] dddd LT [сехетре]',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : function (output) {
	            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';
	            return output + affix;
	        },
	        past : '%s каялла',
	        s : 'пӗр-ик ҫеккунт',
	        m : 'пӗр минут',
	        mm : '%d минут',
	        h : 'пӗр сехет',
	        hh : '%d сехет',
	        d : 'пӗр кун',
	        dd : '%d кун',
	        M : 'пӗр уйӑх',
	        MM : '%d уйӑх',
	        y : 'пӗр ҫул',
	        yy : '%d ҫул'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-мӗш/,
	    ordinal : '%d-мӗш',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return cv;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/cv.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/cy.js **/
jupyter.define('moment@2.18.1/locale/cy.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Welsh [cy]
	//! author : Robert Allen : https://github.com/robgallen
	//! author : https://github.com/ryangreaves
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var cy = moment.defineLocale('cy', {
	    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),
	    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),
	    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),
	    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
	    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
	    weekdaysParseExact : true,
	    // time formats are the same as en-gb
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[Heddiw am] LT',
	        nextDay: '[Yfory am] LT',
	        nextWeek: 'dddd [am] LT',
	        lastDay: '[Ddoe am] LT',
	        lastWeek: 'dddd [diwethaf am] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'mewn %s',
	        past: '%s yn ôl',
	        s: 'ychydig eiliadau',
	        m: 'munud',
	        mm: '%d munud',
	        h: 'awr',
	        hh: '%d awr',
	        d: 'diwrnod',
	        dd: '%d diwrnod',
	        M: 'mis',
	        MM: '%d mis',
	        y: 'blwyddyn',
	        yy: '%d flynedd'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
	    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
	    ordinal: function (number) {
	        var b = number,
	            output = '',
	            lookup = [
	                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
	                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
	            ];
	        if (b > 20) {
	            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
	                output = 'fed'; // not 30ain, 70ain or 90ain
	            } else {
	                output = 'ain';
	            }
	        } else if (b > 0) {
	            output = lookup[b];
	        }
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return cy;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/cy.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/da.js **/
jupyter.define('moment@2.18.1/locale/da.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Danish [da]
	//! author : Ulrik Nielsen : https://github.com/mrbase
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var da = moment.defineLocale('da', {
	    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
	    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),
	    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay : '[i dag kl.] LT',
	        nextDay : '[i morgen kl.] LT',
	        nextWeek : 'på dddd [kl.] LT',
	        lastDay : '[i går kl.] LT',
	        lastWeek : '[i] dddd[s kl.] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s siden',
	        s : 'få sekunder',
	        m : 'et minut',
	        mm : '%d minutter',
	        h : 'en time',
	        hh : '%d timer',
	        d : 'en dag',
	        dd : '%d dage',
	        M : 'en måned',
	        MM : '%d måneder',
	        y : 'et år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return da;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/da.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/de.js **/
jupyter.define('moment@2.18.1/locale/de.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : German [de]
	//! author : lluchs : https://github.com/lluchs
	//! author: Menelion Elensúle: https://github.com/Oire
	//! author : Mikolaj Dadela : https://github.com/mik01aj
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var de = moment.defineLocale('de', {
	    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd, D. MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return de;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/de.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/de-at.js **/
jupyter.define('moment@2.18.1/locale/de-at.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : German (Austria) [de-at]
	//! author : lluchs : https://github.com/lluchs
	//! author: Menelion Elensúle: https://github.com/Oire
	//! author : Martin Groller : https://github.com/MadMG
	//! author : Mikolaj Dadela : https://github.com/mik01aj
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var deAt = moment.defineLocale('de-at', {
	    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH:mm',
	        LLLL : 'dddd, D. MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return deAt;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/de-at.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/de-ch.js **/
jupyter.define('moment@2.18.1/locale/de-ch.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : German (Switzerland) [de-ch]
	//! author : sschueller : https://github.com/sschueller
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eine Minute', 'einer Minute'],
	        'h': ['eine Stunde', 'einer Stunde'],
	        'd': ['ein Tag', 'einem Tag'],
	        'dd': [number + ' Tage', number + ' Tagen'],
	        'M': ['ein Monat', 'einem Monat'],
	        'MM': [number + ' Monate', number + ' Monaten'],
	        'y': ['ein Jahr', 'einem Jahr'],
	        'yy': [number + ' Jahre', number + ' Jahren']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var deCh = moment.defineLocale('de-ch', {
	    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
	    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT: 'HH.mm',
	        LTS: 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY HH.mm',
	        LLLL : 'dddd, D. MMMM YYYY HH.mm'
	    },
	    calendar : {
	        sameDay: '[heute um] LT [Uhr]',
	        sameElse: 'L',
	        nextDay: '[morgen um] LT [Uhr]',
	        nextWeek: 'dddd [um] LT [Uhr]',
	        lastDay: '[gestern um] LT [Uhr]',
	        lastWeek: '[letzten] dddd [um] LT [Uhr]'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : 'vor %s',
	        s : 'ein paar Sekunden',
	        m : processRelativeTime,
	        mm : '%d Minuten',
	        h : processRelativeTime,
	        hh : '%d Stunden',
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return deCh;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/de-ch.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/dv.js **/
jupyter.define('moment@2.18.1/locale/dv.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Maldivian [dv]
	//! author : Jawish Hameed : https://github.com/jawish
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'ޖެނުއަރީ',
	    'ފެބްރުއަރީ',
	    'މާރިޗު',
	    'އޭޕްރީލު',
	    'މޭ',
	    'ޖޫން',
	    'ޖުލައި',
	    'އޯގަސްޓު',
	    'ސެޕްޓެމްބަރު',
	    'އޮކްޓޯބަރު',
	    'ނޮވެމްބަރު',
	    'ޑިސެމްބަރު'
	];
	var weekdays = [
	    'އާދިއްތަ',
	    'ހޯމަ',
	    'އަންގާރަ',
	    'ބުދަ',
	    'ބުރާސްފަތި',
	    'ހުކުރު',
	    'ހޮނިހިރު'
	];
	
	var dv = moment.defineLocale('dv', {
	    months : months,
	    monthsShort : months,
	    weekdays : weekdays,
	    weekdaysShort : weekdays,
	    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),
	    longDateFormat : {
	
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'D/M/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /މކ|މފ/,
	    isPM : function (input) {
	        return 'މފ' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'މކ';
	        } else {
	            return 'މފ';
	        }
	    },
	    calendar : {
	        sameDay : '[މިއަދު] LT',
	        nextDay : '[މާދަމާ] LT',
	        nextWeek : 'dddd LT',
	        lastDay : '[އިއްޔެ] LT',
	        lastWeek : '[ފާއިތުވި] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ތެރޭގައި %s',
	        past : 'ކުރިން %s',
	        s : 'ސިކުންތުކޮޅެއް',
	        m : 'މިނިޓެއް',
	        mm : 'މިނިޓު %d',
	        h : 'ގަޑިއިރެއް',
	        hh : 'ގަޑިއިރު %d',
	        d : 'ދުވަހެއް',
	        dd : 'ދުވަސް %d',
	        M : 'މަހެއް',
	        MM : 'މަސް %d',
	        y : 'އަހަރެއް',
	        yy : 'އަހަރު %d'
	    },
	    preparse: function (string) {
	        return string.replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/,/g, '،');
	    },
	    week : {
	        dow : 7,  // Sunday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return dv;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/dv.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/el.js **/
jupyter.define('moment@2.18.1/locale/el.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Greek [el]
	//! author : Aggelos Karalias : https://github.com/mehiel
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	function isFunction(input) {
	    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
	}
	
	
	var el = moment.defineLocale('el', {
	    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),
	    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),
	    months : function (momentToFormat, format) {
	        if (!momentToFormat) {
	            return this._monthsNominativeEl;
	        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'
	            return this._monthsGenitiveEl[momentToFormat.month()];
	        } else {
	            return this._monthsNominativeEl[momentToFormat.month()];
	        }
	    },
	    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
	    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),
	    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),
	    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'μμ' : 'ΜΜ';
	        } else {
	            return isLower ? 'πμ' : 'ΠΜ';
	        }
	    },
	    isPM : function (input) {
	        return ((input + '').toLowerCase()[0] === 'μ');
	    },
	    meridiemParse : /[ΠΜ]\.?Μ?\.?/i,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendarEl : {
	        sameDay : '[Σήμερα {}] LT',
	        nextDay : '[Αύριο {}] LT',
	        nextWeek : 'dddd [{}] LT',
	        lastDay : '[Χθες {}] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 6:
	                    return '[το προηγούμενο] dddd [{}] LT';
	                default:
	                    return '[την προηγούμενη] dddd [{}] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    calendar : function (key, mom) {
	        var output = this._calendarEl[key],
	            hours = mom && mom.hours();
	        if (isFunction(output)) {
	            output = output.apply(mom);
	        }
	        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));
	    },
	    relativeTime : {
	        future : 'σε %s',
	        past : '%s πριν',
	        s : 'λίγα δευτερόλεπτα',
	        m : 'ένα λεπτό',
	        mm : '%d λεπτά',
	        h : 'μία ώρα',
	        hh : '%d ώρες',
	        d : 'μία μέρα',
	        dd : '%d μέρες',
	        M : 'ένας μήνας',
	        MM : '%d μήνες',
	        y : 'ένας χρόνος',
	        yy : '%d χρόνια'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}η/,
	    ordinal: '%dη',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4st is the first week of the year.
	    }
	});
	
	return el;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/el.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/en-au.js **/
jupyter.define('moment@2.18.1/locale/en-au.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : English (Australia) [en-au]
	//! author : Jared Morse : https://github.com/jarcoal
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enAu = moment.defineLocale('en-au', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few seconds',
	        m : 'a minute',
	        mm : '%d minutes',
	        h : 'an hour',
	        hh : '%d hours',
	        d : 'a day',
	        dd : '%d days',
	        M : 'a month',
	        MM : '%d months',
	        y : 'a year',
	        yy : '%d years'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enAu;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/en-au.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/en-ca.js **/
jupyter.define('moment@2.18.1/locale/en-ca.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : English (Canada) [en-ca]
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enCa = moment.defineLocale('en-ca', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'YYYY-MM-DD',
	        LL : 'MMMM D, YYYY',
	        LLL : 'MMMM D, YYYY h:mm A',
	        LLLL : 'dddd, MMMM D, YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few seconds',
	        m : 'a minute',
	        mm : '%d minutes',
	        h : 'an hour',
	        hh : '%d hours',
	        d : 'a day',
	        dd : '%d days',
	        M : 'a month',
	        MM : '%d months',
	        y : 'a year',
	        yy : '%d years'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    }
	});
	
	return enCa;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/en-ca.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/en-gb.js **/
jupyter.define('moment@2.18.1/locale/en-gb.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : English (United Kingdom) [en-gb]
	//! author : Chris Gedrim : https://github.com/chrisgedrim
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enGb = moment.defineLocale('en-gb', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few seconds',
	        m : 'a minute',
	        mm : '%d minutes',
	        h : 'an hour',
	        hh : '%d hours',
	        d : 'a day',
	        dd : '%d days',
	        M : 'a month',
	        MM : '%d months',
	        y : 'a year',
	        yy : '%d years'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enGb;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/en-gb.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/en-ie.js **/
jupyter.define('moment@2.18.1/locale/en-ie.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : English (Ireland) [en-ie]
	//! author : Chris Cartlidge : https://github.com/chriscartlidge
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enIe = moment.defineLocale('en-ie', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few seconds',
	        m : 'a minute',
	        mm : '%d minutes',
	        h : 'an hour',
	        hh : '%d hours',
	        d : 'a day',
	        dd : '%d days',
	        M : 'a month',
	        MM : '%d months',
	        y : 'a year',
	        yy : '%d years'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enIe;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/en-ie.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/en-nz.js **/
jupyter.define('moment@2.18.1/locale/en-nz.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : English (New Zealand) [en-nz]
	//! author : Luke McGregor : https://github.com/lukemcgregor
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var enNz = moment.defineLocale('en-nz', {
	    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
	    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
	    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
	    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Today at] LT',
	        nextDay : '[Tomorrow at] LT',
	        nextWeek : 'dddd [at] LT',
	        lastDay : '[Yesterday at] LT',
	        lastWeek : '[Last] dddd [at] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'in %s',
	        past : '%s ago',
	        s : 'a few seconds',
	        m : 'a minute',
	        mm : '%d minutes',
	        h : 'an hour',
	        hh : '%d hours',
	        d : 'a day',
	        dd : '%d days',
	        M : 'a month',
	        MM : '%d months',
	        y : 'a year',
	        yy : '%d years'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return enNz;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/en-nz.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/eo.js **/
jupyter.define('moment@2.18.1/locale/eo.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Esperanto [eo]
	//! author : Colin Dean : https://github.com/colindean
	//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia
	//! comment : miestasmia corrected the translation by colindean
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var eo = moment.defineLocale('eo', {
	    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),
	    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),
	    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),
	    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D[-a de] MMMM, YYYY',
	        LLL : 'D[-a de] MMMM, YYYY HH:mm',
	        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'
	    },
	    meridiemParse: /[ap]\.t\.m/i,
	    isPM: function (input) {
	        return input.charAt(0).toLowerCase() === 'p';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'p.t.m.' : 'P.T.M.';
	        } else {
	            return isLower ? 'a.t.m.' : 'A.T.M.';
	        }
	    },
	    calendar : {
	        sameDay : '[Hodiaŭ je] LT',
	        nextDay : '[Morgaŭ je] LT',
	        nextWeek : 'dddd [je] LT',
	        lastDay : '[Hieraŭ je] LT',
	        lastWeek : '[pasinta] dddd [je] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'post %s',
	        past : 'antaŭ %s',
	        s : 'sekundoj',
	        m : 'minuto',
	        mm : '%d minutoj',
	        h : 'horo',
	        hh : '%d horoj',
	        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo
	        dd : '%d tagoj',
	        M : 'monato',
	        MM : '%d monatoj',
	        y : 'jaro',
	        yy : '%d jaroj'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}a/,
	    ordinal : '%da',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return eo;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/eo.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/es.js **/
jupyter.define('moment@2.18.1/locale/es.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Spanish [es]
	//! author : Julio Napurí : https://github.com/julionc
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');
	var monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
	
	var es = moment.defineLocale('es', {
	    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortDot;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShort[m.month()];
	        } else {
	            return monthsShortDot[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY H:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastDay : function () {
	            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'en %s',
	        past : 'hace %s',
	        s : 'unos segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'una hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un año',
	        yy : '%d años'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return es;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/es.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/es-do.js **/
jupyter.define('moment@2.18.1/locale/es-do.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Spanish (Dominican Republic) [es-do]
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');
	var monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');
	
	var esDo = moment.defineLocale('es-do', {
	    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortDot;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShort[m.month()];
	        } else {
	            return monthsShortDot[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY h:mm A',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastDay : function () {
	            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        lastWeek : function () {
	            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'en %s',
	        past : 'hace %s',
	        s : 'unos segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'una hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un año',
	        yy : '%d años'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return esDo;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/es-do.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/et.js **/
jupyter.define('moment@2.18.1/locale/et.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Estonian [et]
	//! author : Henry Kehlmann : https://github.com/madhenry
	//! improvements : Illimar Tambek : https://github.com/ragulka
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
	        'm' : ['ühe minuti', 'üks minut'],
	        'mm': [number + ' minuti', number + ' minutit'],
	        'h' : ['ühe tunni', 'tund aega', 'üks tund'],
	        'hh': [number + ' tunni', number + ' tundi'],
	        'd' : ['ühe päeva', 'üks päev'],
	        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],
	        'MM': [number + ' kuu', number + ' kuud'],
	        'y' : ['ühe aasta', 'aasta', 'üks aasta'],
	        'yy': [number + ' aasta', number + ' aastat']
	    };
	    if (withoutSuffix) {
	        return format[key][2] ? format[key][2] : format[key][1];
	    }
	    return isFuture ? format[key][0] : format[key][1];
	}
	
	var et = moment.defineLocale('et', {
	    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),
	    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),
	    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),
	    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),
	    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),
	    longDateFormat : {
	        LT   : 'H:mm',
	        LTS : 'H:mm:ss',
	        L    : 'DD.MM.YYYY',
	        LL   : 'D. MMMM YYYY',
	        LLL  : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[Täna,] LT',
	        nextDay  : '[Homme,] LT',
	        nextWeek : '[Järgmine] dddd LT',
	        lastDay  : '[Eile,] LT',
	        lastWeek : '[Eelmine] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s pärast',
	        past   : '%s tagasi',
	        s      : processRelativeTime,
	        m      : processRelativeTime,
	        mm     : processRelativeTime,
	        h      : processRelativeTime,
	        hh     : processRelativeTime,
	        d      : processRelativeTime,
	        dd     : '%d päeva',
	        M      : processRelativeTime,
	        MM     : processRelativeTime,
	        y      : processRelativeTime,
	        yy     : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return et;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/et.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/eu.js **/
jupyter.define('moment@2.18.1/locale/eu.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Basque [eu]
	//! author : Eneko Illarramendi : https://github.com/eillarra
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var eu = moment.defineLocale('eu', {
	    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),
	    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),
	    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),
	    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'YYYY[ko] MMMM[ren] D[a]',
	        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
	        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
	        l : 'YYYY-M-D',
	        ll : 'YYYY[ko] MMM D[a]',
	        lll : 'YYYY[ko] MMM D[a] HH:mm',
	        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
	    },
	    calendar : {
	        sameDay : '[gaur] LT[etan]',
	        nextDay : '[bihar] LT[etan]',
	        nextWeek : 'dddd LT[etan]',
	        lastDay : '[atzo] LT[etan]',
	        lastWeek : '[aurreko] dddd LT[etan]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s barru',
	        past : 'duela %s',
	        s : 'segundo batzuk',
	        m : 'minutu bat',
	        mm : '%d minutu',
	        h : 'ordu bat',
	        hh : '%d ordu',
	        d : 'egun bat',
	        dd : '%d egun',
	        M : 'hilabete bat',
	        MM : '%d hilabete',
	        y : 'urte bat',
	        yy : '%d urte'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return eu;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/eu.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/fa.js **/
jupyter.define('moment@2.18.1/locale/fa.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Persian [fa]
	//! author : Ebrahim Byagowi : https://github.com/ebraminio
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '۱',
	    '2': '۲',
	    '3': '۳',
	    '4': '۴',
	    '5': '۵',
	    '6': '۶',
	    '7': '۷',
	    '8': '۸',
	    '9': '۹',
	    '0': '۰'
	};
	var numberMap = {
	    '۱': '1',
	    '۲': '2',
	    '۳': '3',
	    '۴': '4',
	    '۵': '5',
	    '۶': '6',
	    '۷': '7',
	    '۸': '8',
	    '۹': '9',
	    '۰': '0'
	};
	
	var fa = moment.defineLocale('fa', {
	    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
	    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
	    weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
	    weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
	    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /قبل از ظهر|بعد از ظهر/,
	    isPM: function (input) {
	        return /بعد از ظهر/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'قبل از ظهر';
	        } else {
	            return 'بعد از ظهر';
	        }
	    },
	    calendar : {
	        sameDay : '[امروز ساعت] LT',
	        nextDay : '[فردا ساعت] LT',
	        nextWeek : 'dddd [ساعت] LT',
	        lastDay : '[دیروز ساعت] LT',
	        lastWeek : 'dddd [پیش] [ساعت] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'در %s',
	        past : '%s پیش',
	        s : 'چند ثانیه',
	        m : 'یک دقیقه',
	        mm : '%d دقیقه',
	        h : 'یک ساعت',
	        hh : '%d ساعت',
	        d : 'یک روز',
	        dd : '%d روز',
	        M : 'یک ماه',
	        MM : '%d ماه',
	        y : 'یک سال',
	        yy : '%d سال'
	    },
	    preparse: function (string) {
	        return string.replace(/[۰-۹]/g, function (match) {
	            return numberMap[match];
	        }).replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        }).replace(/,/g, '،');
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}م/,
	    ordinal : '%dم',
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12 // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return fa;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/fa.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/fi.js **/
jupyter.define('moment@2.18.1/locale/fi.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Finnish [fi]
	//! author : Tarmo Aidantausta : https://github.com/bleadof
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');
	var numbersFuture = [
	        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
	        numbersPast[7], numbersPast[8], numbersPast[9]
	    ];
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = '';
	    switch (key) {
	        case 's':
	            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
	        case 'm':
	            return isFuture ? 'minuutin' : 'minuutti';
	        case 'mm':
	            result = isFuture ? 'minuutin' : 'minuuttia';
	            break;
	        case 'h':
	            return isFuture ? 'tunnin' : 'tunti';
	        case 'hh':
	            result = isFuture ? 'tunnin' : 'tuntia';
	            break;
	        case 'd':
	            return isFuture ? 'päivän' : 'päivä';
	        case 'dd':
	            result = isFuture ? 'päivän' : 'päivää';
	            break;
	        case 'M':
	            return isFuture ? 'kuukauden' : 'kuukausi';
	        case 'MM':
	            result = isFuture ? 'kuukauden' : 'kuukautta';
	            break;
	        case 'y':
	            return isFuture ? 'vuoden' : 'vuosi';
	        case 'yy':
	            result = isFuture ? 'vuoden' : 'vuotta';
	            break;
	    }
	    result = verbalNumber(number, isFuture) + ' ' + result;
	    return result;
	}
	function verbalNumber(number, isFuture) {
	    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;
	}
	
	var fi = moment.defineLocale('fi', {
	    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),
	    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),
	    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),
	    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),
	    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'Do MMMM[ta] YYYY',
	        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
	        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
	        l : 'D.M.YYYY',
	        ll : 'Do MMM YYYY',
	        lll : 'Do MMM YYYY, [klo] HH.mm',
	        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
	    },
	    calendar : {
	        sameDay : '[tänään] [klo] LT',
	        nextDay : '[huomenna] [klo] LT',
	        nextWeek : 'dddd [klo] LT',
	        lastDay : '[eilen] [klo] LT',
	        lastWeek : '[viime] dddd[na] [klo] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s päästä',
	        past : '%s sitten',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fi;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/fi.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/fo.js **/
jupyter.define('moment@2.18.1/locale/fo.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Faroese [fo]
	//! author : Ragnar Johannesen : https://github.com/ragnar123
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var fo = moment.defineLocale('fo', {
	    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
	    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),
	    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),
	    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D. MMMM, YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Í dag kl.] LT',
	        nextDay : '[Í morgin kl.] LT',
	        nextWeek : 'dddd [kl.] LT',
	        lastDay : '[Í gjár kl.] LT',
	        lastWeek : '[síðstu] dddd [kl] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'um %s',
	        past : '%s síðani',
	        s : 'fá sekund',
	        m : 'ein minutt',
	        mm : '%d minuttir',
	        h : 'ein tími',
	        hh : '%d tímar',
	        d : 'ein dagur',
	        dd : '%d dagar',
	        M : 'ein mánaði',
	        MM : '%d mánaðir',
	        y : 'eitt ár',
	        yy : '%d ár'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fo;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/fo.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/fr.js **/
jupyter.define('moment@2.18.1/locale/fr.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : French [fr]
	//! author : John Fischer : https://github.com/jfroffice
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var fr = moment.defineLocale('fr', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Aujourd’hui à] LT',
	        nextDay : '[Demain à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[Hier à] LT',
	        lastWeek : 'dddd [dernier à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // TODO: Return 'e' when day of month > 1. Move this case inside
	            // block for masculine words below.
	            // See https://github.com/moment/moment/issues/3375
	            case 'D':
	                return number + (number === 1 ? 'er' : '');
	
	            // Words with masculine grammatical gender: mois, trimestre, jour
	            default:
	            case 'M':
	            case 'Q':
	            case 'DDD':
	            case 'd':
	                return number + (number === 1 ? 'er' : 'e');
	
	            // Words with feminine grammatical gender: semaine
	            case 'w':
	            case 'W':
	                return number + (number === 1 ? 're' : 'e');
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fr;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/fr.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/fr-ca.js **/
jupyter.define('moment@2.18.1/locale/fr-ca.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : French (Canada) [fr-ca]
	//! author : Jonathan Abourbih : https://github.com/jonbca
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var frCa = moment.defineLocale('fr-ca', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Aujourd’hui à] LT',
	        nextDay : '[Demain à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[Hier à] LT',
	        lastWeek : 'dddd [dernier à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // Words with masculine grammatical gender: mois, trimestre, jour
	            default:
	            case 'M':
	            case 'Q':
	            case 'D':
	            case 'DDD':
	            case 'd':
	                return number + (number === 1 ? 'er' : 'e');
	
	            // Words with feminine grammatical gender: semaine
	            case 'w':
	            case 'W':
	                return number + (number === 1 ? 're' : 'e');
	        }
	    }
	});
	
	return frCa;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/fr-ca.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/fr-ch.js **/
jupyter.define('moment@2.18.1/locale/fr-ch.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : French (Switzerland) [fr-ch]
	//! author : Gaspard Bucher : https://github.com/gaspard
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var frCh = moment.defineLocale('fr-ch', {
	    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
	    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
	    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
	    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Aujourd’hui à] LT',
	        nextDay : '[Demain à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[Hier à] LT',
	        lastWeek : 'dddd [dernier à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dans %s',
	        past : 'il y a %s',
	        s : 'quelques secondes',
	        m : 'une minute',
	        mm : '%d minutes',
	        h : 'une heure',
	        hh : '%d heures',
	        d : 'un jour',
	        dd : '%d jours',
	        M : 'un mois',
	        MM : '%d mois',
	        y : 'un an',
	        yy : '%d ans'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // Words with masculine grammatical gender: mois, trimestre, jour
	            default:
	            case 'M':
	            case 'Q':
	            case 'D':
	            case 'DDD':
	            case 'd':
	                return number + (number === 1 ? 'er' : 'e');
	
	            // Words with feminine grammatical gender: semaine
	            case 'w':
	            case 'W':
	                return number + (number === 1 ? 're' : 'e');
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return frCh;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/fr-ch.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/fy.js **/
jupyter.define('moment@2.18.1/locale/fy.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Frisian [fy]
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');
	
	var fy = moment.defineLocale('fy', {
	    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortWithDots;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	    monthsParseExact : true,
	    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),
	    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),
	    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[hjoed om] LT',
	        nextDay: '[moarn om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[juster om] LT',
	        lastWeek: '[ôfrûne] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'oer %s',
	        past : '%s lyn',
	        s : 'in pear sekonden',
	        m : 'ien minút',
	        mm : '%d minuten',
	        h : 'ien oere',
	        hh : '%d oeren',
	        d : 'ien dei',
	        dd : '%d dagen',
	        M : 'ien moanne',
	        MM : '%d moannen',
	        y : 'ien jier',
	        yy : '%d jierren'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return fy;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/fy.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/gd.js **/
jupyter.define('moment@2.18.1/locale/gd.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Scottish Gaelic [gd]
	//! author : Jon Ashdown : https://github.com/jonashdown
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'
	];
	
	var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];
	
	var weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];
	
	var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];
	
	var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];
	
	var gd = moment.defineLocale('gd', {
	    months : months,
	    monthsShort : monthsShort,
	    monthsParseExact : true,
	    weekdays : weekdays,
	    weekdaysShort : weekdaysShort,
	    weekdaysMin : weekdaysMin,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[An-diugh aig] LT',
	        nextDay : '[A-màireach aig] LT',
	        nextWeek : 'dddd [aig] LT',
	        lastDay : '[An-dè aig] LT',
	        lastWeek : 'dddd [seo chaidh] [aig] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ann an %s',
	        past : 'bho chionn %s',
	        s : 'beagan diogan',
	        m : 'mionaid',
	        mm : '%d mionaidean',
	        h : 'uair',
	        hh : '%d uairean',
	        d : 'latha',
	        dd : '%d latha',
	        M : 'mìos',
	        MM : '%d mìosan',
	        y : 'bliadhna',
	        yy : '%d bliadhna'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}(d|na|mh)/,
	    ordinal : function (number) {
	        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return gd;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/gd.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/gl.js **/
jupyter.define('moment@2.18.1/locale/gl.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Galician [gl]
	//! author : Juan G. Hurtado : https://github.com/juanghurtado
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var gl = moment.defineLocale('gl', {
	    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),
	    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),
	    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),
	    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY H:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
	    },
	    calendar : {
	        sameDay : function () {
	            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
	        },
	        nextDay : function () {
	            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
	        },
	        nextWeek : function () {
	            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
	        },
	        lastDay : function () {
	            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';
	        },
	        lastWeek : function () {
	            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : function (str) {
	            if (str.indexOf('un') === 0) {
	                return 'n' + str;
	            }
	            return 'en ' + str;
	        },
	        past : 'hai %s',
	        s : 'uns segundos',
	        m : 'un minuto',
	        mm : '%d minutos',
	        h : 'unha hora',
	        hh : '%d horas',
	        d : 'un día',
	        dd : '%d días',
	        M : 'un mes',
	        MM : '%d meses',
	        y : 'un ano',
	        yy : '%d anos'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return gl;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/gl.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/gom-latn.js **/
jupyter.define('moment@2.18.1/locale/gom-latn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Konkani Latin script [gom-latn]
	//! author : The Discoverer : https://github.com/WikiDiscoverer
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's': ['thodde secondanim', 'thodde second'],
	        'm': ['eka mintan', 'ek minute'],
	        'mm': [number + ' mintanim', number + ' mintam'],
	        'h': ['eka horan', 'ek hor'],
	        'hh': [number + ' horanim', number + ' hor'],
	        'd': ['eka disan', 'ek dis'],
	        'dd': [number + ' disanim', number + ' dis'],
	        'M': ['eka mhoinean', 'ek mhoino'],
	        'MM': [number + ' mhoineanim', number + ' mhoine'],
	        'y': ['eka vorsan', 'ek voros'],
	        'yy': [number + ' vorsanim', number + ' vorsam']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	
	var gomLatn = moment.defineLocale('gom-latn', {
	    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),
	    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\'var'.split('_'),
	    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),
	    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'A h:mm [vazta]',
	        LTS : 'A h:mm:ss [vazta]',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY A h:mm [vazta]',
	        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',
	        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'
	    },
	    calendar : {
	        sameDay: '[Aiz] LT',
	        nextDay: '[Faleam] LT',
	        nextWeek: '[Ieta to] dddd[,] LT',
	        lastDay: '[Kal] LT',
	        lastWeek: '[Fatlo] dddd[,] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s',
	        past : '%s adim',
	        s : processRelativeTime,
	        m : processRelativeTime,
	        mm : processRelativeTime,
	        h : processRelativeTime,
	        hh : processRelativeTime,
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}(er)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            // the ordinal 'er' only applies to day of the month
	            case 'D':
	                return number + 'er';
	            default:
	            case 'M':
	            case 'Q':
	            case 'DDD':
	            case 'd':
	            case 'w':
	            case 'W':
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    },
	    meridiemParse: /rati|sokalli|donparam|sanje/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'rati') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'sokalli') {
	            return hour;
	        } else if (meridiem === 'donparam') {
	            return hour > 12 ? hour : hour + 12;
	        } else if (meridiem === 'sanje') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'rati';
	        } else if (hour < 12) {
	            return 'sokalli';
	        } else if (hour < 16) {
	            return 'donparam';
	        } else if (hour < 20) {
	            return 'sanje';
	        } else {
	            return 'rati';
	        }
	    }
	});
	
	return gomLatn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/gom-latn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/he.js **/
jupyter.define('moment@2.18.1/locale/he.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Hebrew [he]
	//! author : Tomer Cohen : https://github.com/tomer
	//! author : Moshe Simantov : https://github.com/DevelopmentIL
	//! author : Tal Ater : https://github.com/TalAter
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var he = moment.defineLocale('he', {
	    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),
	    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),
	    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),
	    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),
	    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [ב]MMMM YYYY',
	        LLL : 'D [ב]MMMM YYYY HH:mm',
	        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
	        l : 'D/M/YYYY',
	        ll : 'D MMM YYYY',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd, D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[היום ב־]LT',
	        nextDay : '[מחר ב־]LT',
	        nextWeek : 'dddd [בשעה] LT',
	        lastDay : '[אתמול ב־]LT',
	        lastWeek : '[ביום] dddd [האחרון בשעה] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'בעוד %s',
	        past : 'לפני %s',
	        s : 'מספר שניות',
	        m : 'דקה',
	        mm : '%d דקות',
	        h : 'שעה',
	        hh : function (number) {
	            if (number === 2) {
	                return 'שעתיים';
	            }
	            return number + ' שעות';
	        },
	        d : 'יום',
	        dd : function (number) {
	            if (number === 2) {
	                return 'יומיים';
	            }
	            return number + ' ימים';
	        },
	        M : 'חודש',
	        MM : function (number) {
	            if (number === 2) {
	                return 'חודשיים';
	            }
	            return number + ' חודשים';
	        },
	        y : 'שנה',
	        yy : function (number) {
	            if (number === 2) {
	                return 'שנתיים';
	            } else if (number % 10 === 0 && number !== 10) {
	                return number + ' שנה';
	            }
	            return number + ' שנים';
	        }
	    },
	    meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,
	    isPM : function (input) {
	        return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 5) {
	            return 'לפנות בוקר';
	        } else if (hour < 10) {
	            return 'בבוקר';
	        } else if (hour < 12) {
	            return isLower ? 'לפנה"צ' : 'לפני הצהריים';
	        } else if (hour < 18) {
	            return isLower ? 'אחה"צ' : 'אחרי הצהריים';
	        } else {
	            return 'בערב';
	        }
	    }
	});
	
	return he;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/he.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/hi.js **/
jupyter.define('moment@2.18.1/locale/hi.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Hindi [hi]
	//! author : Mayank Singhal : https://github.com/mayanksinghal
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	var hi = moment.defineLocale('hi', {
	    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),
	    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
	    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),
	    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm बजे',
	        LTS : 'A h:mm:ss बजे',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm बजे',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[कल] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[कल] LT',
	        lastWeek : '[पिछले] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s में',
	        past : '%s पहले',
	        s : 'कुछ ही क्षण',
	        m : 'एक मिनट',
	        mm : '%d मिनट',
	        h : 'एक घंटा',
	        hh : '%d घंटे',
	        d : 'एक दिन',
	        dd : '%d दिन',
	        M : 'एक महीने',
	        MM : '%d महीने',
	        y : 'एक वर्ष',
	        yy : '%d वर्ष'
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // Hindi notation for meridiems are quite fuzzy in practice. While there exists
	    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
	    meridiemParse: /रात|सुबह|दोपहर|शाम/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'रात') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'सुबह') {
	            return hour;
	        } else if (meridiem === 'दोपहर') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'शाम') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'रात';
	        } else if (hour < 10) {
	            return 'सुबह';
	        } else if (hour < 17) {
	            return 'दोपहर';
	        } else if (hour < 20) {
	            return 'शाम';
	        } else {
	            return 'रात';
	        }
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return hi;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/hi.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/hr.js **/
jupyter.define('moment@2.18.1/locale/hr.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Croatian [hr]
	//! author : Bojan Marković : https://github.com/bmarkovic
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
	        case 'mm':
	            if (number === 1) {
	                result += 'minuta';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'minute';
	            } else {
	                result += 'minuta';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'jedan sat' : 'jednog sata';
	        case 'hh':
	            if (number === 1) {
	                result += 'sat';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'sata';
	            } else {
	                result += 'sati';
	            }
	            return result;
	        case 'dd':
	            if (number === 1) {
	                result += 'dan';
	            } else {
	                result += 'dana';
	            }
	            return result;
	        case 'MM':
	            if (number === 1) {
	                result += 'mjesec';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'mjeseca';
	            } else {
	                result += 'mjeseci';
	            }
	            return result;
	        case 'yy':
	            if (number === 1) {
	                result += 'godina';
	            } else if (number === 2 || number === 3 || number === 4) {
	                result += 'godine';
	            } else {
	                result += 'godina';
	            }
	            return result;
	    }
	}
	
	var hr = moment.defineLocale('hr', {
	    months : {
	        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),
	        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')
	    },
	    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danas u] LT',
	        nextDay  : '[sutra u] LT',
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[jučer u] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                    return '[prošlu] dddd [u] LT';
	                case 6:
	                    return '[prošle] [subote] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prošli] dddd [u] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'par sekundi',
	        m      : translate,
	        mm     : translate,
	        h      : translate,
	        hh     : translate,
	        d      : 'dan',
	        dd     : translate,
	        M      : 'mjesec',
	        MM     : translate,
	        y      : 'godinu',
	        yy     : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return hr;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/hr.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/hu.js **/
jupyter.define('moment@2.18.1/locale/hu.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Hungarian [hu]
	//! author : Adam Brunner : https://github.com/adambrunner
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
	function translate(number, withoutSuffix, key, isFuture) {
	    var num = number,
	        suffix;
	    switch (key) {
	        case 's':
	            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
	        case 'm':
	            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
	        case 'mm':
	            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
	        case 'h':
	            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
	        case 'hh':
	            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
	        case 'd':
	            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
	        case 'dd':
	            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
	        case 'M':
	            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
	        case 'MM':
	            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
	        case 'y':
	            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
	        case 'yy':
	            return num + (isFuture || withoutSuffix ? ' év' : ' éve');
	    }
	    return '';
	}
	function week(isFuture) {
	    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
	}
	
	var hu = moment.defineLocale('hu', {
	    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),
	    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),
	    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),
	    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),
	    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'YYYY.MM.DD.',
	        LL : 'YYYY. MMMM D.',
	        LLL : 'YYYY. MMMM D. H:mm',
	        LLLL : 'YYYY. MMMM D., dddd H:mm'
	    },
	    meridiemParse: /de|du/i,
	    isPM: function (input) {
	        return input.charAt(1).toLowerCase() === 'u';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower === true ? 'de' : 'DE';
	        } else {
	            return isLower === true ? 'du' : 'DU';
	        }
	    },
	    calendar : {
	        sameDay : '[ma] LT[-kor]',
	        nextDay : '[holnap] LT[-kor]',
	        nextWeek : function () {
	            return week.call(this, true);
	        },
	        lastDay : '[tegnap] LT[-kor]',
	        lastWeek : function () {
	            return week.call(this, false);
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s múlva',
	        past : '%s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return hu;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/hu.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/hy-am.js **/
jupyter.define('moment@2.18.1/locale/hy-am.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Armenian [hy-am]
	//! author : Armendarabyan : https://github.com/armendarabyan
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var hyAm = moment.defineLocale('hy-am', {
	    months : {
	        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),
	        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')
	    },
	    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),
	    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),
	    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
	    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY թ.',
	        LLL : 'D MMMM YYYY թ., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'
	    },
	    calendar : {
	        sameDay: '[այսօր] LT',
	        nextDay: '[վաղը] LT',
	        lastDay: '[երեկ] LT',
	        nextWeek: function () {
	            return 'dddd [օրը ժամը] LT';
	        },
	        lastWeek: function () {
	            return '[անցած] dddd [օրը ժամը] LT';
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s հետո',
	        past : '%s առաջ',
	        s : 'մի քանի վայրկյան',
	        m : 'րոպե',
	        mm : '%d րոպե',
	        h : 'ժամ',
	        hh : '%d ժամ',
	        d : 'օր',
	        dd : '%d օր',
	        M : 'ամիս',
	        MM : '%d ամիս',
	        y : 'տարի',
	        yy : '%d տարի'
	    },
	    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,
	    isPM: function (input) {
	        return /^(ցերեկվա|երեկոյան)$/.test(input);
	    },
	    meridiem : function (hour) {
	        if (hour < 4) {
	            return 'գիշերվա';
	        } else if (hour < 12) {
	            return 'առավոտվա';
	        } else if (hour < 17) {
	            return 'ցերեկվա';
	        } else {
	            return 'երեկոյան';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'DDD':
	            case 'w':
	            case 'W':
	            case 'DDDo':
	                if (number === 1) {
	                    return number + '-ին';
	                }
	                return number + '-րդ';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return hyAm;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/hy-am.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/id.js **/
jupyter.define('moment@2.18.1/locale/id.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Indonesian [id]
	//! author : Mohammad Satrio Utomo : https://github.com/tyok
	//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var id = moment.defineLocale('id', {
	    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),
	    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),
	    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|siang|sore|malam/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'siang') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'sore' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'siang';
	        } else if (hours < 19) {
	            return 'sore';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Besok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kemarin pukul] LT',
	        lastWeek : 'dddd [lalu pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lalu',
	        s : 'beberapa detik',
	        m : 'semenit',
	        mm : '%d menit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return id;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/id.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/is.js **/
jupyter.define('moment@2.18.1/locale/is.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Icelandic [is]
	//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(n) {
	    if (n % 100 === 11) {
	        return true;
	    } else if (n % 10 === 1) {
	        return false;
	    }
	    return true;
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':
	            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';
	        case 'm':
	            return withoutSuffix ? 'mínúta' : 'mínútu';
	        case 'mm':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');
	            } else if (withoutSuffix) {
	                return result + 'mínúta';
	            }
	            return result + 'mínútu';
	        case 'hh':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');
	            }
	            return result + 'klukkustund';
	        case 'd':
	            if (withoutSuffix) {
	                return 'dagur';
	            }
	            return isFuture ? 'dag' : 'degi';
	        case 'dd':
	            if (plural(number)) {
	                if (withoutSuffix) {
	                    return result + 'dagar';
	                }
	                return result + (isFuture ? 'daga' : 'dögum');
	            } else if (withoutSuffix) {
	                return result + 'dagur';
	            }
	            return result + (isFuture ? 'dag' : 'degi');
	        case 'M':
	            if (withoutSuffix) {
	                return 'mánuður';
	            }
	            return isFuture ? 'mánuð' : 'mánuði';
	        case 'MM':
	            if (plural(number)) {
	                if (withoutSuffix) {
	                    return result + 'mánuðir';
	                }
	                return result + (isFuture ? 'mánuði' : 'mánuðum');
	            } else if (withoutSuffix) {
	                return result + 'mánuður';
	            }
	            return result + (isFuture ? 'mánuð' : 'mánuði');
	        case 'y':
	            return withoutSuffix || isFuture ? 'ár' : 'ári';
	        case 'yy':
	            if (plural(number)) {
	                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
	            }
	            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
	    }
	}
	
	var is = moment.defineLocale('is', {
	    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),
	    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),
	    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),
	    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] H:mm',
	        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
	    },
	    calendar : {
	        sameDay : '[í dag kl.] LT',
	        nextDay : '[á morgun kl.] LT',
	        nextWeek : 'dddd [kl.] LT',
	        lastDay : '[í gær kl.] LT',
	        lastWeek : '[síðasta] dddd [kl.] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'eftir %s',
	        past : 'fyrir %s síðan',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : 'klukkustund',
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return is;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/is.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/it.js **/
jupyter.define('moment@2.18.1/locale/it.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Italian [it]
	//! author : Lorenzo : https://github.com/aliem
	//! author: Mattia Larentis: https://github.com/nostalgiaz
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var it = moment.defineLocale('it', {
	    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),
	    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
	    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),
	    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
	    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Oggi alle] LT',
	        nextDay: '[Domani alle] LT',
	        nextWeek: 'dddd [alle] LT',
	        lastDay: '[Ieri alle] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[la scorsa] dddd [alle] LT';
	                default:
	                    return '[lo scorso] dddd [alle] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : function (s) {
	            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;
	        },
	        past : '%s fa',
	        s : 'alcuni secondi',
	        m : 'un minuto',
	        mm : '%d minuti',
	        h : 'un\'ora',
	        hh : '%d ore',
	        d : 'un giorno',
	        dd : '%d giorni',
	        M : 'un mese',
	        MM : '%d mesi',
	        y : 'un anno',
	        yy : '%d anni'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}º/,
	    ordinal: '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return it;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/it.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ja.js **/
jupyter.define('moment@2.18.1/locale/ja.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Japanese [ja]
	//! author : LI Long : https://github.com/baryon
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ja = moment.defineLocale('ja', {
	    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
	    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),
	    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY/MM/DD',
	        LL : 'YYYY年M月D日',
	        LLL : 'YYYY年M月D日 HH:mm',
	        LLLL : 'YYYY年M月D日 HH:mm dddd',
	        l : 'YYYY/MM/DD',
	        ll : 'YYYY年M月D日',
	        lll : 'YYYY年M月D日 HH:mm',
	        llll : 'YYYY年M月D日 HH:mm dddd'
	    },
	    meridiemParse: /午前|午後/i,
	    isPM : function (input) {
	        return input === '午後';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return '午前';
	        } else {
	            return '午後';
	        }
	    },
	    calendar : {
	        sameDay : '[今日] LT',
	        nextDay : '[明日] LT',
	        nextWeek : '[来週]dddd LT',
	        lastDay : '[昨日] LT',
	        lastWeek : '[前週]dddd LT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}日/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd':
	            case 'D':
	            case 'DDD':
	                return number + '日';
	            default:
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s後',
	        past : '%s前',
	        s : '数秒',
	        m : '1分',
	        mm : '%d分',
	        h : '1時間',
	        hh : '%d時間',
	        d : '1日',
	        dd : '%d日',
	        M : '1ヶ月',
	        MM : '%dヶ月',
	        y : '1年',
	        yy : '%d年'
	    }
	});
	
	return ja;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ja.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/jv.js **/
jupyter.define('moment@2.18.1/locale/jv.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Javanese [jv]
	//! author : Rony Lantip : https://github.com/lantip
	//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var jv = moment.defineLocale('jv', {
	    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),
	    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),
	    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),
	    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),
	    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /enjing|siyang|sonten|ndalu/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'enjing') {
	            return hour;
	        } else if (meridiem === 'siyang') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'enjing';
	        } else if (hours < 15) {
	            return 'siyang';
	        } else if (hours < 19) {
	            return 'sonten';
	        } else {
	            return 'ndalu';
	        }
	    },
	    calendar : {
	        sameDay : '[Dinten puniko pukul] LT',
	        nextDay : '[Mbenjang pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kala wingi pukul] LT',
	        lastWeek : 'dddd [kepengker pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'wonten ing %s',
	        past : '%s ingkang kepengker',
	        s : 'sawetawis detik',
	        m : 'setunggal menit',
	        mm : '%d menit',
	        h : 'setunggal jam',
	        hh : '%d jam',
	        d : 'sedinten',
	        dd : '%d dinten',
	        M : 'sewulan',
	        MM : '%d wulan',
	        y : 'setaun',
	        yy : '%d taun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return jv;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/jv.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ka.js **/
jupyter.define('moment@2.18.1/locale/ka.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Georgian [ka]
	//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ka = moment.defineLocale('ka', {
	    months : {
	        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
	        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')
	    },
	    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),
	    weekdays : {
	        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),
	        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),
	        isFormat: /(წინა|შემდეგ)/
	    },
	    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),
	    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[დღეს] LT[-ზე]',
	        nextDay : '[ხვალ] LT[-ზე]',
	        lastDay : '[გუშინ] LT[-ზე]',
	        nextWeek : '[შემდეგ] dddd LT[-ზე]',
	        lastWeek : '[წინა] dddd LT-ზე',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : function (s) {
	            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?
	                s.replace(/ი$/, 'ში') :
	                s + 'ში';
	        },
	        past : function (s) {
	            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {
	                return s.replace(/(ი|ე)$/, 'ის უკან');
	            }
	            if ((/წელი/).test(s)) {
	                return s.replace(/წელი$/, 'წლის უკან');
	            }
	        },
	        s : 'რამდენიმე წამი',
	        m : 'წუთი',
	        mm : '%d წუთი',
	        h : 'საათი',
	        hh : '%d საათი',
	        d : 'დღე',
	        dd : '%d დღე',
	        M : 'თვე',
	        MM : '%d თვე',
	        y : 'წელი',
	        yy : '%d წელი'
	    },
	    dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,
	    ordinal : function (number) {
	        if (number === 0) {
	            return number;
	        }
	        if (number === 1) {
	            return number + '-ლი';
	        }
	        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {
	            return 'მე-' + number;
	        }
	        return number + '-ე';
	    },
	    week : {
	        dow : 1,
	        doy : 7
	    }
	});
	
	return ka;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ka.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/kk.js **/
jupyter.define('moment@2.18.1/locale/kk.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Kazakh [kk]
	//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    0: '-ші',
	    1: '-ші',
	    2: '-ші',
	    3: '-ші',
	    4: '-ші',
	    5: '-ші',
	    6: '-шы',
	    7: '-ші',
	    8: '-ші',
	    9: '-шы',
	    10: '-шы',
	    20: '-шы',
	    30: '-шы',
	    40: '-шы',
	    50: '-ші',
	    60: '-шы',
	    70: '-ші',
	    80: '-ші',
	    90: '-шы',
	    100: '-ші'
	};
	
	var kk = moment.defineLocale('kk', {
	    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),
	    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),
	    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),
	    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),
	    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бүгін сағат] LT',
	        nextDay : '[Ертең сағат] LT',
	        nextWeek : 'dddd [сағат] LT',
	        lastDay : '[Кеше сағат] LT',
	        lastWeek : '[Өткен аптаның] dddd [сағат] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ішінде',
	        past : '%s бұрын',
	        s : 'бірнеше секунд',
	        m : 'бір минут',
	        mm : '%d минут',
	        h : 'бір сағат',
	        hh : '%d сағат',
	        d : 'бір күн',
	        dd : '%d күн',
	        M : 'бір ай',
	        MM : '%d ай',
	        y : 'бір жыл',
	        yy : '%d жыл'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/,
	    ordinal : function (number) {
	        var a = number % 10,
	            b = number >= 100 ? 100 : null;
	        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return kk;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/kk.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/km.js **/
jupyter.define('moment@2.18.1/locale/km.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Cambodian [km]
	//! author : Kruy Vanna : https://github.com/kruyvanna
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var km = moment.defineLocale('km', {
	    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
	    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),
	    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',
	        nextDay: '[ស្អែក ម៉ោង] LT',
	        nextWeek: 'dddd [ម៉ោង] LT',
	        lastDay: '[ម្សិលមិញ ម៉ោង] LT',
	        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: '%sទៀត',
	        past: '%sមុន',
	        s: 'ប៉ុន្មានវិនាទី',
	        m: 'មួយនាទី',
	        mm: '%d នាទី',
	        h: 'មួយម៉ោង',
	        hh: '%d ម៉ោង',
	        d: 'មួយថ្ងៃ',
	        dd: '%d ថ្ងៃ',
	        M: 'មួយខែ',
	        MM: '%d ខែ',
	        y: 'មួយឆ្នាំ',
	        yy: '%d ឆ្នាំ'
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return km;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/km.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/kn.js **/
jupyter.define('moment@2.18.1/locale/kn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Kannada [kn]
	//! author : Rajeev Naik : https://github.com/rajeevnaikte
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '೧',
	    '2': '೨',
	    '3': '೩',
	    '4': '೪',
	    '5': '೫',
	    '6': '೬',
	    '7': '೭',
	    '8': '೮',
	    '9': '೯',
	    '0': '೦'
	};
	var numberMap = {
	    '೧': '1',
	    '೨': '2',
	    '೩': '3',
	    '೪': '4',
	    '೫': '5',
	    '೬': '6',
	    '೭': '7',
	    '೮': '8',
	    '೯': '9',
	    '೦': '0'
	};
	
	var kn = moment.defineLocale('kn', {
	    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),
	    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),
	    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),
	    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[ಇಂದು] LT',
	        nextDay : '[ನಾಳೆ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ನಿನ್ನೆ] LT',
	        lastWeek : '[ಕೊನೆಯ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ನಂತರ',
	        past : '%s ಹಿಂದೆ',
	        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',
	        m : 'ಒಂದು ನಿಮಿಷ',
	        mm : '%d ನಿಮಿಷ',
	        h : 'ಒಂದು ಗಂಟೆ',
	        hh : '%d ಗಂಟೆ',
	        d : 'ಒಂದು ದಿನ',
	        dd : '%d ದಿನ',
	        M : 'ಒಂದು ತಿಂಗಳು',
	        MM : '%d ತಿಂಗಳು',
	        y : 'ಒಂದು ವರ್ಷ',
	        yy : '%d ವರ್ಷ'
	    },
	    preparse: function (string) {
	        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ರಾತ್ರಿ') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {
	            return hour;
	        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'ಸಂಜೆ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ರಾತ್ರಿ';
	        } else if (hour < 10) {
	            return 'ಬೆಳಿಗ್ಗೆ';
	        } else if (hour < 17) {
	            return 'ಮಧ್ಯಾಹ್ನ';
	        } else if (hour < 20) {
	            return 'ಸಂಜೆ';
	        } else {
	            return 'ರಾತ್ರಿ';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/,
	    ordinal : function (number) {
	        return number + 'ನೇ';
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return kn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/kn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ko.js **/
jupyter.define('moment@2.18.1/locale/ko.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Korean [ko]
	//! author : Kyungwook, Park : https://github.com/kyungw00k
	//! author : Jeeeyul Lee <jeeeyul@gmail.com>
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ko = moment.defineLocale('ko', {
	    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
	    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
	    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),
	    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),
	    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'YYYY.MM.DD',
	        LL : 'YYYY년 MMMM D일',
	        LLL : 'YYYY년 MMMM D일 A h:mm',
	        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',
	        l : 'YYYY.MM.DD',
	        ll : 'YYYY년 MMMM D일',
	        lll : 'YYYY년 MMMM D일 A h:mm',
	        llll : 'YYYY년 MMMM D일 dddd A h:mm'
	    },
	    calendar : {
	        sameDay : '오늘 LT',
	        nextDay : '내일 LT',
	        nextWeek : 'dddd LT',
	        lastDay : '어제 LT',
	        lastWeek : '지난주 dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s 후',
	        past : '%s 전',
	        s : '몇 초',
	        ss : '%d초',
	        m : '1분',
	        mm : '%d분',
	        h : '한 시간',
	        hh : '%d시간',
	        d : '하루',
	        dd : '%d일',
	        M : '한 달',
	        MM : '%d달',
	        y : '일 년',
	        yy : '%d년'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}일/,
	    ordinal : '%d일',
	    meridiemParse : /오전|오후/,
	    isPM : function (token) {
	        return token === '오후';
	    },
	    meridiem : function (hour, minute, isUpper) {
	        return hour < 12 ? '오전' : '오후';
	    }
	});
	
	return ko;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ko.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ky.js **/
jupyter.define('moment@2.18.1/locale/ky.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Kyrgyz [ky]
	//! author : Chyngyz Arystan uulu : https://github.com/chyngyz
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var suffixes = {
	    0: '-чү',
	    1: '-чи',
	    2: '-чи',
	    3: '-чү',
	    4: '-чү',
	    5: '-чи',
	    6: '-чы',
	    7: '-чи',
	    8: '-чи',
	    9: '-чу',
	    10: '-чу',
	    20: '-чы',
	    30: '-чу',
	    40: '-чы',
	    50: '-чү',
	    60: '-чы',
	    70: '-чи',
	    80: '-чи',
	    90: '-чу',
	    100: '-чү'
	};
	
	var ky = moment.defineLocale('ky', {
	    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
	    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),
	    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),
	    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),
	    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бүгүн саат] LT',
	        nextDay : '[Эртең саат] LT',
	        nextWeek : 'dddd [саат] LT',
	        lastDay : '[Кече саат] LT',
	        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ичинде',
	        past : '%s мурун',
	        s : 'бирнече секунд',
	        m : 'бир мүнөт',
	        mm : '%d мүнөт',
	        h : 'бир саат',
	        hh : '%d саат',
	        d : 'бир күн',
	        dd : '%d күн',
	        M : 'бир ай',
	        MM : '%d ай',
	        y : 'бир жыл',
	        yy : '%d жыл'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/,
	    ordinal : function (number) {
	        var a = number % 10,
	            b = number >= 100 ? 100 : null;
	        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ky;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ky.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/lb.js **/
jupyter.define('moment@2.18.1/locale/lb.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Luxembourgish [lb]
	//! author : mweimerskirch : https://github.com/mweimerskirch
	//! author : David Raison : https://github.com/kwisatz
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        'm': ['eng Minutt', 'enger Minutt'],
	        'h': ['eng Stonn', 'enger Stonn'],
	        'd': ['een Dag', 'engem Dag'],
	        'M': ['ee Mount', 'engem Mount'],
	        'y': ['ee Joer', 'engem Joer']
	    };
	    return withoutSuffix ? format[key][0] : format[key][1];
	}
	function processFutureTime(string) {
	    var number = string.substr(0, string.indexOf(' '));
	    if (eifelerRegelAppliesToNumber(number)) {
	        return 'a ' + string;
	    }
	    return 'an ' + string;
	}
	function processPastTime(string) {
	    var number = string.substr(0, string.indexOf(' '));
	    if (eifelerRegelAppliesToNumber(number)) {
	        return 'viru ' + string;
	    }
	    return 'virun ' + string;
	}
	/**
	 * Returns true if the word before the given number loses the '-n' ending.
	 * e.g. 'an 10 Deeg' but 'a 5 Deeg'
	 *
	 * @param number {integer}
	 * @returns {boolean}
	 */
	function eifelerRegelAppliesToNumber(number) {
	    number = parseInt(number, 10);
	    if (isNaN(number)) {
	        return false;
	    }
	    if (number < 0) {
	        // Negative Number --> always true
	        return true;
	    } else if (number < 10) {
	        // Only 1 digit
	        if (4 <= number && number <= 7) {
	            return true;
	        }
	        return false;
	    } else if (number < 100) {
	        // 2 digits
	        var lastDigit = number % 10, firstDigit = number / 10;
	        if (lastDigit === 0) {
	            return eifelerRegelAppliesToNumber(firstDigit);
	        }
	        return eifelerRegelAppliesToNumber(lastDigit);
	    } else if (number < 10000) {
	        // 3 or 4 digits --> recursively check first digit
	        while (number >= 10) {
	            number = number / 10;
	        }
	        return eifelerRegelAppliesToNumber(number);
	    } else {
	        // Anything larger than 4 digits: recursively check first n-3 digits
	        number = number / 1000;
	        return eifelerRegelAppliesToNumber(number);
	    }
	}
	
	var lb = moment.defineLocale('lb', {
	    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
	    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
	    monthsParseExact : true,
	    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),
	    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),
	    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm [Auer]',
	        LTS: 'H:mm:ss [Auer]',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm [Auer]',
	        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
	    },
	    calendar: {
	        sameDay: '[Haut um] LT',
	        sameElse: 'L',
	        nextDay: '[Muer um] LT',
	        nextWeek: 'dddd [um] LT',
	        lastDay: '[Gëschter um] LT',
	        lastWeek: function () {
	            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule
	            switch (this.day()) {
	                case 2:
	                case 4:
	                    return '[Leschten] dddd [um] LT';
	                default:
	                    return '[Leschte] dddd [um] LT';
	            }
	        }
	    },
	    relativeTime : {
	        future : processFutureTime,
	        past : processPastTime,
	        s : 'e puer Sekonnen',
	        m : processRelativeTime,
	        mm : '%d Minutten',
	        h : processRelativeTime,
	        hh : '%d Stonnen',
	        d : processRelativeTime,
	        dd : '%d Deeg',
	        M : processRelativeTime,
	        MM : '%d Méint',
	        y : processRelativeTime,
	        yy : '%d Joer'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal: '%d.',
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lb;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/lb.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/lo.js **/
jupyter.define('moment@2.18.1/locale/lo.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Lao [lo]
	//! author : Ryan Hart : https://github.com/ryanhart2
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var lo = moment.defineLocale('lo', {
	    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),
	    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),
	    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
	    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
	    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,
	    isPM: function (input) {
	        return input === 'ຕອນແລງ';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ຕອນເຊົ້າ';
	        } else {
	            return 'ຕອນແລງ';
	        }
	    },
	    calendar : {
	        sameDay : '[ມື້ນີ້ເວລາ] LT',
	        nextDay : '[ມື້ອື່ນເວລາ] LT',
	        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',
	        lastDay : '[ມື້ວານນີ້ເວລາ] LT',
	        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ອີກ %s',
	        past : '%sຜ່ານມາ',
	        s : 'ບໍ່ເທົ່າໃດວິນາທີ',
	        m : '1 ນາທີ',
	        mm : '%d ນາທີ',
	        h : '1 ຊົ່ວໂມງ',
	        hh : '%d ຊົ່ວໂມງ',
	        d : '1 ມື້',
	        dd : '%d ມື້',
	        M : '1 ເດືອນ',
	        MM : '%d ເດືອນ',
	        y : '1 ປີ',
	        yy : '%d ປີ'
	    },
	    dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/,
	    ordinal : function (number) {
	        return 'ທີ່' + number;
	    }
	});
	
	return lo;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/lo.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/lt.js **/
jupyter.define('moment@2.18.1/locale/lt.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Lithuanian [lt]
	//! author : Mindaugas Mozūras : https://github.com/mmozuras
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var units = {
	    'm' : 'minutė_minutės_minutę',
	    'mm': 'minutės_minučių_minutes',
	    'h' : 'valanda_valandos_valandą',
	    'hh': 'valandos_valandų_valandas',
	    'd' : 'diena_dienos_dieną',
	    'dd': 'dienos_dienų_dienas',
	    'M' : 'mėnuo_mėnesio_mėnesį',
	    'MM': 'mėnesiai_mėnesių_mėnesius',
	    'y' : 'metai_metų_metus',
	    'yy': 'metai_metų_metus'
	};
	function translateSeconds(number, withoutSuffix, key, isFuture) {
	    if (withoutSuffix) {
	        return 'kelios sekundės';
	    } else {
	        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
	    }
	}
	function translateSingular(number, withoutSuffix, key, isFuture) {
	    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
	}
	function special(number) {
	    return number % 10 === 0 || (number > 10 && number < 20);
	}
	function forms(key) {
	    return units[key].split('_');
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    if (number === 1) {
	        return result + translateSingular(number, withoutSuffix, key[0], isFuture);
	    } else if (withoutSuffix) {
	        return result + (special(number) ? forms(key)[1] : forms(key)[0]);
	    } else {
	        if (isFuture) {
	            return result + forms(key)[1];
	        } else {
	            return result + (special(number) ? forms(key)[1] : forms(key)[2]);
	        }
	    }
	}
	var lt = moment.defineLocale('lt', {
	    months : {
	        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
	        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
	        isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/
	    },
	    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
	    weekdays : {
	        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),
	        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),
	        isFormat: /dddd HH:mm/
	    },
	    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
	    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'YYYY [m.] MMMM D [d.]',
	        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
	        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
	        l : 'YYYY-MM-DD',
	        ll : 'YYYY [m.] MMMM D [d.]',
	        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
	        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
	    },
	    calendar : {
	        sameDay : '[Šiandien] LT',
	        nextDay : '[Rytoj] LT',
	        nextWeek : 'dddd LT',
	        lastDay : '[Vakar] LT',
	        lastWeek : '[Praėjusį] dddd LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'po %s',
	        past : 'prieš %s',
	        s : translateSeconds,
	        m : translateSingular,
	        mm : translate,
	        h : translateSingular,
	        hh : translate,
	        d : translateSingular,
	        dd : translate,
	        M : translateSingular,
	        MM : translate,
	        y : translateSingular,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-oji/,
	    ordinal : function (number) {
	        return number + '-oji';
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lt;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/lt.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/lv.js **/
jupyter.define('moment@2.18.1/locale/lv.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Latvian [lv]
	//! author : Kristaps Karlsons : https://github.com/skakri
	//! author : Jānis Elmeris : https://github.com/JanisE
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var units = {
	    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
	    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),
	    'h': 'stundas_stundām_stunda_stundas'.split('_'),
	    'hh': 'stundas_stundām_stunda_stundas'.split('_'),
	    'd': 'dienas_dienām_diena_dienas'.split('_'),
	    'dd': 'dienas_dienām_diena_dienas'.split('_'),
	    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
	    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
	    'y': 'gada_gadiem_gads_gadi'.split('_'),
	    'yy': 'gada_gadiem_gads_gadi'.split('_')
	};
	/**
	 * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.
	 */
	function format(forms, number, withoutSuffix) {
	    if (withoutSuffix) {
	        // E.g. "21 minūte", "3 minūtes".
	        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];
	    } else {
	        // E.g. "21 minūtes" as in "pēc 21 minūtes".
	        // E.g. "3 minūtēm" as in "pēc 3 minūtēm".
	        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];
	    }
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    return number + ' ' + format(units[key], number, withoutSuffix);
	}
	function relativeTimeWithSingular(number, withoutSuffix, key) {
	    return format(units[key], number, withoutSuffix);
	}
	function relativeSeconds(number, withoutSuffix) {
	    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';
	}
	
	var lv = moment.defineLocale('lv', {
	    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),
	    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),
	    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY.',
	        LL : 'YYYY. [gada] D. MMMM',
	        LLL : 'YYYY. [gada] D. MMMM, HH:mm',
	        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
	    },
	    calendar : {
	        sameDay : '[Šodien pulksten] LT',
	        nextDay : '[Rīt pulksten] LT',
	        nextWeek : 'dddd [pulksten] LT',
	        lastDay : '[Vakar pulksten] LT',
	        lastWeek : '[Pagājušā] dddd [pulksten] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'pēc %s',
	        past : 'pirms %s',
	        s : relativeSeconds,
	        m : relativeTimeWithSingular,
	        mm : relativeTimeWithPlural,
	        h : relativeTimeWithSingular,
	        hh : relativeTimeWithPlural,
	        d : relativeTimeWithSingular,
	        dd : relativeTimeWithPlural,
	        M : relativeTimeWithSingular,
	        MM : relativeTimeWithPlural,
	        y : relativeTimeWithSingular,
	        yy : relativeTimeWithPlural
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return lv;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/lv.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/me.js **/
jupyter.define('moment@2.18.1/locale/me.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Montenegrin [me]
	//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['jedan minut', 'jednog minuta'],
	        mm: ['minut', 'minuta', 'minuta'],
	        h: ['jedan sat', 'jednog sata'],
	        hh: ['sat', 'sata', 'sati'],
	        dd: ['dan', 'dana', 'dana'],
	        MM: ['mjesec', 'mjeseca', 'mjeseci'],
	        yy: ['godina', 'godine', 'godina']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var me = moment.defineLocale('me', {
	    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact : true,
	    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
	    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[danas u] LT',
	        nextDay: '[sjutra u] LT',
	
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedjelju] [u] LT';
	                case 3:
	                    return '[u] [srijedu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[juče u] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[prošle] [nedjelje] [u] LT',
	                '[prošlog] [ponedjeljka] [u] LT',
	                '[prošlog] [utorka] [u] LT',
	                '[prošle] [srijede] [u] LT',
	                '[prošlog] [četvrtka] [u] LT',
	                '[prošlog] [petka] [u] LT',
	                '[prošle] [subote] [u] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'prije %s',
	        s      : 'nekoliko sekundi',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'dan',
	        dd     : translator.translate,
	        M      : 'mjesec',
	        MM     : translator.translate,
	        y      : 'godinu',
	        yy     : translator.translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return me;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/me.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/mi.js **/
jupyter.define('moment@2.18.1/locale/mi.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Maori [mi]
	//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var mi = moment.defineLocale('mi', {
	    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),
	    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),
	    monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
	    monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,
	    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),
	    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
	    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY [i] HH:mm',
	        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'
	    },
	    calendar: {
	        sameDay: '[i teie mahana, i] LT',
	        nextDay: '[apopo i] LT',
	        nextWeek: 'dddd [i] LT',
	        lastDay: '[inanahi i] LT',
	        lastWeek: 'dddd [whakamutunga i] LT',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'i roto i %s',
	        past: '%s i mua',
	        s: 'te hēkona ruarua',
	        m: 'he meneti',
	        mm: '%d meneti',
	        h: 'te haora',
	        hh: '%d haora',
	        d: 'he ra',
	        dd: '%d ra',
	        M: 'he marama',
	        MM: '%d marama',
	        y: 'he tau',
	        yy: '%d tau'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}º/,
	    ordinal: '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return mi;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/mi.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/mk.js **/
jupyter.define('moment@2.18.1/locale/mk.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Macedonian [mk]
	//! author : Borislav Mickov : https://github.com/B0k0
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var mk = moment.defineLocale('mk', {
	    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),
	    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),
	    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),
	    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),
	    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'D.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay : '[Денес во] LT',
	        nextDay : '[Утре во] LT',
	        nextWeek : '[Во] dddd [во] LT',
	        lastDay : '[Вчера во] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 6:
	                    return '[Изминатата] dddd [во] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[Изминатиот] dddd [во] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'после %s',
	        past : 'пред %s',
	        s : 'неколку секунди',
	        m : 'минута',
	        mm : '%d минути',
	        h : 'час',
	        hh : '%d часа',
	        d : 'ден',
	        dd : '%d дена',
	        M : 'месец',
	        MM : '%d месеци',
	        y : 'година',
	        yy : '%d години'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
	    ordinal : function (number) {
	        var lastDigit = number % 10,
	            last2Digits = number % 100;
	        if (number === 0) {
	            return number + '-ев';
	        } else if (last2Digits === 0) {
	            return number + '-ен';
	        } else if (last2Digits > 10 && last2Digits < 20) {
	            return number + '-ти';
	        } else if (lastDigit === 1) {
	            return number + '-ви';
	        } else if (lastDigit === 2) {
	            return number + '-ри';
	        } else if (lastDigit === 7 || lastDigit === 8) {
	            return number + '-ми';
	        } else {
	            return number + '-ти';
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return mk;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/mk.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ml.js **/
jupyter.define('moment@2.18.1/locale/ml.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Malayalam [ml]
	//! author : Floyd Pink : https://github.com/floydpink
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ml = moment.defineLocale('ml', {
	    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),
	    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),
	    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),
	    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm -നു',
	        LTS : 'A h:mm:ss -നു',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm -നു',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
	    },
	    calendar : {
	        sameDay : '[ഇന്ന്] LT',
	        nextDay : '[നാളെ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ഇന്നലെ] LT',
	        lastWeek : '[കഴിഞ്ഞ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s കഴിഞ്ഞ്',
	        past : '%s മുൻപ്',
	        s : 'അൽപ നിമിഷങ്ങൾ',
	        m : 'ഒരു മിനിറ്റ്',
	        mm : '%d മിനിറ്റ്',
	        h : 'ഒരു മണിക്കൂർ',
	        hh : '%d മണിക്കൂർ',
	        d : 'ഒരു ദിവസം',
	        dd : '%d ദിവസം',
	        M : 'ഒരു മാസം',
	        MM : '%d മാസം',
	        y : 'ഒരു വർഷം',
	        yy : '%d വർഷം'
	    },
	    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if ((meridiem === 'രാത്രി' && hour >= 4) ||
	                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||
	                meridiem === 'വൈകുന്നേരം') {
	            return hour + 12;
	        } else {
	            return hour;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'രാത്രി';
	        } else if (hour < 12) {
	            return 'രാവിലെ';
	        } else if (hour < 17) {
	            return 'ഉച്ച കഴിഞ്ഞ്';
	        } else if (hour < 20) {
	            return 'വൈകുന്നേരം';
	        } else {
	            return 'രാത്രി';
	        }
	    }
	});
	
	return ml;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ml.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/mr.js **/
jupyter.define('moment@2.18.1/locale/mr.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Marathi [mr]
	//! author : Harshad Kale : https://github.com/kalehv
	//! author : Vivek Athalye : https://github.com/vnathalye
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	function relativeTimeMr(number, withoutSuffix, string, isFuture)
	{
	    var output = '';
	    if (withoutSuffix) {
	        switch (string) {
	            case 's': output = 'काही सेकंद'; break;
	            case 'm': output = 'एक मिनिट'; break;
	            case 'mm': output = '%d मिनिटे'; break;
	            case 'h': output = 'एक तास'; break;
	            case 'hh': output = '%d तास'; break;
	            case 'd': output = 'एक दिवस'; break;
	            case 'dd': output = '%d दिवस'; break;
	            case 'M': output = 'एक महिना'; break;
	            case 'MM': output = '%d महिने'; break;
	            case 'y': output = 'एक वर्ष'; break;
	            case 'yy': output = '%d वर्षे'; break;
	        }
	    }
	    else {
	        switch (string) {
	            case 's': output = 'काही सेकंदां'; break;
	            case 'm': output = 'एका मिनिटा'; break;
	            case 'mm': output = '%d मिनिटां'; break;
	            case 'h': output = 'एका तासा'; break;
	            case 'hh': output = '%d तासां'; break;
	            case 'd': output = 'एका दिवसा'; break;
	            case 'dd': output = '%d दिवसां'; break;
	            case 'M': output = 'एका महिन्या'; break;
	            case 'MM': output = '%d महिन्यां'; break;
	            case 'y': output = 'एका वर्षा'; break;
	            case 'yy': output = '%d वर्षां'; break;
	        }
	    }
	    return output.replace(/%d/i, number);
	}
	
	var mr = moment.defineLocale('mr', {
	    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),
	    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
	    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),
	    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm वाजता',
	        LTS : 'A h:mm:ss वाजता',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm वाजता',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[उद्या] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[काल] LT',
	        lastWeek: '[मागील] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future: '%sमध्ये',
	        past: '%sपूर्वी',
	        s: relativeTimeMr,
	        m: relativeTimeMr,
	        mm: relativeTimeMr,
	        h: relativeTimeMr,
	        hh: relativeTimeMr,
	        d: relativeTimeMr,
	        dd: relativeTimeMr,
	        M: relativeTimeMr,
	        MM: relativeTimeMr,
	        y: relativeTimeMr,
	        yy: relativeTimeMr
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'रात्री') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'सकाळी') {
	            return hour;
	        } else if (meridiem === 'दुपारी') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'सायंकाळी') {
	            return hour + 12;
	        }
	    },
	    meridiem: function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'रात्री';
	        } else if (hour < 10) {
	            return 'सकाळी';
	        } else if (hour < 17) {
	            return 'दुपारी';
	        } else if (hour < 20) {
	            return 'सायंकाळी';
	        } else {
	            return 'रात्री';
	        }
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return mr;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/mr.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ms.js **/
jupyter.define('moment@2.18.1/locale/ms.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Malay [ms]
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ms = moment.defineLocale('ms', {
	    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
	    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
	    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
	    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|tengahari|petang|malam/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'tengahari') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'petang' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'tengahari';
	        } else if (hours < 19) {
	            return 'petang';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Esok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kelmarin pukul] LT',
	        lastWeek : 'dddd [lepas pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lepas',
	        s : 'beberapa saat',
	        m : 'seminit',
	        mm : '%d minit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ms;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ms.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ms-my.js **/
jupyter.define('moment@2.18.1/locale/ms-my.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Malay [ms-my]
	//! note : DEPRECATED, the correct one is [ms]
	//! author : Weldan Jamili : https://github.com/weldan
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var msMy = moment.defineLocale('ms-my', {
	    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
	    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
	    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
	    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [pukul] HH.mm',
	        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
	    },
	    meridiemParse: /pagi|tengahari|petang|malam/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'pagi') {
	            return hour;
	        } else if (meridiem === 'tengahari') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'petang' || meridiem === 'malam') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'pagi';
	        } else if (hours < 15) {
	            return 'tengahari';
	        } else if (hours < 19) {
	            return 'petang';
	        } else {
	            return 'malam';
	        }
	    },
	    calendar : {
	        sameDay : '[Hari ini pukul] LT',
	        nextDay : '[Esok pukul] LT',
	        nextWeek : 'dddd [pukul] LT',
	        lastDay : '[Kelmarin pukul] LT',
	        lastWeek : 'dddd [lepas pukul] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'dalam %s',
	        past : '%s yang lepas',
	        s : 'beberapa saat',
	        m : 'seminit',
	        mm : '%d minit',
	        h : 'sejam',
	        hh : '%d jam',
	        d : 'sehari',
	        dd : '%d hari',
	        M : 'sebulan',
	        MM : '%d bulan',
	        y : 'setahun',
	        yy : '%d tahun'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return msMy;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ms-my.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/my.js **/
jupyter.define('moment@2.18.1/locale/my.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Burmese [my]
	//! author : Squar team, mysquar.com
	//! author : David Rossellat : https://github.com/gholadr
	//! author : Tin Aung Lin : https://github.com/thanyawzinmin
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '၁',
	    '2': '၂',
	    '3': '၃',
	    '4': '၄',
	    '5': '၅',
	    '6': '၆',
	    '7': '၇',
	    '8': '၈',
	    '9': '၉',
	    '0': '၀'
	};
	var numberMap = {
	    '၁': '1',
	    '၂': '2',
	    '၃': '3',
	    '၄': '4',
	    '၅': '5',
	    '၆': '6',
	    '၇': '7',
	    '၈': '8',
	    '၉': '9',
	    '၀': '0'
	};
	
	var my = moment.defineLocale('my', {
	    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),
	    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),
	    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),
	    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
	    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
	
	    longDateFormat: {
	        LT: 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L: 'DD/MM/YYYY',
	        LL: 'D MMMM YYYY',
	        LLL: 'D MMMM YYYY HH:mm',
	        LLLL: 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar: {
	        sameDay: '[ယနေ.] LT [မှာ]',
	        nextDay: '[မနက်ဖြန်] LT [မှာ]',
	        nextWeek: 'dddd LT [မှာ]',
	        lastDay: '[မနေ.က] LT [မှာ]',
	        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',
	        sameElse: 'L'
	    },
	    relativeTime: {
	        future: 'လာမည့် %s မှာ',
	        past: 'လွန်ခဲ့သော %s က',
	        s: 'စက္ကန်.အနည်းငယ်',
	        m: 'တစ်မိနစ်',
	        mm: '%d မိနစ်',
	        h: 'တစ်နာရီ',
	        hh: '%d နာရီ',
	        d: 'တစ်ရက်',
	        dd: '%d ရက်',
	        M: 'တစ်လ',
	        MM: '%d လ',
	        y: 'တစ်နှစ်',
	        yy: '%d နှစ်'
	    },
	    preparse: function (string) {
	        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    week: {
	        dow: 1, // Monday is the first day of the week.
	        doy: 4 // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return my;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/my.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/nb.js **/
jupyter.define('moment@2.18.1/locale/nb.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Norwegian Bokmål [nb]
	//! authors : Espen Hovlandsdal : https://github.com/rexxars
	//!           Sigurd Gartmann : https://github.com/sigurdga
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var nb = moment.defineLocale('nb', {
	    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
	    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),
	    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] HH:mm',
	        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[i dag kl.] LT',
	        nextDay: '[i morgen kl.] LT',
	        nextWeek: 'dddd [kl.] LT',
	        lastDay: '[i går kl.] LT',
	        lastWeek: '[forrige] dddd [kl.] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s siden',
	        s : 'noen sekunder',
	        m : 'ett minutt',
	        mm : '%d minutter',
	        h : 'en time',
	        hh : '%d timer',
	        d : 'en dag',
	        dd : '%d dager',
	        M : 'en måned',
	        MM : '%d måneder',
	        y : 'ett år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nb;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/nb.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ne.js **/
jupyter.define('moment@2.18.1/locale/ne.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Nepalese [ne]
	//! author : suvash : https://github.com/suvash
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '१',
	    '2': '२',
	    '3': '३',
	    '4': '४',
	    '5': '५',
	    '6': '६',
	    '7': '७',
	    '8': '८',
	    '9': '९',
	    '0': '०'
	};
	var numberMap = {
	    '१': '1',
	    '२': '2',
	    '३': '3',
	    '४': '4',
	    '५': '5',
	    '६': '6',
	    '७': '7',
	    '८': '8',
	    '९': '9',
	    '०': '0'
	};
	
	var ne = moment.defineLocale('ne', {
	    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),
	    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),
	    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),
	    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'Aको h:mm बजे',
	        LTS : 'Aको h:mm:ss बजे',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, Aको h:mm बजे',
	        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
	    },
	    preparse: function (string) {
	        return string.replace(/[१२३४५६७८९०]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'राति') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'बिहान') {
	            return hour;
	        } else if (meridiem === 'दिउँसो') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'साँझ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 3) {
	            return 'राति';
	        } else if (hour < 12) {
	            return 'बिहान';
	        } else if (hour < 16) {
	            return 'दिउँसो';
	        } else if (hour < 20) {
	            return 'साँझ';
	        } else {
	            return 'राति';
	        }
	    },
	    calendar : {
	        sameDay : '[आज] LT',
	        nextDay : '[भोलि] LT',
	        nextWeek : '[आउँदो] dddd[,] LT',
	        lastDay : '[हिजो] LT',
	        lastWeek : '[गएको] dddd[,] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%sमा',
	        past : '%s अगाडि',
	        s : 'केही क्षण',
	        m : 'एक मिनेट',
	        mm : '%d मिनेट',
	        h : 'एक घण्टा',
	        hh : '%d घण्टा',
	        d : 'एक दिन',
	        dd : '%d दिन',
	        M : 'एक महिना',
	        MM : '%d महिना',
	        y : 'एक बर्ष',
	        yy : '%d बर्ष'
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ne;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ne.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/nl.js **/
jupyter.define('moment@2.18.1/locale/nl.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Dutch [nl]
	//! author : Joris Röling : https://github.com/jorisroling
	//! author : Jacob Middag : https://github.com/middagj
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
	
	var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];
	var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
	
	var nl = moment.defineLocale('nl', {
	    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortWithDots;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	
	    monthsRegex: monthsRegex,
	    monthsShortRegex: monthsRegex,
	    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,
	    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
	
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
	    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
	    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD-MM-YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[vandaag om] LT',
	        nextDay: '[morgen om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[gisteren om] LT',
	        lastWeek: '[afgelopen] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'over %s',
	        past : '%s geleden',
	        s : 'een paar seconden',
	        m : 'één minuut',
	        mm : '%d minuten',
	        h : 'één uur',
	        hh : '%d uur',
	        d : 'één dag',
	        dd : '%d dagen',
	        M : 'één maand',
	        MM : '%d maanden',
	        y : 'één jaar',
	        yy : '%d jaar'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nl;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/nl.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/nl-be.js **/
jupyter.define('moment@2.18.1/locale/nl-be.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Dutch (Belgium) [nl-be]
	//! author : Joris Röling : https://github.com/jorisroling
	//! author : Jacob Middag : https://github.com/middagj
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');
	var monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');
	
	var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];
	var monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
	
	var nlBe = moment.defineLocale('nl-be', {
	    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),
	    monthsShort : function (m, format) {
	        if (!m) {
	            return monthsShortWithDots;
	        } else if (/-MMM-/.test(format)) {
	            return monthsShortWithoutDots[m.month()];
	        } else {
	            return monthsShortWithDots[m.month()];
	        }
	    },
	
	    monthsRegex: monthsRegex,
	    monthsShortRegex: monthsRegex,
	    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,
	    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
	
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
	    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),
	    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[vandaag om] LT',
	        nextDay: '[morgen om] LT',
	        nextWeek: 'dddd [om] LT',
	        lastDay: '[gisteren om] LT',
	        lastWeek: '[afgelopen] dddd [om] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'over %s',
	        past : '%s geleden',
	        s : 'een paar seconden',
	        m : 'één minuut',
	        mm : '%d minuten',
	        h : 'één uur',
	        hh : '%d uur',
	        d : 'één dag',
	        dd : '%d dagen',
	        M : 'één maand',
	        MM : '%d maanden',
	        y : 'één jaar',
	        yy : '%d jaar'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
	    ordinal : function (number) {
	        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nlBe;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/nl-be.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/nn.js **/
jupyter.define('moment@2.18.1/locale/nn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Nynorsk [nn]
	//! author : https://github.com/mechuwind
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var nn = moment.defineLocale('nn', {
	    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
	    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),
	    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),
	    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY [kl.] H:mm',
	        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[I dag klokka] LT',
	        nextDay: '[I morgon klokka] LT',
	        nextWeek: 'dddd [klokka] LT',
	        lastDay: '[I går klokka] LT',
	        lastWeek: '[Føregåande] dddd [klokka] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : '%s sidan',
	        s : 'nokre sekund',
	        m : 'eit minutt',
	        mm : '%d minutt',
	        h : 'ein time',
	        hh : '%d timar',
	        d : 'ein dag',
	        dd : '%d dagar',
	        M : 'ein månad',
	        MM : '%d månader',
	        y : 'eit år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return nn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/nn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/pa-in.js **/
jupyter.define('moment@2.18.1/locale/pa-in.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Punjabi (India) [pa-in]
	//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '੧',
	    '2': '੨',
	    '3': '੩',
	    '4': '੪',
	    '5': '੫',
	    '6': '੬',
	    '7': '੭',
	    '8': '੮',
	    '9': '੯',
	    '0': '੦'
	};
	var numberMap = {
	    '੧': '1',
	    '੨': '2',
	    '੩': '3',
	    '੪': '4',
	    '੫': '5',
	    '੬': '6',
	    '੭': '7',
	    '੮': '8',
	    '੯': '9',
	    '੦': '0'
	};
	
	var paIn = moment.defineLocale('pa-in', {
	    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.
	    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),
	    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),
	    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),
	    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
	    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm ਵਜੇ',
	        LTS : 'A h:mm:ss ਵਜੇ',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'
	    },
	    calendar : {
	        sameDay : '[ਅਜ] LT',
	        nextDay : '[ਕਲ] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[ਕਲ] LT',
	        lastWeek : '[ਪਿਛਲੇ] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s ਵਿੱਚ',
	        past : '%s ਪਿਛਲੇ',
	        s : 'ਕੁਝ ਸਕਿੰਟ',
	        m : 'ਇਕ ਮਿੰਟ',
	        mm : '%d ਮਿੰਟ',
	        h : 'ਇੱਕ ਘੰਟਾ',
	        hh : '%d ਘੰਟੇ',
	        d : 'ਇੱਕ ਦਿਨ',
	        dd : '%d ਦਿਨ',
	        M : 'ਇੱਕ ਮਹੀਨਾ',
	        MM : '%d ਮਹੀਨੇ',
	        y : 'ਇੱਕ ਸਾਲ',
	        yy : '%d ਸਾਲ'
	    },
	    preparse: function (string) {
	        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists
	    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.
	    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ਰਾਤ') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ਸਵੇਰ') {
	            return hour;
	        } else if (meridiem === 'ਦੁਪਹਿਰ') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'ਸ਼ਾਮ') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ਰਾਤ';
	        } else if (hour < 10) {
	            return 'ਸਵੇਰ';
	        } else if (hour < 17) {
	            return 'ਦੁਪਹਿਰ';
	        } else if (hour < 20) {
	            return 'ਸ਼ਾਮ';
	        } else {
	            return 'ਰਾਤ';
	        }
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return paIn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/pa-in.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/pl.js **/
jupyter.define('moment@2.18.1/locale/pl.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Polish [pl]
	//! author : Rafal Hirsz : https://github.com/evoL
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');
	var monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');
	function plural(n) {
	    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);
	}
	function translate(number, withoutSuffix, key) {
	    var result = number + ' ';
	    switch (key) {
	        case 'm':
	            return withoutSuffix ? 'minuta' : 'minutę';
	        case 'mm':
	            return result + (plural(number) ? 'minuty' : 'minut');
	        case 'h':
	            return withoutSuffix  ? 'godzina'  : 'godzinę';
	        case 'hh':
	            return result + (plural(number) ? 'godziny' : 'godzin');
	        case 'MM':
	            return result + (plural(number) ? 'miesiące' : 'miesięcy');
	        case 'yy':
	            return result + (plural(number) ? 'lata' : 'lat');
	    }
	}
	
	var pl = moment.defineLocale('pl', {
	    months : function (momentToFormat, format) {
	        if (!momentToFormat) {
	            return monthsNominative;
	        } else if (format === '') {
	            // Hack: if format empty we know this is used to generate
	            // RegExp by moment. Give then back both valid forms of months
	            // in RegExp ready format.
	            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';
	        } else if (/D MMMM/.test(format)) {
	            return monthsSubjective[momentToFormat.month()];
	        } else {
	            return monthsNominative[momentToFormat.month()];
	        }
	    },
	    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),
	    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),
	    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),
	    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Dziś o] LT',
	        nextDay: '[Jutro o] LT',
	        nextWeek: '[W] dddd [o] LT',
	        lastDay: '[Wczoraj o] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[W zeszłą niedzielę o] LT';
	                case 3:
	                    return '[W zeszłą środę o] LT';
	                case 6:
	                    return '[W zeszłą sobotę o] LT';
	                default:
	                    return '[W zeszły] dddd [o] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : '%s temu',
	        s : 'kilka sekund',
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : '1 dzień',
	        dd : '%d dni',
	        M : 'miesiąc',
	        MM : translate,
	        y : 'rok',
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return pl;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/pl.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/pt.js **/
jupyter.define('moment@2.18.1/locale/pt.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Portuguese [pt]
	//! author : Jefferson : https://github.com/jalex79
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var pt = moment.defineLocale('pt', {
	    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
	    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY HH:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hoje às] LT',
	        nextDay: '[Amanhã às] LT',
	        nextWeek: 'dddd [às] LT',
	        lastDay: '[Ontem às] LT',
	        lastWeek: function () {
	            return (this.day() === 0 || this.day() === 6) ?
	                '[Último] dddd [às] LT' : // Saturday + Sunday
	                '[Última] dddd [às] LT'; // Monday - Friday
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'em %s',
	        past : 'há %s',
	        s : 'segundos',
	        m : 'um minuto',
	        mm : '%d minutos',
	        h : 'uma hora',
	        hh : '%d horas',
	        d : 'um dia',
	        dd : '%d dias',
	        M : 'um mês',
	        MM : '%d meses',
	        y : 'um ano',
	        yy : '%d anos'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}º/,
	    ordinal : '%dº',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return pt;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/pt.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/pt-br.js **/
jupyter.define('moment@2.18.1/locale/pt-br.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Portuguese (Brazil) [pt-br]
	//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var ptBr = moment.defineLocale('pt-br', {
	    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
	    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D [de] MMMM [de] YYYY',
	        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
	        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hoje às] LT',
	        nextDay: '[Amanhã às] LT',
	        nextWeek: 'dddd [às] LT',
	        lastDay: '[Ontem às] LT',
	        lastWeek: function () {
	            return (this.day() === 0 || this.day() === 6) ?
	                '[Último] dddd [às] LT' : // Saturday + Sunday
	                '[Última] dddd [às] LT'; // Monday - Friday
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'em %s',
	        past : '%s atrás',
	        s : 'poucos segundos',
	        m : 'um minuto',
	        mm : '%d minutos',
	        h : 'uma hora',
	        hh : '%d horas',
	        d : 'um dia',
	        dd : '%d dias',
	        M : 'um mês',
	        MM : '%d meses',
	        y : 'um ano',
	        yy : '%d anos'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}º/,
	    ordinal : '%dº'
	});
	
	return ptBr;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/pt-br.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ro.js **/
jupyter.define('moment@2.18.1/locale/ro.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Romanian [ro]
	//! author : Vlad Gurdiga : https://github.com/gurdiga
	//! author : Valentin Agachi : https://github.com/avaly
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	            'mm': 'minute',
	            'hh': 'ore',
	            'dd': 'zile',
	            'MM': 'luni',
	            'yy': 'ani'
	        },
	        separator = ' ';
	    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
	        separator = ' de ';
	    }
	    return number + separator + format[key];
	}
	
	var ro = moment.defineLocale('ro', {
	    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),
	    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),
	    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),
	    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY H:mm',
	        LLLL : 'dddd, D MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay: '[azi la] LT',
	        nextDay: '[mâine la] LT',
	        nextWeek: 'dddd [la] LT',
	        lastDay: '[ieri la] LT',
	        lastWeek: '[fosta] dddd [la] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'peste %s',
	        past : '%s în urmă',
	        s : 'câteva secunde',
	        m : 'un minut',
	        mm : relativeTimeWithPlural,
	        h : 'o oră',
	        hh : relativeTimeWithPlural,
	        d : 'o zi',
	        dd : relativeTimeWithPlural,
	        M : 'o lună',
	        MM : relativeTimeWithPlural,
	        y : 'un an',
	        yy : relativeTimeWithPlural
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ro;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ro.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ru.js **/
jupyter.define('moment@2.18.1/locale/ru.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Russian [ru]
	//! author : Viktorminator : https://github.com/Viktorminator
	//! Author : Menelion Elensúle : https://github.com/Oire
	//! author : Коренберг Марк : https://github.com/socketpair
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
	        'hh': 'час_часа_часов',
	        'dd': 'день_дня_дней',
	        'MM': 'месяц_месяца_месяцев',
	        'yy': 'год_года_лет'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'минута' : 'минуту';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];
	
	// http://new.gramota.ru/spravka/rules/139-prop : § 103
	// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637
	// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753
	var ru = moment.defineLocale('ru', {
	    months : {
	        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),
	        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')
	    },
	    monthsShort : {
	        // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ?
	        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),
	        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')
	    },
	    weekdays : {
	        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
	        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),
	        isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/
	    },
	    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
	    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
	    monthsParse : monthsParse,
	    longMonthsParse : monthsParse,
	    shortMonthsParse : monthsParse,
	
	    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки
	    monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
	
	    // копия предыдущего
	    monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
	
	    // полные названия с падежами
	    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,
	
	    // Выражение, которое соотвествует только сокращённым формам
	    monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY г.',
	        LLL : 'D MMMM YYYY г., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY г., HH:mm'
	    },
	    calendar : {
	        sameDay: '[Сегодня в] LT',
	        nextDay: '[Завтра в] LT',
	        lastDay: '[Вчера в] LT',
	        nextWeek: function (now) {
	            if (now.week() !== this.week()) {
	                switch (this.day()) {
	                    case 0:
	                        return '[В следующее] dddd [в] LT';
	                    case 1:
	                    case 2:
	                    case 4:
	                        return '[В следующий] dddd [в] LT';
	                    case 3:
	                    case 5:
	                    case 6:
	                        return '[В следующую] dddd [в] LT';
	                }
	            } else {
	                if (this.day() === 2) {
	                    return '[Во] dddd [в] LT';
	                } else {
	                    return '[В] dddd [в] LT';
	                }
	            }
	        },
	        lastWeek: function (now) {
	            if (now.week() !== this.week()) {
	                switch (this.day()) {
	                    case 0:
	                        return '[В прошлое] dddd [в] LT';
	                    case 1:
	                    case 2:
	                    case 4:
	                        return '[В прошлый] dddd [в] LT';
	                    case 3:
	                    case 5:
	                    case 6:
	                        return '[В прошлую] dddd [в] LT';
	                }
	            } else {
	                if (this.day() === 2) {
	                    return '[Во] dddd [в] LT';
	                } else {
	                    return '[В] dddd [в] LT';
	                }
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'через %s',
	        past : '%s назад',
	        s : 'несколько секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : 'час',
	        hh : relativeTimeWithPlural,
	        d : 'день',
	        dd : relativeTimeWithPlural,
	        M : 'месяц',
	        MM : relativeTimeWithPlural,
	        y : 'год',
	        yy : relativeTimeWithPlural
	    },
	    meridiemParse: /ночи|утра|дня|вечера/i,
	    isPM : function (input) {
	        return /^(дня|вечера)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночи';
	        } else if (hour < 12) {
	            return 'утра';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечера';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	                return number + '-й';
	            case 'D':
	                return number + '-го';
	            case 'w':
	            case 'W':
	                return number + '-я';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ru;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ru.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sd.js **/
jupyter.define('moment@2.18.1/locale/sd.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Sindhi [sd]
	//! author : Narain Sagar : https://github.com/narainsagar
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'جنوري',
	    'فيبروري',
	    'مارچ',
	    'اپريل',
	    'مئي',
	    'جون',
	    'جولاءِ',
	    'آگسٽ',
	    'سيپٽمبر',
	    'آڪٽوبر',
	    'نومبر',
	    'ڊسمبر'
	];
	var days = [
	    'آچر',
	    'سومر',
	    'اڱارو',
	    'اربع',
	    'خميس',
	    'جمع',
	    'ڇنڇر'
	];
	
	var sd = moment.defineLocale('sd', {
	    months : months,
	    monthsShort : months,
	    weekdays : days,
	    weekdaysShort : days,
	    weekdaysMin : days,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd، D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /صبح|شام/,
	    isPM : function (input) {
	        return 'شام' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'صبح';
	        }
	        return 'شام';
	    },
	    calendar : {
	        sameDay : '[اڄ] LT',
	        nextDay : '[سڀاڻي] LT',
	        nextWeek : 'dddd [اڳين هفتي تي] LT',
	        lastDay : '[ڪالهه] LT',
	        lastWeek : '[گزريل هفتي] dddd [تي] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s پوء',
	        past : '%s اڳ',
	        s : 'چند سيڪنڊ',
	        m : 'هڪ منٽ',
	        mm : '%d منٽ',
	        h : 'هڪ ڪلاڪ',
	        hh : '%d ڪلاڪ',
	        d : 'هڪ ڏينهن',
	        dd : '%d ڏينهن',
	        M : 'هڪ مهينو',
	        MM : '%d مهينا',
	        y : 'هڪ سال',
	        yy : '%d سال'
	    },
	    preparse: function (string) {
	        return string.replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/,/g, '،');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sd;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sd.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/se.js **/
jupyter.define('moment@2.18.1/locale/se.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Northern Sami [se]
	//! authors : Bård Rolstad Henriksen : https://github.com/karamell
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var se = moment.defineLocale('se', {
	    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),
	    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),
	    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),
	    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),
	    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'MMMM D. [b.] YYYY',
	        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',
	        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'
	    },
	    calendar : {
	        sameDay: '[otne ti] LT',
	        nextDay: '[ihttin ti] LT',
	        nextWeek: 'dddd [ti] LT',
	        lastDay: '[ikte ti] LT',
	        lastWeek: '[ovddit] dddd [ti] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s geažes',
	        past : 'maŋit %s',
	        s : 'moadde sekunddat',
	        m : 'okta minuhta',
	        mm : '%d minuhtat',
	        h : 'okta diimmu',
	        hh : '%d diimmut',
	        d : 'okta beaivi',
	        dd : '%d beaivvit',
	        M : 'okta mánnu',
	        MM : '%d mánut',
	        y : 'okta jahki',
	        yy : '%d jagit'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return se;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/se.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/si.js **/
jupyter.define('moment@2.18.1/locale/si.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Sinhalese [si]
	//! author : Sampath Sitinamaluwa : https://github.com/sampathsris
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	/*jshint -W100*/
	var si = moment.defineLocale('si', {
	    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),
	    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),
	    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),
	    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),
	    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'a h:mm',
	        LTS : 'a h:mm:ss',
	        L : 'YYYY/MM/DD',
	        LL : 'YYYY MMMM D',
	        LLL : 'YYYY MMMM D, a h:mm',
	        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
	    },
	    calendar : {
	        sameDay : '[අද] LT[ට]',
	        nextDay : '[හෙට] LT[ට]',
	        nextWeek : 'dddd LT[ට]',
	        lastDay : '[ඊයේ] LT[ට]',
	        lastWeek : '[පසුගිය] dddd LT[ට]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%sකින්',
	        past : '%sකට පෙර',
	        s : 'තත්පර කිහිපය',
	        m : 'මිනිත්තුව',
	        mm : 'මිනිත්තු %d',
	        h : 'පැය',
	        hh : 'පැය %d',
	        d : 'දිනය',
	        dd : 'දින %d',
	        M : 'මාසය',
	        MM : 'මාස %d',
	        y : 'වසර',
	        yy : 'වසර %d'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2} වැනි/,
	    ordinal : function (number) {
	        return number + ' වැනි';
	    },
	    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,
	    isPM : function (input) {
	        return input === 'ප.ව.' || input === 'පස් වරු';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'ප.ව.' : 'පස් වරු';
	        } else {
	            return isLower ? 'පෙ.ව.' : 'පෙර වරු';
	        }
	    }
	});
	
	return si;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/si.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sk.js **/
jupyter.define('moment@2.18.1/locale/sk.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Slovak [sk]
	//! author : Martin Minka : https://github.com/k2s
	//! based on work of petrbela : https://github.com/petrbela
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');
	var monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');
	function plural(n) {
	    return (n > 1) && (n < 5);
	}
	function translate(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':  // a few seconds / in a few seconds / a few seconds ago
	            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';
	        case 'm':  // a minute / in a minute / a minute ago
	            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');
	        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'minúty' : 'minút');
	            } else {
	                return result + 'minútami';
	            }
	            break;
	        case 'h':  // an hour / in an hour / an hour ago
	            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
	        case 'hh': // 9 hours / in 9 hours / 9 hours ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'hodiny' : 'hodín');
	            } else {
	                return result + 'hodinami';
	            }
	            break;
	        case 'd':  // a day / in a day / a day ago
	            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';
	        case 'dd': // 9 days / in 9 days / 9 days ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'dni' : 'dní');
	            } else {
	                return result + 'dňami';
	            }
	            break;
	        case 'M':  // a month / in a month / a month ago
	            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';
	        case 'MM': // 9 months / in 9 months / 9 months ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'mesiace' : 'mesiacov');
	            } else {
	                return result + 'mesiacmi';
	            }
	            break;
	        case 'y':  // a year / in a year / a year ago
	            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';
	        case 'yy': // 9 years / in 9 years / 9 years ago
	            if (withoutSuffix || isFuture) {
	                return result + (plural(number) ? 'roky' : 'rokov');
	            } else {
	                return result + 'rokmi';
	            }
	            break;
	    }
	}
	
	var sk = moment.defineLocale('sk', {
	    months : months,
	    monthsShort : monthsShort,
	    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),
	    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),
	    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
	    longDateFormat : {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay: '[dnes o] LT',
	        nextDay: '[zajtra o] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v nedeľu o] LT';
	                case 1:
	                case 2:
	                    return '[v] dddd [o] LT';
	                case 3:
	                    return '[v stredu o] LT';
	                case 4:
	                    return '[vo štvrtok o] LT';
	                case 5:
	                    return '[v piatok o] LT';
	                case 6:
	                    return '[v sobotu o] LT';
	            }
	        },
	        lastDay: '[včera o] LT',
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[minulú nedeľu o] LT';
	                case 1:
	                case 2:
	                    return '[minulý] dddd [o] LT';
	                case 3:
	                    return '[minulú stredu o] LT';
	                case 4:
	                case 5:
	                    return '[minulý] dddd [o] LT';
	                case 6:
	                    return '[minulú sobotu o] LT';
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past : 'pred %s',
	        s : translate,
	        m : translate,
	        mm : translate,
	        h : translate,
	        hh : translate,
	        d : translate,
	        dd : translate,
	        M : translate,
	        MM : translate,
	        y : translate,
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sk;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sk.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sl.js **/
jupyter.define('moment@2.18.1/locale/sl.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Slovenian [sl]
	//! author : Robert Sedovšek : https://github.com/sedovsek
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var result = number + ' ';
	    switch (key) {
	        case 's':
	            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';
	        case 'm':
	            return withoutSuffix ? 'ena minuta' : 'eno minuto';
	        case 'mm':
	            if (number === 1) {
	                result += withoutSuffix ? 'minuta' : 'minuto';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'minute' : 'minutami';
	            } else {
	                result += withoutSuffix || isFuture ? 'minut' : 'minutami';
	            }
	            return result;
	        case 'h':
	            return withoutSuffix ? 'ena ura' : 'eno uro';
	        case 'hh':
	            if (number === 1) {
	                result += withoutSuffix ? 'ura' : 'uro';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'uri' : 'urama';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'ure' : 'urami';
	            } else {
	                result += withoutSuffix || isFuture ? 'ur' : 'urami';
	            }
	            return result;
	        case 'd':
	            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';
	        case 'dd':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'dan' : 'dnem';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';
	            } else {
	                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';
	            }
	            return result;
	        case 'M':
	            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';
	        case 'MM':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';
	            } else {
	                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';
	            }
	            return result;
	        case 'y':
	            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';
	        case 'yy':
	            if (number === 1) {
	                result += withoutSuffix || isFuture ? 'leto' : 'letom';
	            } else if (number === 2) {
	                result += withoutSuffix || isFuture ? 'leti' : 'letoma';
	            } else if (number < 5) {
	                result += withoutSuffix || isFuture ? 'leta' : 'leti';
	            } else {
	                result += withoutSuffix || isFuture ? 'let' : 'leti';
	            }
	            return result;
	    }
	}
	
	var sl = moment.defineLocale('sl', {
	    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),
	    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),
	    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM YYYY',
	        LLL : 'D. MMMM YYYY H:mm',
	        LLLL : 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar : {
	        sameDay  : '[danes ob] LT',
	        nextDay  : '[jutri ob] LT',
	
	        nextWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[v] [nedeljo] [ob] LT';
	                case 3:
	                    return '[v] [sredo] [ob] LT';
	                case 6:
	                    return '[v] [soboto] [ob] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[v] dddd [ob] LT';
	            }
	        },
	        lastDay  : '[včeraj ob] LT',
	        lastWeek : function () {
	            switch (this.day()) {
	                case 0:
	                    return '[prejšnjo] [nedeljo] [ob] LT';
	                case 3:
	                    return '[prejšnjo] [sredo] [ob] LT';
	                case 6:
	                    return '[prejšnjo] [soboto] [ob] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[prejšnji] dddd [ob] LT';
	            }
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'čez %s',
	        past   : 'pred %s',
	        s      : processRelativeTime,
	        m      : processRelativeTime,
	        mm     : processRelativeTime,
	        h      : processRelativeTime,
	        hh     : processRelativeTime,
	        d      : processRelativeTime,
	        dd     : processRelativeTime,
	        M      : processRelativeTime,
	        MM     : processRelativeTime,
	        y      : processRelativeTime,
	        yy     : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sl;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sl.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sq.js **/
jupyter.define('moment@2.18.1/locale/sq.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Albanian [sq]
	//! author : Flakërim Ismani : https://github.com/flakerimi
	//! author : Menelion Elensúle : https://github.com/Oire
	//! author : Oerd Cukalla : https://github.com/oerd
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sq = moment.defineLocale('sq', {
	    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),
	    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),
	    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),
	    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),
	    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),
	    weekdaysParseExact : true,
	    meridiemParse: /PD|MD/,
	    isPM: function (input) {
	        return input.charAt(0) === 'M';
	    },
	    meridiem : function (hours, minutes, isLower) {
	        return hours < 12 ? 'PD' : 'MD';
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[Sot në] LT',
	        nextDay : '[Nesër në] LT',
	        nextWeek : 'dddd [në] LT',
	        lastDay : '[Dje në] LT',
	        lastWeek : 'dddd [e kaluar në] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'në %s',
	        past : '%s më parë',
	        s : 'disa sekonda',
	        m : 'një minutë',
	        mm : '%d minuta',
	        h : 'një orë',
	        hh : '%d orë',
	        d : 'një ditë',
	        dd : '%d ditë',
	        M : 'një muaj',
	        MM : '%d muaj',
	        y : 'një vit',
	        yy : '%d vite'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sq;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sq.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sr.js **/
jupyter.define('moment@2.18.1/locale/sr.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Serbian [sr]
	//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['jedan minut', 'jedne minute'],
	        mm: ['minut', 'minute', 'minuta'],
	        h: ['jedan sat', 'jednog sata'],
	        hh: ['sat', 'sata', 'sati'],
	        dd: ['dan', 'dana', 'dana'],
	        MM: ['mesec', 'meseca', 'meseci'],
	        yy: ['godina', 'godine', 'godina']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var sr = moment.defineLocale('sr', {
	    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),
	    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),
	    monthsParseExact: true,
	    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),
	    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),
	    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[danas u] LT',
	        nextDay: '[sutra u] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[u] [nedelju] [u] LT';
	                case 3:
	                    return '[u] [sredu] [u] LT';
	                case 6:
	                    return '[u] [subotu] [u] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[u] dddd [u] LT';
	            }
	        },
	        lastDay  : '[juče u] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[prošle] [nedelje] [u] LT',
	                '[prošlog] [ponedeljka] [u] LT',
	                '[prošlog] [utorka] [u] LT',
	                '[prošle] [srede] [u] LT',
	                '[prošlog] [četvrtka] [u] LT',
	                '[prošlog] [petka] [u] LT',
	                '[prošle] [subote] [u] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'za %s',
	        past   : 'pre %s',
	        s      : 'nekoliko sekundi',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'dan',
	        dd     : translator.translate,
	        M      : 'mesec',
	        MM     : translator.translate,
	        y      : 'godinu',
	        yy     : translator.translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sr;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sr.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sr-cyrl.js **/
jupyter.define('moment@2.18.1/locale/sr-cyrl.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Serbian Cyrillic [sr-cyrl]
	//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var translator = {
	    words: { //Different grammatical cases
	        m: ['један минут', 'једне минуте'],
	        mm: ['минут', 'минуте', 'минута'],
	        h: ['један сат', 'једног сата'],
	        hh: ['сат', 'сата', 'сати'],
	        dd: ['дан', 'дана', 'дана'],
	        MM: ['месец', 'месеца', 'месеци'],
	        yy: ['година', 'године', 'година']
	    },
	    correctGrammaticalCase: function (number, wordKey) {
	        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
	    },
	    translate: function (number, withoutSuffix, key) {
	        var wordKey = translator.words[key];
	        if (key.length === 1) {
	            return withoutSuffix ? wordKey[0] : wordKey[1];
	        } else {
	            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
	        }
	    }
	};
	
	var srCyrl = moment.defineLocale('sr-cyrl', {
	    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),
	    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),
	    monthsParseExact: true,
	    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),
	    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),
	    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat: {
	        LT: 'H:mm',
	        LTS : 'H:mm:ss',
	        L: 'DD.MM.YYYY',
	        LL: 'D. MMMM YYYY',
	        LLL: 'D. MMMM YYYY H:mm',
	        LLLL: 'dddd, D. MMMM YYYY H:mm'
	    },
	    calendar: {
	        sameDay: '[данас у] LT',
	        nextDay: '[сутра у] LT',
	        nextWeek: function () {
	            switch (this.day()) {
	                case 0:
	                    return '[у] [недељу] [у] LT';
	                case 3:
	                    return '[у] [среду] [у] LT';
	                case 6:
	                    return '[у] [суботу] [у] LT';
	                case 1:
	                case 2:
	                case 4:
	                case 5:
	                    return '[у] dddd [у] LT';
	            }
	        },
	        lastDay  : '[јуче у] LT',
	        lastWeek : function () {
	            var lastWeekDays = [
	                '[прошле] [недеље] [у] LT',
	                '[прошлог] [понедељка] [у] LT',
	                '[прошлог] [уторка] [у] LT',
	                '[прошле] [среде] [у] LT',
	                '[прошлог] [четвртка] [у] LT',
	                '[прошлог] [петка] [у] LT',
	                '[прошле] [суботе] [у] LT'
	            ];
	            return lastWeekDays[this.day()];
	        },
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'за %s',
	        past   : 'пре %s',
	        s      : 'неколико секунди',
	        m      : translator.translate,
	        mm     : translator.translate,
	        h      : translator.translate,
	        hh     : translator.translate,
	        d      : 'дан',
	        dd     : translator.translate,
	        M      : 'месец',
	        MM     : translator.translate,
	        y      : 'годину',
	        yy     : translator.translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return srCyrl;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sr-cyrl.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ss.js **/
jupyter.define('moment@2.18.1/locale/ss.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : siSwati [ss]
	//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	
	var ss = moment.defineLocale('ss', {
	    months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'),
	    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),
	    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),
	    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),
	    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Namuhla nga] LT',
	        nextDay : '[Kusasa nga] LT',
	        nextWeek : 'dddd [nga] LT',
	        lastDay : '[Itolo nga] LT',
	        lastWeek : 'dddd [leliphelile] [nga] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'nga %s',
	        past : 'wenteka nga %s',
	        s : 'emizuzwana lomcane',
	        m : 'umzuzu',
	        mm : '%d emizuzu',
	        h : 'lihora',
	        hh : '%d emahora',
	        d : 'lilanga',
	        dd : '%d emalanga',
	        M : 'inyanga',
	        MM : '%d tinyanga',
	        y : 'umnyaka',
	        yy : '%d iminyaka'
	    },
	    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 11) {
	            return 'ekuseni';
	        } else if (hours < 15) {
	            return 'emini';
	        } else if (hours < 19) {
	            return 'entsambama';
	        } else {
	            return 'ebusuku';
	        }
	    },
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'ekuseni') {
	            return hour;
	        } else if (meridiem === 'emini') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {
	            if (hour === 0) {
	                return 0;
	            }
	            return hour + 12;
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}/,
	    ordinal : '%d',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ss;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ss.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sv.js **/
jupyter.define('moment@2.18.1/locale/sv.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Swedish [sv]
	//! author : Jens Alm : https://github.com/ulmus
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sv = moment.defineLocale('sv', {
	    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),
	    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
	    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),
	    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),
	    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY-MM-DD',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY [kl.] HH:mm',
	        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Idag] LT',
	        nextDay: '[Imorgon] LT',
	        lastDay: '[Igår] LT',
	        nextWeek: '[På] dddd LT',
	        lastWeek: '[I] dddd[s] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'om %s',
	        past : 'för %s sedan',
	        s : 'några sekunder',
	        m : 'en minut',
	        mm : '%d minuter',
	        h : 'en timme',
	        hh : '%d timmar',
	        d : 'en dag',
	        dd : '%d dagar',
	        M : 'en månad',
	        MM : '%d månader',
	        y : 'ett år',
	        yy : '%d år'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(e|a)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'e' :
	            (b === 1) ? 'a' :
	            (b === 2) ? 'a' :
	            (b === 3) ? 'e' : 'e';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return sv;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sv.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/sw.js **/
jupyter.define('moment@2.18.1/locale/sw.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Swahili [sw]
	//! author : Fahad Kassim : https://github.com/fadsel
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var sw = moment.defineLocale('sw', {
	    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),
	    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),
	    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),
	    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),
	    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[leo saa] LT',
	        nextDay : '[kesho saa] LT',
	        nextWeek : '[wiki ijayo] dddd [saat] LT',
	        lastDay : '[jana] LT',
	        lastWeek : '[wiki iliyopita] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s baadaye',
	        past : 'tokea %s',
	        s : 'hivi punde',
	        m : 'dakika moja',
	        mm : 'dakika %d',
	        h : 'saa limoja',
	        hh : 'masaa %d',
	        d : 'siku moja',
	        dd : 'masiku %d',
	        M : 'mwezi mmoja',
	        MM : 'miezi %d',
	        y : 'mwaka mmoja',
	        yy : 'miaka %d'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return sw;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/sw.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ta.js **/
jupyter.define('moment@2.18.1/locale/ta.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Tamil [ta]
	//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var symbolMap = {
	    '1': '௧',
	    '2': '௨',
	    '3': '௩',
	    '4': '௪',
	    '5': '௫',
	    '6': '௬',
	    '7': '௭',
	    '8': '௮',
	    '9': '௯',
	    '0': '௦'
	};
	var numberMap = {
	    '௧': '1',
	    '௨': '2',
	    '௩': '3',
	    '௪': '4',
	    '௫': '5',
	    '௬': '6',
	    '௭': '7',
	    '௮': '8',
	    '௯': '9',
	    '௦': '0'
	};
	
	var ta = moment.defineLocale('ta', {
	    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
	    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),
	    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),
	    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),
	    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, HH:mm',
	        LLLL : 'dddd, D MMMM YYYY, HH:mm'
	    },
	    calendar : {
	        sameDay : '[இன்று] LT',
	        nextDay : '[நாளை] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[நேற்று] LT',
	        lastWeek : '[கடந்த வாரம்] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s இல்',
	        past : '%s முன்',
	        s : 'ஒரு சில விநாடிகள்',
	        m : 'ஒரு நிமிடம்',
	        mm : '%d நிமிடங்கள்',
	        h : 'ஒரு மணி நேரம்',
	        hh : '%d மணி நேரம்',
	        d : 'ஒரு நாள்',
	        dd : '%d நாட்கள்',
	        M : 'ஒரு மாதம்',
	        MM : '%d மாதங்கள்',
	        y : 'ஒரு வருடம்',
	        yy : '%d ஆண்டுகள்'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}வது/,
	    ordinal : function (number) {
	        return number + 'வது';
	    },
	    preparse: function (string) {
	        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {
	            return numberMap[match];
	        });
	    },
	    postformat: function (string) {
	        return string.replace(/\d/g, function (match) {
	            return symbolMap[match];
	        });
	    },
	    // refer http://ta.wikipedia.org/s/1er1
	    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 2) {
	            return ' யாமம்';
	        } else if (hour < 6) {
	            return ' வைகறை';  // வைகறை
	        } else if (hour < 10) {
	            return ' காலை'; // காலை
	        } else if (hour < 14) {
	            return ' நண்பகல்'; // நண்பகல்
	        } else if (hour < 18) {
	            return ' எற்பாடு'; // எற்பாடு
	        } else if (hour < 22) {
	            return ' மாலை'; // மாலை
	        } else {
	            return ' யாமம்';
	        }
	    },
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'யாமம்') {
	            return hour < 2 ? hour : hour + 12;
	        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {
	            return hour;
	        } else if (meridiem === 'நண்பகல்') {
	            return hour >= 10 ? hour : hour + 12;
	        } else {
	            return hour + 12;
	        }
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return ta;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ta.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/te.js **/
jupyter.define('moment@2.18.1/locale/te.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Telugu [te]
	//! author : Krishna Chaitanya Thota : https://github.com/kcthota
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var te = moment.defineLocale('te', {
	    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),
	    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),
	    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),
	    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),
	    longDateFormat : {
	        LT : 'A h:mm',
	        LTS : 'A h:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY, A h:mm',
	        LLLL : 'dddd, D MMMM YYYY, A h:mm'
	    },
	    calendar : {
	        sameDay : '[నేడు] LT',
	        nextDay : '[రేపు] LT',
	        nextWeek : 'dddd, LT',
	        lastDay : '[నిన్న] LT',
	        lastWeek : '[గత] dddd, LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s లో',
	        past : '%s క్రితం',
	        s : 'కొన్ని క్షణాలు',
	        m : 'ఒక నిమిషం',
	        mm : '%d నిమిషాలు',
	        h : 'ఒక గంట',
	        hh : '%d గంటలు',
	        d : 'ఒక రోజు',
	        dd : '%d రోజులు',
	        M : 'ఒక నెల',
	        MM : '%d నెలలు',
	        y : 'ఒక సంవత్సరం',
	        yy : '%d సంవత్సరాలు'
	    },
	    dayOfMonthOrdinalParse : /\d{1,2}వ/,
	    ordinal : '%dవ',
	    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === 'రాత్రి') {
	            return hour < 4 ? hour : hour + 12;
	        } else if (meridiem === 'ఉదయం') {
	            return hour;
	        } else if (meridiem === 'మధ్యాహ్నం') {
	            return hour >= 10 ? hour : hour + 12;
	        } else if (meridiem === 'సాయంత్రం') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'రాత్రి';
	        } else if (hour < 10) {
	            return 'ఉదయం';
	        } else if (hour < 17) {
	            return 'మధ్యాహ్నం';
	        } else if (hour < 20) {
	            return 'సాయంత్రం';
	        } else {
	            return 'రాత్రి';
	        }
	    },
	    week : {
	        dow : 0, // Sunday is the first day of the week.
	        doy : 6  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return te;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/te.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/tet.js **/
jupyter.define('moment@2.18.1/locale/tet.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Tetun Dili (East Timor) [tet]
	//! author : Joshua Brooks : https://github.com/joshbrooks
	//! author : Onorio De J. Afonso : https://github.com/marobo
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tet = moment.defineLocale('tet', {
	    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),
	    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),
	    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),
	    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Ohin iha] LT',
	        nextDay: '[Aban iha] LT',
	        nextWeek: 'dddd [iha] LT',
	        lastDay: '[Horiseik iha] LT',
	        lastWeek: 'dddd [semana kotuk] [iha] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'iha %s',
	        past : '%s liuba',
	        s : 'minutu balun',
	        m : 'minutu ida',
	        mm : 'minutus %d',
	        h : 'horas ida',
	        hh : 'horas %d',
	        d : 'loron ida',
	        dd : 'loron %d',
	        M : 'fulan ida',
	        MM : 'fulan %d',
	        y : 'tinan ida',
	        yy : 'tinan %d'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tet;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/tet.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/th.js **/
jupyter.define('moment@2.18.1/locale/th.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Thai [th]
	//! author : Kridsada Thanabulpong : https://github.com/sirn
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var th = moment.defineLocale('th', {
	    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),
	    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),
	    monthsParseExact: true,
	    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),
	    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference
	    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'H:mm',
	        LTS : 'H:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY เวลา H:mm',
	        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'
	    },
	    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
	    isPM: function (input) {
	        return input === 'หลังเที่ยง';
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'ก่อนเที่ยง';
	        } else {
	            return 'หลังเที่ยง';
	        }
	    },
	    calendar : {
	        sameDay : '[วันนี้ เวลา] LT',
	        nextDay : '[พรุ่งนี้ เวลา] LT',
	        nextWeek : 'dddd[หน้า เวลา] LT',
	        lastDay : '[เมื่อวานนี้ เวลา] LT',
	        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'อีก %s',
	        past : '%sที่แล้ว',
	        s : 'ไม่กี่วินาที',
	        m : '1 นาที',
	        mm : '%d นาที',
	        h : '1 ชั่วโมง',
	        hh : '%d ชั่วโมง',
	        d : '1 วัน',
	        dd : '%d วัน',
	        M : '1 เดือน',
	        MM : '%d เดือน',
	        y : '1 ปี',
	        yy : '%d ปี'
	    }
	});
	
	return th;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/th.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/tl-ph.js **/
jupyter.define('moment@2.18.1/locale/tl-ph.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Tagalog (Philippines) [tl-ph]
	//! author : Dan Hagman : https://github.com/hagmandan
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tlPh = moment.defineLocale('tl-ph', {
	    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),
	    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),
	    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),
	    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),
	    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'MM/D/YYYY',
	        LL : 'MMMM D, YYYY',
	        LLL : 'MMMM D, YYYY HH:mm',
	        LLLL : 'dddd, MMMM DD, YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: 'LT [ngayong araw]',
	        nextDay: '[Bukas ng] LT',
	        nextWeek: 'LT [sa susunod na] dddd',
	        lastDay: 'LT [kahapon]',
	        lastWeek: 'LT [noong nakaraang] dddd',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'sa loob ng %s',
	        past : '%s ang nakalipas',
	        s : 'ilang segundo',
	        m : 'isang minuto',
	        mm : '%d minuto',
	        h : 'isang oras',
	        hh : '%d oras',
	        d : 'isang araw',
	        dd : '%d araw',
	        M : 'isang buwan',
	        MM : '%d buwan',
	        y : 'isang taon',
	        yy : '%d taon'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}/,
	    ordinal : function (number) {
	        return number;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tlPh;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/tl-ph.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/tlh.js **/
jupyter.define('moment@2.18.1/locale/tlh.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Klingon [tlh]
	//! author : Dominika Kruk : https://github.com/amaranthrose
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');
	
	function translateFuture(output) {
	    var time = output;
	    time = (output.indexOf('jaj') !== -1) ?
	    time.slice(0, -3) + 'leS' :
	    (output.indexOf('jar') !== -1) ?
	    time.slice(0, -3) + 'waQ' :
	    (output.indexOf('DIS') !== -1) ?
	    time.slice(0, -3) + 'nem' :
	    time + ' pIq';
	    return time;
	}
	
	function translatePast(output) {
	    var time = output;
	    time = (output.indexOf('jaj') !== -1) ?
	    time.slice(0, -3) + 'Hu’' :
	    (output.indexOf('jar') !== -1) ?
	    time.slice(0, -3) + 'wen' :
	    (output.indexOf('DIS') !== -1) ?
	    time.slice(0, -3) + 'ben' :
	    time + ' ret';
	    return time;
	}
	
	function translate(number, withoutSuffix, string, isFuture) {
	    var numberNoun = numberAsNoun(number);
	    switch (string) {
	        case 'mm':
	            return numberNoun + ' tup';
	        case 'hh':
	            return numberNoun + ' rep';
	        case 'dd':
	            return numberNoun + ' jaj';
	        case 'MM':
	            return numberNoun + ' jar';
	        case 'yy':
	            return numberNoun + ' DIS';
	    }
	}
	
	function numberAsNoun(number) {
	    var hundred = Math.floor((number % 1000) / 100),
	    ten = Math.floor((number % 100) / 10),
	    one = number % 10,
	    word = '';
	    if (hundred > 0) {
	        word += numbersNouns[hundred] + 'vatlh';
	    }
	    if (ten > 0) {
	        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';
	    }
	    if (one > 0) {
	        word += ((word !== '') ? ' ' : '') + numbersNouns[one];
	    }
	    return (word === '') ? 'pagh' : word;
	}
	
	var tlh = moment.defineLocale('tlh', {
	    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),
	    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[DaHjaj] LT',
	        nextDay: '[wa’leS] LT',
	        nextWeek: 'LLL',
	        lastDay: '[wa’Hu’] LT',
	        lastWeek: 'LLL',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : translateFuture,
	        past : translatePast,
	        s : 'puS lup',
	        m : 'wa’ tup',
	        mm : translate,
	        h : 'wa’ rep',
	        hh : translate,
	        d : 'wa’ jaj',
	        dd : translate,
	        M : 'wa’ jar',
	        MM : translate,
	        y : 'wa’ DIS',
	        yy : translate
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return tlh;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/tlh.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/tr.js **/
jupyter.define('moment@2.18.1/locale/tr.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Turkish [tr]
	//! authors : Erhan Gundogan : https://github.com/erhangundogan,
	//!           Burak Yiğit Kaya: https://github.com/BYK
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var suffixes = {
	    1: '\'inci',
	    5: '\'inci',
	    8: '\'inci',
	    70: '\'inci',
	    80: '\'inci',
	    2: '\'nci',
	    7: '\'nci',
	    20: '\'nci',
	    50: '\'nci',
	    3: '\'üncü',
	    4: '\'üncü',
	    100: '\'üncü',
	    6: '\'ncı',
	    9: '\'uncu',
	    10: '\'uncu',
	    30: '\'uncu',
	    60: '\'ıncı',
	    90: '\'ıncı'
	};
	
	var tr = moment.defineLocale('tr', {
	    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),
	    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
	    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),
	    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
	    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[bugün saat] LT',
	        nextDay : '[yarın saat] LT',
	        nextWeek : '[haftaya] dddd [saat] LT',
	        lastDay : '[dün] LT',
	        lastWeek : '[geçen hafta] dddd [saat] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s sonra',
	        past : '%s önce',
	        s : 'birkaç saniye',
	        m : 'bir dakika',
	        mm : '%d dakika',
	        h : 'bir saat',
	        hh : '%d saat',
	        d : 'bir gün',
	        dd : '%d gün',
	        M : 'bir ay',
	        MM : '%d ay',
	        y : 'bir yıl',
	        yy : '%d yıl'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,
	    ordinal : function (number) {
	        if (number === 0) {  // special case for zero
	            return number + '\'ıncı';
	        }
	        var a = number % 10,
	            b = number % 100 - a,
	            c = number >= 100 ? 100 : null;
	        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tr;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/tr.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/tzl.js **/
jupyter.define('moment@2.18.1/locale/tzl.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Talossan [tzl]
	//! author : Robin van der Vliet : https://github.com/robin0van0der0v
	//! author : Iustì Canun
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.
	// This is currently too difficult (maybe even impossible) to add.
	var tzl = moment.defineLocale('tzl', {
	    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
	    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
	    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
	    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
	    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
	    longDateFormat : {
	        LT : 'HH.mm',
	        LTS : 'HH.mm.ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D. MMMM [dallas] YYYY',
	        LLL : 'D. MMMM [dallas] YYYY HH.mm',
	        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'
	    },
	    meridiemParse: /d\'o|d\'a/i,
	    isPM : function (input) {
	        return 'd\'o' === input.toLowerCase();
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours > 11) {
	            return isLower ? 'd\'o' : 'D\'O';
	        } else {
	            return isLower ? 'd\'a' : 'D\'A';
	        }
	    },
	    calendar : {
	        sameDay : '[oxhi à] LT',
	        nextDay : '[demà à] LT',
	        nextWeek : 'dddd [à] LT',
	        lastDay : '[ieiri à] LT',
	        lastWeek : '[sür el] dddd [lasteu à] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'osprei %s',
	        past : 'ja%s',
	        s : processRelativeTime,
	        m : processRelativeTime,
	        mm : processRelativeTime,
	        h : processRelativeTime,
	        hh : processRelativeTime,
	        d : processRelativeTime,
	        dd : processRelativeTime,
	        M : processRelativeTime,
	        MM : processRelativeTime,
	        y : processRelativeTime,
	        yy : processRelativeTime
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}\./,
	    ordinal : '%d.',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	function processRelativeTime(number, withoutSuffix, key, isFuture) {
	    var format = {
	        's': ['viensas secunds', '\'iensas secunds'],
	        'm': ['\'n míut', '\'iens míut'],
	        'mm': [number + ' míuts', '' + number + ' míuts'],
	        'h': ['\'n þora', '\'iensa þora'],
	        'hh': [number + ' þoras', '' + number + ' þoras'],
	        'd': ['\'n ziua', '\'iensa ziua'],
	        'dd': [number + ' ziuas', '' + number + ' ziuas'],
	        'M': ['\'n mes', '\'iens mes'],
	        'MM': [number + ' mesen', '' + number + ' mesen'],
	        'y': ['\'n ar', '\'iens ar'],
	        'yy': [number + ' ars', '' + number + ' ars']
	    };
	    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);
	}
	
	return tzl;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/tzl.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/tzm.js **/
jupyter.define('moment@2.18.1/locale/tzm.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Central Atlas Tamazight [tzm]
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tzm = moment.defineLocale('tzm', {
	    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
	    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),
	    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS: 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
	        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',
	        nextWeek: 'dddd [ⴴ] LT',
	        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',
	        lastWeek: 'dddd [ⴴ] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',
	        past : 'ⵢⴰⵏ %s',
	        s : 'ⵉⵎⵉⴽ',
	        m : 'ⵎⵉⵏⵓⴺ',
	        mm : '%d ⵎⵉⵏⵓⴺ',
	        h : 'ⵙⴰⵄⴰ',
	        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',
	        d : 'ⴰⵙⵙ',
	        dd : '%d oⵙⵙⴰⵏ',
	        M : 'ⴰⵢoⵓⵔ',
	        MM : '%d ⵉⵢⵢⵉⵔⵏ',
	        y : 'ⴰⵙⴳⴰⵙ',
	        yy : '%d ⵉⵙⴳⴰⵙⵏ'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tzm;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/tzm.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/tzm-latn.js **/
jupyter.define('moment@2.18.1/locale/tzm-latn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Central Atlas Tamazight Latin [tzm-latn]
	//! author : Abdel Said : https://github.com/abdelsaid
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var tzmLatn = moment.defineLocale('tzm-latn', {
	    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
	    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),
	    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[asdkh g] LT',
	        nextDay: '[aska g] LT',
	        nextWeek: 'dddd [g] LT',
	        lastDay: '[assant g] LT',
	        lastWeek: 'dddd [g] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'dadkh s yan %s',
	        past : 'yan %s',
	        s : 'imik',
	        m : 'minuḍ',
	        mm : '%d minuḍ',
	        h : 'saɛa',
	        hh : '%d tassaɛin',
	        d : 'ass',
	        dd : '%d ossan',
	        M : 'ayowr',
	        MM : '%d iyyirn',
	        y : 'asgas',
	        yy : '%d isgasn'
	    },
	    week : {
	        dow : 6, // Saturday is the first day of the week.
	        doy : 12  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return tzmLatn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/tzm-latn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/uk.js **/
jupyter.define('moment@2.18.1/locale/uk.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Ukrainian [uk]
	//! author : zemlanin : https://github.com/zemlanin
	//! Author : Menelion Elensúle : https://github.com/Oire
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	function plural(word, num) {
	    var forms = word.split('_');
	    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
	}
	function relativeTimeWithPlural(number, withoutSuffix, key) {
	    var format = {
	        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
	        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',
	        'dd': 'день_дні_днів',
	        'MM': 'місяць_місяці_місяців',
	        'yy': 'рік_роки_років'
	    };
	    if (key === 'm') {
	        return withoutSuffix ? 'хвилина' : 'хвилину';
	    }
	    else if (key === 'h') {
	        return withoutSuffix ? 'година' : 'годину';
	    }
	    else {
	        return number + ' ' + plural(format[key], +number);
	    }
	}
	function weekdaysCaseReplace(m, format) {
	    var weekdays = {
	        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
	        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
	        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
	    };
	
	    if (!m) {
	        return weekdays['nominative'];
	    }
	
	    var nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
	        'accusative' :
	        ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
	            'genitive' :
	            'nominative');
	    return weekdays[nounCase][m.day()];
	}
	function processHoursFunction(str) {
	    return function () {
	        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
	    };
	}
	
	var uk = moment.defineLocale('uk', {
	    months : {
	        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),
	        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')
	    },
	    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),
	    weekdays : weekdaysCaseReplace,
	    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD.MM.YYYY',
	        LL : 'D MMMM YYYY р.',
	        LLL : 'D MMMM YYYY р., HH:mm',
	        LLLL : 'dddd, D MMMM YYYY р., HH:mm'
	    },
	    calendar : {
	        sameDay: processHoursFunction('[Сьогодні '),
	        nextDay: processHoursFunction('[Завтра '),
	        lastDay: processHoursFunction('[Вчора '),
	        nextWeek: processHoursFunction('[У] dddd ['),
	        lastWeek: function () {
	            switch (this.day()) {
	                case 0:
	                case 3:
	                case 5:
	                case 6:
	                    return processHoursFunction('[Минулої] dddd [').call(this);
	                case 1:
	                case 2:
	                case 4:
	                    return processHoursFunction('[Минулого] dddd [').call(this);
	            }
	        },
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : 'за %s',
	        past : '%s тому',
	        s : 'декілька секунд',
	        m : relativeTimeWithPlural,
	        mm : relativeTimeWithPlural,
	        h : 'годину',
	        hh : relativeTimeWithPlural,
	        d : 'день',
	        dd : relativeTimeWithPlural,
	        M : 'місяць',
	        MM : relativeTimeWithPlural,
	        y : 'рік',
	        yy : relativeTimeWithPlural
	    },
	    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
	    meridiemParse: /ночі|ранку|дня|вечора/,
	    isPM: function (input) {
	        return /^(дня|вечора)$/.test(input);
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 4) {
	            return 'ночі';
	        } else if (hour < 12) {
	            return 'ранку';
	        } else if (hour < 17) {
	            return 'дня';
	        } else {
	            return 'вечора';
	        }
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/,
	    ordinal: function (number, period) {
	        switch (period) {
	            case 'M':
	            case 'd':
	            case 'DDD':
	            case 'w':
	            case 'W':
	                return number + '-й';
	            case 'D':
	                return number + '-го';
	            default:
	                return number;
	        }
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return uk;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/uk.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/ur.js **/
jupyter.define('moment@2.18.1/locale/ur.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Urdu [ur]
	//! author : Sawood Alam : https://github.com/ibnesayeed
	//! author : Zack : https://github.com/ZackVision
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var months = [
	    'جنوری',
	    'فروری',
	    'مارچ',
	    'اپریل',
	    'مئی',
	    'جون',
	    'جولائی',
	    'اگست',
	    'ستمبر',
	    'اکتوبر',
	    'نومبر',
	    'دسمبر'
	];
	var days = [
	    'اتوار',
	    'پیر',
	    'منگل',
	    'بدھ',
	    'جمعرات',
	    'جمعہ',
	    'ہفتہ'
	];
	
	var ur = moment.defineLocale('ur', {
	    months : months,
	    monthsShort : months,
	    weekdays : days,
	    weekdaysShort : days,
	    weekdaysMin : days,
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd، D MMMM YYYY HH:mm'
	    },
	    meridiemParse: /صبح|شام/,
	    isPM : function (input) {
	        return 'شام' === input;
	    },
	    meridiem : function (hour, minute, isLower) {
	        if (hour < 12) {
	            return 'صبح';
	        }
	        return 'شام';
	    },
	    calendar : {
	        sameDay : '[آج بوقت] LT',
	        nextDay : '[کل بوقت] LT',
	        nextWeek : 'dddd [بوقت] LT',
	        lastDay : '[گذشتہ روز بوقت] LT',
	        lastWeek : '[گذشتہ] dddd [بوقت] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : '%s بعد',
	        past : '%s قبل',
	        s : 'چند سیکنڈ',
	        m : 'ایک منٹ',
	        mm : '%d منٹ',
	        h : 'ایک گھنٹہ',
	        hh : '%d گھنٹے',
	        d : 'ایک دن',
	        dd : '%d دن',
	        M : 'ایک ماہ',
	        MM : '%d ماہ',
	        y : 'ایک سال',
	        yy : '%d سال'
	    },
	    preparse: function (string) {
	        return string.replace(/،/g, ',');
	    },
	    postformat: function (string) {
	        return string.replace(/,/g, '،');
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return ur;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/ur.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/uz.js **/
jupyter.define('moment@2.18.1/locale/uz.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Uzbek [uz]
	//! author : Sardor Muminov : https://github.com/muminoff
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var uz = moment.defineLocale('uz', {
	    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),
	    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),
	    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),
	    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),
	    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'D MMMM YYYY, dddd HH:mm'
	    },
	    calendar : {
	        sameDay : '[Бугун соат] LT [да]',
	        nextDay : '[Эртага] LT [да]',
	        nextWeek : 'dddd [куни соат] LT [да]',
	        lastDay : '[Кеча соат] LT [да]',
	        lastWeek : '[Утган] dddd [куни соат] LT [да]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'Якин %s ичида',
	        past : 'Бир неча %s олдин',
	        s : 'фурсат',
	        m : 'бир дакика',
	        mm : '%d дакика',
	        h : 'бир соат',
	        hh : '%d соат',
	        d : 'бир кун',
	        dd : '%d кун',
	        M : 'бир ой',
	        MM : '%d ой',
	        y : 'бир йил',
	        yy : '%d йил'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return uz;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/uz.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/uz-latn.js **/
jupyter.define('moment@2.18.1/locale/uz-latn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Uzbek Latin [uz-latn]
	//! author : Rasulbek Mirzayev : github.com/Rasulbeeek
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var uzLatn = moment.defineLocale('uz-latn', {
	    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),
	    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),
	    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),
	    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),
	    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'D MMMM YYYY, dddd HH:mm'
	    },
	    calendar : {
	        sameDay : '[Bugun soat] LT [da]',
	        nextDay : '[Ertaga] LT [da]',
	        nextWeek : 'dddd [kuni soat] LT [da]',
	        lastDay : '[Kecha soat] LT [da]',
	        lastWeek : '[O\'tgan] dddd [kuni soat] LT [da]',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'Yaqin %s ichida',
	        past : 'Bir necha %s oldin',
	        s : 'soniya',
	        m : 'bir daqiqa',
	        mm : '%d daqiqa',
	        h : 'bir soat',
	        hh : '%d soat',
	        d : 'bir kun',
	        dd : '%d kun',
	        M : 'bir oy',
	        MM : '%d oy',
	        y : 'bir yil',
	        yy : '%d yil'
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 7  // The week that contains Jan 1st is the first week of the year.
	    }
	});
	
	return uzLatn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/uz-latn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/vi.js **/
jupyter.define('moment@2.18.1/locale/vi.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Vietnamese [vi]
	//! author : Bang Nguyen : https://github.com/bangnk
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var vi = moment.defineLocale('vi', {
	    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),
	    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),
	    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
	    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
	    weekdaysParseExact : true,
	    meridiemParse: /sa|ch/i,
	    isPM : function (input) {
	        return /^ch$/i.test(input);
	    },
	    meridiem : function (hours, minutes, isLower) {
	        if (hours < 12) {
	            return isLower ? 'sa' : 'SA';
	        } else {
	            return isLower ? 'ch' : 'CH';
	        }
	    },
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM [năm] YYYY',
	        LLL : 'D MMMM [năm] YYYY HH:mm',
	        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
	        l : 'DD/M/YYYY',
	        ll : 'D MMM YYYY',
	        lll : 'D MMM YYYY HH:mm',
	        llll : 'ddd, D MMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay: '[Hôm nay lúc] LT',
	        nextDay: '[Ngày mai lúc] LT',
	        nextWeek: 'dddd [tuần tới lúc] LT',
	        lastDay: '[Hôm qua lúc] LT',
	        lastWeek: 'dddd [tuần rồi lúc] LT',
	        sameElse: 'L'
	    },
	    relativeTime : {
	        future : '%s tới',
	        past : '%s trước',
	        s : 'vài giây',
	        m : 'một phút',
	        mm : '%d phút',
	        h : 'một giờ',
	        hh : '%d giờ',
	        d : 'một ngày',
	        dd : '%d ngày',
	        M : 'một tháng',
	        MM : '%d tháng',
	        y : 'một năm',
	        yy : '%d năm'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}/,
	    ordinal : function (number) {
	        return number;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return vi;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/vi.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/x-pseudo.js **/
jupyter.define('moment@2.18.1/locale/x-pseudo.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Pseudo [x-pseudo]
	//! author : Andrew Hood : https://github.com/andrewhood125
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var xPseudo = moment.defineLocale('x-pseudo', {
	    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),
	    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),
	    monthsParseExact : true,
	    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),
	    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),
	    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),
	    weekdaysParseExact : true,
	    longDateFormat : {
	        LT : 'HH:mm',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY HH:mm',
	        LLLL : 'dddd, D MMMM YYYY HH:mm'
	    },
	    calendar : {
	        sameDay : '[T~ódá~ý át] LT',
	        nextDay : '[T~ómó~rró~w át] LT',
	        nextWeek : 'dddd [át] LT',
	        lastDay : '[Ý~ést~érdá~ý át] LT',
	        lastWeek : '[L~ást] dddd [át] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'í~ñ %s',
	        past : '%s á~gó',
	        s : 'á ~féw ~sécó~ñds',
	        m : 'á ~míñ~úté',
	        mm : '%d m~íñú~tés',
	        h : 'á~ñ hó~úr',
	        hh : '%d h~óúrs',
	        d : 'á ~dáý',
	        dd : '%d d~áýs',
	        M : 'á ~móñ~th',
	        MM : '%d m~óñt~hs',
	        y : 'á ~ýéár',
	        yy : '%d ý~éárs'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
	    ordinal : function (number) {
	        var b = number % 10,
	            output = (~~(number % 100 / 10) === 1) ? 'th' :
	            (b === 1) ? 'st' :
	            (b === 2) ? 'nd' :
	            (b === 3) ? 'rd' : 'th';
	        return number + output;
	    },
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return xPseudo;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/x-pseudo.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/yo.js **/
jupyter.define('moment@2.18.1/locale/yo.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Yoruba Nigeria [yo]
	//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var yo = moment.defineLocale('yo', {
	    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),
	    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),
	    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),
	    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),
	    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),
	    longDateFormat : {
	        LT : 'h:mm A',
	        LTS : 'h:mm:ss A',
	        L : 'DD/MM/YYYY',
	        LL : 'D MMMM YYYY',
	        LLL : 'D MMMM YYYY h:mm A',
	        LLLL : 'dddd, D MMMM YYYY h:mm A'
	    },
	    calendar : {
	        sameDay : '[Ònì ni] LT',
	        nextDay : '[Ọ̀la ni] LT',
	        nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT',
	        lastDay : '[Àna ni] LT',
	        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',
	        sameElse : 'L'
	    },
	    relativeTime : {
	        future : 'ní %s',
	        past : '%s kọjá',
	        s : 'ìsẹjú aayá die',
	        m : 'ìsẹjú kan',
	        mm : 'ìsẹjú %d',
	        h : 'wákati kan',
	        hh : 'wákati %d',
	        d : 'ọjọ́ kan',
	        dd : 'ọjọ́ %d',
	        M : 'osù kan',
	        MM : 'osù %d',
	        y : 'ọdún kan',
	        yy : 'ọdún %d'
	    },
	    dayOfMonthOrdinalParse : /ọjọ́\s\d{1,2}/,
	    ordinal : 'ọjọ́ %d',
	    week : {
	        dow : 1, // Monday is the first day of the week.
	        doy : 4 // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return yo;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/yo.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/zh-cn.js **/
jupyter.define('moment@2.18.1/locale/zh-cn.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Chinese (China) [zh-cn]
	//! author : suupic : https://github.com/suupic
	//! author : Zeno Zeng : https://github.com/zenozeng
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhCn = moment.defineLocale('zh-cn', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日Ah点mm分',
	        LLLL : 'YYYY年MMMD日ddddAh点mm分',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日 HH:mm',
	        llll : 'YYYY年MMMD日dddd HH:mm'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour: function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' ||
	                meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        } else {
	            // '中午'
	            return hour >= 11 ? hour : hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd':
	            case 'D':
	            case 'DDD':
	                return number + '日';
	            case 'M':
	                return number + '月';
	            case 'w':
	            case 'W':
	                return number + '周';
	            default:
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s内',
	        past : '%s前',
	        s : '几秒',
	        m : '1 分钟',
	        mm : '%d 分钟',
	        h : '1 小时',
	        hh : '%d 小时',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 个月',
	        MM : '%d 个月',
	        y : '1 年',
	        yy : '%d 年'
	    },
	    week : {
	        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
	        dow : 1, // Monday is the first day of the week.
	        doy : 4  // The week that contains Jan 4th is the first week of the year.
	    }
	});
	
	return zhCn;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/zh-cn.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/zh-hk.js **/
jupyter.define('moment@2.18.1/locale/zh-hk.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Chinese (Hong Kong) [zh-hk]
	//! author : Ben : https://github.com/ben-lin
	//! author : Chris Lam : https://github.com/hehachris
	//! author : Konstantin : https://github.com/skfd
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhHk = moment.defineLocale('zh-hk', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日 HH:mm',
	        LLLL : 'YYYY年MMMD日dddd HH:mm',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日 HH:mm',
	        llll : 'YYYY年MMMD日dddd HH:mm'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '中午') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd' :
	            case 'D' :
	            case 'DDD' :
	                return number + '日';
	            case 'M' :
	                return number + '月';
	            case 'w' :
	            case 'W' :
	                return number + '週';
	            default :
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s內',
	        past : '%s前',
	        s : '幾秒',
	        m : '1 分鐘',
	        mm : '%d 分鐘',
	        h : '1 小時',
	        hh : '%d 小時',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 個月',
	        MM : '%d 個月',
	        y : '1 年',
	        yy : '%d 年'
	    }
	});
	
	return zhHk;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/zh-hk.js **/


/** START DEFINE BLOCK for moment@2.18.1/locale/zh-tw.js **/
jupyter.define('moment@2.18.1/locale/zh-tw.js', function (module, exports, __jupyter_require__) {
	//! moment.js locale configuration
	//! locale : Chinese (Taiwan) [zh-tw]
	//! author : Ben : https://github.com/ben-lin
	//! author : Chris Lam : https://github.com/hehachris
	
	;(function (global, factory) {
	    true ? factory(__jupyter_require__('moment@2.18.1/moment.js')) :
	   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
	   factory(global.moment)
	}(this, (function (moment) { 'use strict';
	
	
	var zhTw = moment.defineLocale('zh-tw', {
	    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
	    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
	    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
	    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),
	    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),
	    longDateFormat : {
	        LT : 'HH:mm',
	        LTS : 'HH:mm:ss',
	        L : 'YYYY年MMMD日',
	        LL : 'YYYY年MMMD日',
	        LLL : 'YYYY年MMMD日 HH:mm',
	        LLLL : 'YYYY年MMMD日dddd HH:mm',
	        l : 'YYYY年MMMD日',
	        ll : 'YYYY年MMMD日',
	        lll : 'YYYY年MMMD日 HH:mm',
	        llll : 'YYYY年MMMD日dddd HH:mm'
	    },
	    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
	    meridiemHour : function (hour, meridiem) {
	        if (hour === 12) {
	            hour = 0;
	        }
	        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
	            return hour;
	        } else if (meridiem === '中午') {
	            return hour >= 11 ? hour : hour + 12;
	        } else if (meridiem === '下午' || meridiem === '晚上') {
	            return hour + 12;
	        }
	    },
	    meridiem : function (hour, minute, isLower) {
	        var hm = hour * 100 + minute;
	        if (hm < 600) {
	            return '凌晨';
	        } else if (hm < 900) {
	            return '早上';
	        } else if (hm < 1130) {
	            return '上午';
	        } else if (hm < 1230) {
	            return '中午';
	        } else if (hm < 1800) {
	            return '下午';
	        } else {
	            return '晚上';
	        }
	    },
	    calendar : {
	        sameDay : '[今天]LT',
	        nextDay : '[明天]LT',
	        nextWeek : '[下]ddddLT',
	        lastDay : '[昨天]LT',
	        lastWeek : '[上]ddddLT',
	        sameElse : 'L'
	    },
	    dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
	    ordinal : function (number, period) {
	        switch (period) {
	            case 'd' :
	            case 'D' :
	            case 'DDD' :
	                return number + '日';
	            case 'M' :
	                return number + '月';
	            case 'w' :
	            case 'W' :
	                return number + '週';
	            default :
	                return number;
	        }
	    },
	    relativeTime : {
	        future : '%s內',
	        past : '%s前',
	        s : '幾秒',
	        m : '1 分鐘',
	        mm : '%d 分鐘',
	        h : '1 小時',
	        hh : '%d 小時',
	        d : '1 天',
	        dd : '%d 天',
	        M : '1 個月',
	        MM : '%d 個月',
	        y : '1 年',
	        yy : '%d 年'
	    }
	});
	
	return zhTw;
	
	})));
	
})
/** END DEFINE BLOCK for moment@2.18.1/locale/zh-tw.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/undoablevector.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/undoablevector.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var observablevector_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablevector.js');
	/**
	 * A concrete implementation of an observable undoable vector.
	 */
	var ObservableUndoableVector = (function (_super) {
	    __extends(ObservableUndoableVector, _super);
	    /**
	     * Construct a new undoable observable vector.
	     */
	    function ObservableUndoableVector(serializer) {
	        var _this = _super.call(this) || this;
	        _this._inCompound = false;
	        _this._isUndoable = true;
	        _this._madeCompoundChange = false;
	        _this._index = -1;
	        _this._stack = [];
	        _this._serializer = null;
	        _this._serializer = serializer;
	        _this.changed.connect(_this._onVectorChanged, _this);
	        return _this;
	    }
	    Object.defineProperty(ObservableUndoableVector.prototype, "canRedo", {
	        /**
	         * Whether the object can redo changes.
	         */
	        get: function () {
	            return this._index < this._stack.length - 1;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableUndoableVector.prototype, "canUndo", {
	        /**
	         * Whether the object can undo changes.
	         */
	        get: function () {
	            return this._index >= 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the model.
	     */
	    ObservableUndoableVector.prototype.dispose = function () {
	        this._serializer = null;
	        this._stack = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Begin a compound operation.
	     *
	     * @param isUndoAble - Whether the operation is undoable.
	     *   The default is `true`.
	     */
	    ObservableUndoableVector.prototype.beginCompoundOperation = function (isUndoAble) {
	        this._inCompound = true;
	        this._isUndoable = (isUndoAble !== false);
	        this._madeCompoundChange = false;
	    };
	    /**
	     * End a compound operation.
	     */
	    ObservableUndoableVector.prototype.endCompoundOperation = function () {
	        this._inCompound = false;
	        this._isUndoable = true;
	        if (this._madeCompoundChange) {
	            this._index++;
	        }
	    };
	    /**
	     * Undo an operation.
	     */
	    ObservableUndoableVector.prototype.undo = function () {
	        if (!this.canUndo) {
	            return;
	        }
	        var changes = this._stack[this._index];
	        this._isUndoable = false;
	        for (var _i = 0, _a = changes.reverse(); _i < _a.length; _i++) {
	            var change = _a[_i];
	            this._undoChange(change);
	        }
	        this._isUndoable = true;
	        this._index--;
	    };
	    /**
	     * Redo an operation.
	     */
	    ObservableUndoableVector.prototype.redo = function () {
	        if (!this.canRedo) {
	            return;
	        }
	        this._index++;
	        var changes = this._stack[this._index];
	        this._isUndoable = false;
	        for (var _i = 0, changes_1 = changes; _i < changes_1.length; _i++) {
	            var change = changes_1[_i];
	            this._redoChange(change);
	        }
	        this._isUndoable = true;
	    };
	    /**
	     * Clear the change stack.
	     */
	    ObservableUndoableVector.prototype.clearUndo = function () {
	        this._index = -1;
	        this._stack = [];
	    };
	    /**
	     * Handle a change in the vector.
	     */
	    ObservableUndoableVector.prototype._onVectorChanged = function (list, change) {
	        if (this.isDisposed || !this._isUndoable) {
	            return;
	        }
	        // Clear everything after this position if necessary.
	        if (!this._inCompound || !this._madeCompoundChange) {
	            this._stack = this._stack.slice(0, this._index + 1);
	        }
	        // Copy the change.
	        var evt = this._copyChange(change);
	        // Put the change in the stack.
	        if (this._stack[this._index + 1]) {
	            this._stack[this._index + 1].push(evt);
	        }
	        else {
	            this._stack.push([evt]);
	        }
	        // If not in a compound operation, increase index.
	        if (!this._inCompound) {
	            this._index++;
	        }
	        else {
	            this._madeCompoundChange = true;
	        }
	    };
	    /**
	     * Undo a change event.
	     */
	    ObservableUndoableVector.prototype._undoChange = function (change) {
	        var _this = this;
	        var index = 0;
	        var serializer = this._serializer;
	        switch (change.type) {
	            case 'add':
	                algorithm_1.each(change.newValues, function () {
	                    _this.removeAt(change.newIndex);
	                });
	                break;
	            case 'set':
	                index = change.oldIndex;
	                algorithm_1.each(change.oldValues, function (value) {
	                    _this.set(index++, serializer.fromJSON(value));
	                });
	                break;
	            case 'remove':
	                index = change.oldIndex;
	                algorithm_1.each(change.oldValues, function (value) {
	                    _this.insert(index++, serializer.fromJSON(value));
	                });
	                break;
	            case 'move':
	                this.move(change.newIndex, change.oldIndex);
	                break;
	            default:
	                return;
	        }
	    };
	    /**
	     * Redo a change event.
	     */
	    ObservableUndoableVector.prototype._redoChange = function (change) {
	        var _this = this;
	        var index = 0;
	        var serializer = this._serializer;
	        switch (change.type) {
	            case 'add':
	                index = change.newIndex;
	                algorithm_1.each(change.newValues, function (value) {
	                    _this.insert(index++, serializer.fromJSON(value));
	                });
	                break;
	            case 'set':
	                index = change.newIndex;
	                algorithm_1.each(change.newValues, function (value) {
	                    _this.set(change.newIndex++, serializer.fromJSON(value));
	                });
	                break;
	            case 'remove':
	                algorithm_1.each(change.oldValues, function () {
	                    _this.removeAt(change.oldIndex);
	                });
	                break;
	            case 'move':
	                this.move(change.oldIndex, change.newIndex);
	                break;
	            default:
	                return;
	        }
	    };
	    /**
	     * Copy a change as JSON.
	     */
	    ObservableUndoableVector.prototype._copyChange = function (change) {
	        var _this = this;
	        var oldValues = [];
	        algorithm_1.each(change.oldValues, function (value) {
	            oldValues.push(_this._serializer.toJSON(value));
	        });
	        var newValues = [];
	        algorithm_1.each(change.newValues, function (value) {
	            newValues.push(_this._serializer.toJSON(value));
	        });
	        return {
	            type: change.type,
	            oldIndex: change.oldIndex,
	            newIndex: change.newIndex,
	            oldValues: oldValues,
	            newValues: newValues
	        };
	    };
	    return ObservableUndoableVector;
	}(observablevector_1.ObservableVector));
	exports.ObservableUndoableVector = ObservableUndoableVector;
	/**
	 * Namespace for ObservableUndoableVector utilities.
	 */
	(function (ObservableUndoableVector) {
	    /**
	     * A default, identity serializer.
	     */
	    var IdentitySerializer = (function () {
	        function IdentitySerializer() {
	        }
	        /**
	         * Identity serialize.
	         */
	        IdentitySerializer.prototype.toJSON = function (value) {
	            return value;
	        };
	        /**
	         * Identity deserialize.
	         */
	        IdentitySerializer.prototype.fromJSON = function (value) {
	            return value;
	        };
	        return IdentitySerializer;
	    }());
	    ObservableUndoableVector.IdentitySerializer = IdentitySerializer;
	})(ObservableUndoableVector = exports.ObservableUndoableVector || (exports.ObservableUndoableVector = {}));
	exports.ObservableUndoableVector = ObservableUndoableVector;
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/undoablevector.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/url.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/url.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var urlparse = __jupyter_require__('url-parse@^1.1.8/index.js');
	/**
	 * The namespace for URL-related functions.
	 */
	var URLExt;
	(function (URLExt) {
	    /**
	     * Parse a url into a URL object.
	     *
	     * @param urlString - The URL string to parse.
	     *
	     * @returns A URL object.
	     */
	    function parse(url) {
	        if (typeof document !== 'undefined') {
	            var a = document.createElement('a');
	            a.href = url;
	            return a;
	        }
	        return urlparse(url);
	    }
	    URLExt.parse = parse;
	    /**
	     * Join a sequence of url components and normalizes as in node `path.join`.
	     *
	     * @param parts - The url components.
	     *
	     * @returns the joined url.
	     */
	    function join() {
	        var parts = [];
	        for (var _i = 0; _i < arguments.length; _i++) {
	            parts[_i] = arguments[_i];
	        }
	        // Adapted from url-join.
	        // Copyright (c) 2016 José F. Romaniello, MIT License.
	        // https://github.com/jfromaniello/url-join/blob/v1.1.0/lib/url-join.js
	        var str = [].slice.call(parts, 0).join('/');
	        // make sure protocol is followed by two slashes
	        str = str.replace(/:\//g, '://');
	        // remove consecutive slashes
	        str = str.replace(/([^:\s])\/+/g, '$1/');
	        // remove trailing slash before parameters or hash
	        str = str.replace(/\/(\?|&|#[^!])/g, '$1');
	        // replace ? in parameters with &
	        str = str.replace(/(\?.+)\?/g, '$1&');
	        return str;
	    }
	    URLExt.join = join;
	    /**
	     * Encode the components of a multi-segment url.
	     *
	     * @param url - The url to encode.
	     *
	     * @returns the encoded url.
	     *
	     * #### Notes
	     * Preserves the `'/'` separators.
	     * Should not include the base url, since all parts are escaped.
	     */
	    function encodeParts(url) {
	        return join.apply(void 0, url.split('/').map(encodeURIComponent));
	    }
	    URLExt.encodeParts = encodeParts;
	    /**
	     * Return a serialized object string suitable for a query.
	     *
	     * @param object - The source object.
	     *
	     * @returns an encoded url query.
	     *
	     * #### Notes
	     * From [stackoverflow](http://stackoverflow.com/a/30707423).
	     */
	    function objectToQueryString(value) {
	        return '?' + Object.keys(value).map(function (key) {
	            return encodeURIComponent(key) + '=' + encodeURIComponent(String(value[key]));
	        }).join('&');
	    }
	    URLExt.objectToQueryString = objectToQueryString;
	    /**
	     * Test whether the url is a local url.
	     */
	    function isLocal(url) {
	        switch (parse(url).hostname) {
	            case 'localhost':
	            case '':
	                return true;
	            default:
	                return false;
	        }
	    }
	    URLExt.isLocal = isLocal;
	})(URLExt = exports.URLExt || (exports.URLExt = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/url.js **/


/** START DEFINE BLOCK for url-parse@1.1.9/index.js **/
jupyter.define('url-parse@1.1.9/index.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(global) {'use strict';
	
	var required = __jupyter_require__('requires-port@1.0.x/index.js')
	  , qs = __jupyter_require__('querystringify@~1.0.0/index.js')
	  , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i
	  , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//;
	
	/**
	 * These are the parse rules for the URL parser, it informs the parser
	 * about:
	 *
	 * 0. The char it Needs to parse, if it's a string it should be done using
	 *    indexOf, RegExp using exec and NaN means set as current value.
	 * 1. The property we should set when parsing this value.
	 * 2. Indication if it's backwards or forward parsing, when set as number it's
	 *    the value of extra chars that should be split off.
	 * 3. Inherit from location if non existing in the parser.
	 * 4. `toLowerCase` the resulting value.
	 */
	var rules = [
	  ['#', 'hash'],                        // Extract from the back.
	  ['?', 'query'],                       // Extract from the back.
	  ['/', 'pathname'],                    // Extract from the back.
	  ['@', 'auth', 1],                     // Extract from the front.
	  [NaN, 'host', undefined, 1, 1],       // Set left over value.
	  [/:(\d+)$/, 'port', undefined, 1],    // RegExp the back.
	  [NaN, 'hostname', undefined, 1, 1]    // Set left over.
	];
	
	/**
	 * These properties should not be copied or inherited from. This is only needed
	 * for all non blob URL's as a blob URL does not include a hash, only the
	 * origin.
	 *
	 * @type {Object}
	 * @private
	 */
	var ignore = { hash: 1, query: 1 };
	
	/**
	 * The location object differs when your code is loaded through a normal page,
	 * Worker or through a worker using a blob. And with the blobble begins the
	 * trouble as the location object will contain the URL of the blob, not the
	 * location of the page where our code is loaded in. The actual origin is
	 * encoded in the `pathname` so we can thankfully generate a good "default"
	 * location from it so we can generate proper relative URL's again.
	 *
	 * @param {Object|String} loc Optional default location object.
	 * @returns {Object} lolcation object.
	 * @api public
	 */
	function lolcation(loc) {
	  loc = loc || global.location || {};
	
	  var finaldestination = {}
	    , type = typeof loc
	    , key;
	
	  if ('blob:' === loc.protocol) {
	    finaldestination = new URL(unescape(loc.pathname), {});
	  } else if ('string' === type) {
	    finaldestination = new URL(loc, {});
	    for (key in ignore) delete finaldestination[key];
	  } else if ('object' === type) {
	    for (key in loc) {
	      if (key in ignore) continue;
	      finaldestination[key] = loc[key];
	    }
	
	    if (finaldestination.slashes === undefined) {
	      finaldestination.slashes = slashes.test(loc.href);
	    }
	  }
	
	  return finaldestination;
	}
	
	/**
	 * @typedef ProtocolExtract
	 * @type Object
	 * @property {String} protocol Protocol matched in the URL, in lowercase.
	 * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`.
	 * @property {String} rest Rest of the URL that is not part of the protocol.
	 */
	
	/**
	 * Extract protocol information from a URL with/without double slash ("//").
	 *
	 * @param {String} address URL we want to extract from.
	 * @return {ProtocolExtract} Extracted information.
	 * @api private
	 */
	function extractProtocol(address) {
	  var match = protocolre.exec(address);
	
	  return {
	    protocol: match[1] ? match[1].toLowerCase() : '',
	    slashes: !!match[2],
	    rest: match[3]
	  };
	}
	
	/**
	 * Resolve a relative URL pathname against a base URL pathname.
	 *
	 * @param {String} relative Pathname of the relative URL.
	 * @param {String} base Pathname of the base URL.
	 * @return {String} Resolved pathname.
	 * @api private
	 */
	function resolve(relative, base) {
	  var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
	    , i = path.length
	    , last = path[i - 1]
	    , unshift = false
	    , up = 0;
	
	  while (i--) {
	    if (path[i] === '.') {
	      path.splice(i, 1);
	    } else if (path[i] === '..') {
	      path.splice(i, 1);
	      up++;
	    } else if (up) {
	      if (i === 0) unshift = true;
	      path.splice(i, 1);
	      up--;
	    }
	  }
	
	  if (unshift) path.unshift('');
	  if (last === '.' || last === '..') path.push('');
	
	  return path.join('/');
	}
	
	/**
	 * The actual URL instance. Instead of returning an object we've opted-in to
	 * create an actual constructor as it's much more memory efficient and
	 * faster and it pleases my OCD.
	 *
	 * @constructor
	 * @param {String} address URL we want to parse.
	 * @param {Object|String} location Location defaults for relative paths.
	 * @param {Boolean|Function} parser Parser for the query string.
	 * @api public
	 */
	function URL(address, location, parser) {
	  if (!(this instanceof URL)) {
	    return new URL(address, location, parser);
	  }
	
	  var relative, extracted, parse, instruction, index, key
	    , instructions = rules.slice()
	    , type = typeof location
	    , url = this
	    , i = 0;
	
	  //
	  // The following if statements allows this module two have compatibility with
	  // 2 different API:
	  //
	  // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
	  //    where the boolean indicates that the query string should also be parsed.
	  //
	  // 2. The `URL` interface of the browser which accepts a URL, object as
	  //    arguments. The supplied object will be used as default values / fall-back
	  //    for relative paths.
	  //
	  if ('object' !== type && 'string' !== type) {
	    parser = location;
	    location = null;
	  }
	
	  if (parser && 'function' !== typeof parser) parser = qs.parse;
	
	  location = lolcation(location);
	
	  //
	  // Extract protocol information before running the instructions.
	  //
	  extracted = extractProtocol(address || '');
	  relative = !extracted.protocol && !extracted.slashes;
	  url.slashes = extracted.slashes || relative && location.slashes;
	  url.protocol = extracted.protocol || location.protocol || '';
	  address = extracted.rest;
	
	  //
	  // When the authority component is absent the URL starts with a path
	  // component.
	  //
	  if (!extracted.slashes) instructions[2] = [/(.*)/, 'pathname'];
	
	  for (; i < instructions.length; i++) {
	    instruction = instructions[i];
	    parse = instruction[0];
	    key = instruction[1];
	
	    if (parse !== parse) {
	      url[key] = address;
	    } else if ('string' === typeof parse) {
	      if (~(index = address.indexOf(parse))) {
	        if ('number' === typeof instruction[2]) {
	          url[key] = address.slice(0, index);
	          address = address.slice(index + instruction[2]);
	        } else {
	          url[key] = address.slice(index);
	          address = address.slice(0, index);
	        }
	      }
	    } else if ((index = parse.exec(address))) {
	      url[key] = index[1];
	      address = address.slice(0, index.index);
	    }
	
	    url[key] = url[key] || (
	      relative && instruction[3] ? location[key] || '' : ''
	    );
	
	    //
	    // Hostname, host and protocol should be lowercased so they can be used to
	    // create a proper `origin`.
	    //
	    if (instruction[4]) url[key] = url[key].toLowerCase();
	  }
	
	  //
	  // Also parse the supplied query string in to an object. If we're supplied
	  // with a custom parser as function use that instead of the default build-in
	  // parser.
	  //
	  if (parser) url.query = parser(url.query);
	
	  //
	  // If the URL is relative, resolve the pathname against the base URL.
	  //
	  if (
	      relative
	    && location.slashes
	    && url.pathname.charAt(0) !== '/'
	    && (url.pathname !== '' || location.pathname !== '')
	  ) {
	    url.pathname = resolve(url.pathname, location.pathname);
	  }
	
	  //
	  // We should not add port numbers if they are already the default port number
	  // for a given protocol. As the host also contains the port number we're going
	  // override it with the hostname which contains no port number.
	  //
	  if (!required(url.port, url.protocol)) {
	    url.host = url.hostname;
	    url.port = '';
	  }
	
	  //
	  // Parse down the `auth` for the username and password.
	  //
	  url.username = url.password = '';
	  if (url.auth) {
	    instruction = url.auth.split(':');
	    url.username = instruction[0] || '';
	    url.password = instruction[1] || '';
	  }
	
	  url.origin = url.protocol && url.host && url.protocol !== 'file:'
	    ? url.protocol +'//'+ url.host
	    : 'null';
	
	  //
	  // The href is just the compiled result.
	  //
	  url.href = url.toString();
	}
	
	/**
	 * This is convenience method for changing properties in the URL instance to
	 * insure that they all propagate correctly.
	 *
	 * @param {String} part          Property we need to adjust.
	 * @param {Mixed} value          The newly assigned value.
	 * @param {Boolean|Function} fn  When setting the query, it will be the function
	 *                               used to parse the query.
	 *                               When setting the protocol, double slash will be
	 *                               removed from the final url if it is true.
	 * @returns {URL}
	 * @api public
	 */
	function set(part, value, fn) {
	  var url = this;
	
	  switch (part) {
	    case 'query':
	      if ('string' === typeof value && value.length) {
	        value = (fn || qs.parse)(value);
	      }
	
	      url[part] = value;
	      break;
	
	    case 'port':
	      url[part] = value;
	
	      if (!required(value, url.protocol)) {
	        url.host = url.hostname;
	        url[part] = '';
	      } else if (value) {
	        url.host = url.hostname +':'+ value;
	      }
	
	      break;
	
	    case 'hostname':
	      url[part] = value;
	
	      if (url.port) value += ':'+ url.port;
	      url.host = value;
	      break;
	
	    case 'host':
	      url[part] = value;
	
	      if (/:\d+$/.test(value)) {
	        value = value.split(':');
	        url.port = value.pop();
	        url.hostname = value.join(':');
	      } else {
	        url.hostname = value;
	        url.port = '';
	      }
	
	      break;
	
	    case 'protocol':
	      url.protocol = value.toLowerCase();
	      url.slashes = !fn;
	      break;
	
	    case 'pathname':
	      url.pathname = value.length && value.charAt(0) !== '/' ? '/' + value : value;
	
	      break;
	
	    default:
	      url[part] = value;
	  }
	
	  for (var i = 0; i < rules.length; i++) {
	    var ins = rules[i];
	
	    if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();
	  }
	
	  url.origin = url.protocol && url.host && url.protocol !== 'file:'
	    ? url.protocol +'//'+ url.host
	    : 'null';
	
	  url.href = url.toString();
	
	  return url;
	}
	
	/**
	 * Transform the properties back in to a valid and full URL string.
	 *
	 * @param {Function} stringify Optional query stringify function.
	 * @returns {String}
	 * @api public
	 */
	function toString(stringify) {
	  if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
	
	  var query
	    , url = this
	    , protocol = url.protocol;
	
	  if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
	
	  var result = protocol + (url.slashes ? '//' : '');
	
	  if (url.username) {
	    result += url.username;
	    if (url.password) result += ':'+ url.password;
	    result += '@';
	  }
	
	  result += url.host + url.pathname;
	
	  query = 'object' === typeof url.query ? stringify(url.query) : url.query;
	  if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;
	
	  if (url.hash) result += url.hash;
	
	  return result;
	}
	
	URL.prototype = { set: set, toString: toString };
	
	//
	// Expose the URL parser and some additional properties that might be useful for
	// others or testing.
	//
	URL.extractProtocol = extractProtocol;
	URL.location = lolcation;
	URL.qs = qs;
	
	module.exports = URL;
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
})
/** END DEFINE BLOCK for url-parse@1.1.9/index.js **/


/** START DEFINE BLOCK for requires-port@1.0.0/index.js **/
jupyter.define('requires-port@1.0.0/index.js', function (module, exports, __jupyter_require__) {
	'use strict';
	
	/**
	 * Check if we're required to add a port number.
	 *
	 * @see https://url.spec.whatwg.org/#default-port
	 * @param {Number|String} port Port number we need to check
	 * @param {String} protocol Protocol we need to check against.
	 * @returns {Boolean} Is it a default port for the given protocol
	 * @api private
	 */
	module.exports = function required(port, protocol) {
	  protocol = protocol.split(':')[0];
	  port = +port;
	
	  if (!port) return false;
	
	  switch (protocol) {
	    case 'http':
	    case 'ws':
	    return port !== 80;
	
	    case 'https':
	    case 'wss':
	    return port !== 443;
	
	    case 'ftp':
	    return port !== 21;
	
	    case 'gopher':
	    return port !== 70;
	
	    case 'file':
	    return false;
	  }
	
	  return port !== 0;
	};
	
})
/** END DEFINE BLOCK for requires-port@1.0.0/index.js **/


/** START DEFINE BLOCK for querystringify@1.0.0/index.js **/
jupyter.define('querystringify@1.0.0/index.js', function (module, exports, __jupyter_require__) {
	'use strict';
	
	var has = Object.prototype.hasOwnProperty;
	
	/**
	 * Decode a URI encoded string.
	 *
	 * @param {String} input The URI encoded string.
	 * @returns {String} The decoded string.
	 * @api private
	 */
	function decode(input) {
	  return decodeURIComponent(input.replace(/\+/g, ' '));
	}
	
	/**
	 * Simple query string parser.
	 *
	 * @param {String} query The query string that needs to be parsed.
	 * @returns {Object}
	 * @api public
	 */
	function querystring(query) {
	  var parser = /([^=?&]+)=?([^&]*)/g
	    , result = {}
	    , part;
	
	  //
	  // Little nifty parsing hack, leverage the fact that RegExp.exec increments
	  // the lastIndex property so we can continue executing this loop until we've
	  // parsed all results.
	  //
	  for (;
	    part = parser.exec(query);
	    result[decode(part[1])] = decode(part[2])
	  );
	
	  return result;
	}
	
	/**
	 * Transform a query string to an object.
	 *
	 * @param {Object} obj Object that should be transformed.
	 * @param {String} prefix Optional prefix.
	 * @returns {String}
	 * @api public
	 */
	function querystringify(obj, prefix) {
	  prefix = prefix || '';
	
	  var pairs = [];
	
	  //
	  // Optionally prefix with a '?' if needed
	  //
	  if ('string' !== typeof prefix) prefix = '?';
	
	  for (var key in obj) {
	    if (has.call(obj, key)) {
	      pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key]));
	    }
	  }
	
	  return pairs.length ? prefix + pairs.join('&') : '';
	}
	
	//
	// Expose the module.
	//
	exports.stringify = querystringify;
	exports.parse = querystring;
	
})
/** END DEFINE BLOCK for querystringify@1.0.0/index.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/uuid.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/uuid.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Get a random hex string (not a formal UUID).
	 *
	 * @param length - The length of the hex string.
	 */
	function uuid(length) {
	    if (length === void 0) { length = 32; }
	    var s = new Array(length);
	    var hexDigits = '0123456789abcdef';
	    var nChars = hexDigits.length;
	    for (var i = 0; i < length; i++) {
	        s[i] = hexDigits.charAt(Math.floor(Math.random() * nChars));
	    }
	    return s.join('');
	}
	exports.uuid = uuid;
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/uuid.js **/


/** START DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/modeldb.js **/
jupyter.define('@jupyterlab/coreutils@0.3.1/lib/modeldb.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var path_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/path.js');
	var observablemap_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablemap.js');
	var observablejson_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablejson.js');
	var observablestring_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/observablestring.js');
	var undoablevector_1 = __jupyter_require__('@jupyterlab/coreutils@0.3.1/lib/undoablevector.js');
	/**
	 * A concrete implementation of an `IObservableValue`.
	 */
	var ObservableValue = (function () {
	    /**
	     * Constructor for the value.
	     *
	     * @param initialValue: the starting value for the `ObservableValue`.
	     */
	    function ObservableValue(initialValue) {
	        this._value = null;
	        this._changed = new signaling_1.Signal(this);
	        this._isDisposed = false;
	        this._value = initialValue;
	    }
	    Object.defineProperty(ObservableValue.prototype, "type", {
	        /**
	         * The observable type.
	         */
	        get: function () {
	            return 'Value';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableValue.prototype, "isDisposed", {
	        /**
	         * Whether the value has been disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ObservableValue.prototype, "changed", {
	        /**
	         * The changed signal.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the current value.
	     */
	    ObservableValue.prototype.get = function () {
	        return this._value;
	    };
	    /**
	     * Set the current value.
	     */
	    ObservableValue.prototype.set = function (value) {
	        var oldValue = this._value;
	        this._value = value;
	        this._changed.emit({
	            oldValue: oldValue,
	            newValue: value
	        });
	    };
	    /**
	     * Dispose of the resources held by the value.
	     */
	    ObservableValue.prototype.dispose = function () {
	        if (this._isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        signaling_1.Signal.clearData(this);
	        this._value = null;
	    };
	    return ObservableValue;
	}());
	exports.ObservableValue = ObservableValue;
	/**
	 * The namespace for the `ObservableValue` class statics.
	 */
	(function (ObservableValue) {
	    /**
	     * The changed args object emitted by the `IObservableValue`.
	     */
	    var IChangedArgs = (function () {
	        function IChangedArgs() {
	        }
	        return IChangedArgs;
	    }());
	    ObservableValue.IChangedArgs = IChangedArgs;
	})(ObservableValue = exports.ObservableValue || (exports.ObservableValue = {}));
	exports.ObservableValue = ObservableValue;
	/**
	 * A concrete implementation of an `IModelDB`.
	 */
	var ModelDB = (function () {
	    /**
	     * Constructor for the `ModelDB`.
	     */
	    function ModelDB(options) {
	        if (options === void 0) { options = {}; }
	        this._db = null;
	        this._toDispose = false;
	        this._disposables = new disposable_1.DisposableSet();
	        this._basePath = options.basePath || '';
	        if (options.baseDB) {
	            this._db = options.baseDB;
	        }
	        else {
	            this._db = new observablemap_1.ObservableMap();
	            this._toDispose = true;
	        }
	    }
	    Object.defineProperty(ModelDB.prototype, "basePath", {
	        /**
	         * The base path for the `ModelDB`. This is prepended
	         * to all the paths that are passed in to the member
	         * functions of the object.
	         */
	        get: function () {
	            return this._basePath;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ModelDB.prototype, "isDisposed", {
	        /**
	         * Whether the database is disposed.
	         */
	        get: function () {
	            return this._db === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ModelDB.prototype, "isPrepopulated", {
	        /**
	         * Whether the model has been populated with
	         * any model values.
	         */
	        get: function () {
	            return false;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ModelDB.prototype, "connected", {
	        /**
	         * A promise resolved when the model is connected
	         * to its backend. For the in-memory ModelDB it
	         * is immediately resolved.
	         */
	        get: function () {
	            return Promise.resolve(void 0);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get a value for a path.
	     *
	     * @param path: the path for the object.
	     *
	     * @returns an `IObservable`.
	     */
	    ModelDB.prototype.get = function (path) {
	        return this._db.get(this._resolvePath(path));
	    };
	    /**
	     * Whether the `IModelDB` has an object at this path.
	     *
	     * @param path: the path for the object.
	     *
	     * @returns a boolean for whether an object is at `path`.
	     */
	    ModelDB.prototype.has = function (path) {
	        return this._db.has(this._resolvePath(path));
	    };
	    /**
	     * Create a string and insert it in the database.
	     *
	     * @param path: the path for the string.
	     *
	     * @returns the string that was created.
	     */
	    ModelDB.prototype.createString = function (path) {
	        var str = new observablestring_1.ObservableString();
	        this._disposables.add(str);
	        this.set(path, str);
	        return str;
	    };
	    /**
	     * Create an undoable vector and insert it in the database.
	     *
	     * @param path: the path for the vector.
	     *
	     * @returns the vector that was created.
	     *
	     * #### Notes
	     * The vector can only store objects that are simple
	     * JSON Objects and primitives.
	     */
	    ModelDB.prototype.createVector = function (path) {
	        var vec = new undoablevector_1.ObservableUndoableVector(new undoablevector_1.ObservableUndoableVector.IdentitySerializer());
	        this._disposables.add(vec);
	        this.set(path, vec);
	        return vec;
	    };
	    /**
	     * Create a map and insert it in the database.
	     *
	     * @param path: the path for the map.
	     *
	     * @returns the map that was created.
	     *
	     * #### Notes
	     * The map can only store objects that are simple
	     * JSON Objects and primitives.
	     */
	    ModelDB.prototype.createMap = function (path) {
	        var map = new observablejson_1.ObservableJSON();
	        this._disposables.add(map);
	        this.set(path, map);
	        return map;
	    };
	    /**
	     * Create an opaque value and insert it in the database.
	     *
	     * @param path: the path for the value.
	     *
	     * @returns the value that was created.
	     */
	    ModelDB.prototype.createValue = function (path) {
	        var val = new ObservableValue();
	        this._disposables.add(val);
	        this.set(path, val);
	        return val;
	    };
	    /**
	     * Get a value at a path. That value must already have
	     * been created using `createValue`.
	     *
	     * @param path: the path for the value.
	     */
	    ModelDB.prototype.getValue = function (path) {
	        var val = this.get(path);
	        if (val.type !== 'Value') {
	            throw Error('Can only call getValue for an ObservableValue');
	        }
	        return val.get();
	    };
	    /**
	     * Set a value at a path. That value must already have
	     * been created using `createValue`.
	     *
	     * @param path: the path for the value.
	     *
	     * @param value: the new value.
	     */
	    ModelDB.prototype.setValue = function (path, value) {
	        var val = this.get(path);
	        if (val.type !== 'Value') {
	            throw Error('Can only call setValue on an ObservableValue');
	        }
	        val.set(value);
	    };
	    /**
	     * Create a view onto a subtree of the model database.
	     *
	     * @param basePath: the path for the root of the subtree.
	     *
	     * @returns an `IModelDB` with a view onto the original
	     *   `IModelDB`, with `basePath` prepended to all paths.
	     */
	    ModelDB.prototype.view = function (basePath) {
	        var view = new ModelDB({ basePath: basePath, baseDB: this });
	        this._disposables.add(view);
	        return view;
	    };
	    /**
	     * Set a value at a path. Not intended to
	     * be called by user code, instead use the
	     * `create*` factory methods.
	     *
	     * @param path: the path to set the value at.
	     *
	     * @param value: the value to set at the path.
	     */
	    ModelDB.prototype.set = function (path, value) {
	        this._db.set(this._resolvePath(path), value);
	    };
	    /**
	     * Dispose of the resources held by the database.
	     */
	    ModelDB.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        var db = this._db;
	        this._db = null;
	        if (this._toDispose) {
	            db.dispose();
	        }
	        this._disposables.dispose();
	    };
	    /**
	     * Compute the fully resolved path for a path argument.
	     */
	    ModelDB.prototype._resolvePath = function (path) {
	        if (this._basePath) {
	            path = this._basePath + '.' + path;
	        }
	        return path_1.PathExt.normalize(path);
	    };
	    return ModelDB;
	}());
	exports.ModelDB = ModelDB;
	
})
/** END DEFINE BLOCK for @jupyterlab/coreutils@0.3.1/lib/modeldb.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/clipboard.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/clipboard.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	/**
	 * The clipboard interface.
	 */
	var Clipboard;
	(function (Clipboard) {
	    /**
	     * Get the application clipboard instance.
	     */
	    function getInstance() {
	        return Private.instance;
	    }
	    Clipboard.getInstance = getInstance;
	    /**
	     * Set the application clipboard instance.
	     */
	    function setInstance(value) {
	        Private.instance = value;
	    }
	    Clipboard.setInstance = setInstance;
	    /**
	     * Copy text to the system clipboard.
	     *
	     * #### Notes
	     * This can only be called in response to a user input event.
	     */
	    function copyToSystem(text) {
	        var node = document.body;
	        var handler = function (event) {
	            var data = event.clipboardData || window.clipboardData;
	            data.setData('text', text);
	            event.preventDefault();
	            node.removeEventListener('copy', handler);
	        };
	        node.addEventListener('copy', handler);
	        generateEvent(node);
	    }
	    Clipboard.copyToSystem = copyToSystem;
	    /**
	     * Generate a clipboard event on a node.
	     *
	     * @param node - The element on which to generate the event.
	     *
	     * @param type - The type of event to generate.
	     *   `'paste'` events cannot be programmatically generated.
	     *
	     * #### Notes
	     * This can only be called in response to a user input event.
	     */
	    function generateEvent(node, type) {
	        // http://stackoverflow.com/a/5210367
	        if (type === void 0) { type = 'copy'; }
	        // Identify selected text.
	        var sel = window.getSelection();
	        // Save the current selection.
	        var savedRanges = [];
	        for (var i = 0, len = sel.rangeCount; i < len; ++i) {
	            savedRanges[i] = sel.getRangeAt(i).cloneRange();
	        }
	        // Select the node content.
	        var range = document.createRange();
	        range.selectNodeContents(node);
	        sel.removeAllRanges();
	        sel.addRange(range);
	        // Execute the command.
	        document.execCommand(type);
	        // Restore the previous selection.
	        sel = window.getSelection();
	        sel.removeAllRanges();
	        for (var i = 0, len = savedRanges.length; i < len; ++i) {
	            sel.addRange(savedRanges[i]);
	        }
	    }
	    Clipboard.generateEvent = generateEvent;
	})(Clipboard = exports.Clipboard || (exports.Clipboard = {}));
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The application clipboard instance.
	     */
	    Private.instance = new coreutils_1.MimeData();
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/clipboard.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/commandlinker.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/commandlinker.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) Jupyter Development Team.
	| Distributed under the terms of the Modified BSD License.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	/**
	 * The command data attribute added to nodes that are connected.
	 */
	var COMMAND_ATTR = 'commandlinker-command';
	/**
	 * The args data attribute added to nodes that are connected.
	 */
	var ARGS_ATTR = 'commandlinker-args';
	/* tslint:disable */
	/**
	 * The command linker token.
	 */
	exports.ICommandLinker = new coreutils_1.Token('jupyter.services.command-linker');
	/**
	 * A static class that provides helper methods to generate clickable nodes that
	 * execute registered commands with pre-populated arguments.
	 */
	var CommandLinker = (function () {
	    /**
	     * Instantiate a new command linker.
	     */
	    function CommandLinker(options) {
	        this._commands = null;
	        this._commands = options.commands;
	        document.body.addEventListener('click', this);
	    }
	    Object.defineProperty(CommandLinker.prototype, "isDisposed", {
	        /**
	         * Test whether the linker is disposed.
	         */
	        get: function () {
	            return this._commands === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the linker.
	     */
	    CommandLinker.prototype.dispose = function () {
	        if (this._commands === null) {
	            return;
	        }
	        this._commands = null;
	        document.body.removeEventListener('click', this);
	    };
	    /**
	     * Connect a command/argument pair to a given node so that when it is clicked,
	     * the command will execute.
	     *
	     * @param node - The node being connected.
	     *
	     * @param command - The command ID to execute upon click.
	     *
	     * @param args - The arguments with which to invoke the command.
	     *
	     * @returns The same node that was passed in, after it has been connected.
	     *
	     * #### Notes
	     * Only `click` events will execute the command on a connected node. So, there
	     * are two considerations that are relevant:
	     * 1. If a node is connected, the default click action will be prevented.
	     * 2. The `HTMLElement` passed in should be clickable.
	     */
	    CommandLinker.prototype.connectNode = function (node, command, args) {
	        var argsValue = JSON.stringify(args);
	        node.setAttribute("data-" + COMMAND_ATTR, command);
	        if (argsValue) {
	            node.setAttribute("data-" + ARGS_ATTR, argsValue);
	        }
	        return node;
	    };
	    /**
	     * Disconnect a node that has been connected to execute a command on click.
	     *
	     * @param node - The node being disconnected.
	     *
	     * @returns The same node that was passed in, after it has been disconnected.
	     *
	     * #### Notes
	     * This method is safe to call multiple times and is safe to call on nodes
	     * that were never connected.
	     *
	     * This method can be called on rendered virtual DOM nodes that were populated
	     * using the `populateVNodeDataset` method in order to disconnect them from
	     * executing their command/argument pair.
	     */
	    CommandLinker.prototype.disconnectNode = function (node) {
	        node.removeAttribute("data-" + COMMAND_ATTR);
	        node.removeAttribute("data-" + ARGS_ATTR);
	        return node;
	    };
	    /**
	     * Handle the DOM events for the command linker helper class.
	     *
	     * @param event - The DOM event sent to the class.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    CommandLinker.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                this._evtClick(event);
	                break;
	            default:
	                return;
	        }
	    };
	    /**
	     * Populate the `dataset` attribute within the collection of attributes used
	     * to instantiate a virtual DOM node with the values necessary for its
	     * rendered DOM node to respond to clicks by executing a command/argument
	     * pair.
	     *
	     * @param command - The command ID to execute upon click.
	     *
	     * @param args - The arguments with which to invoke the command.
	     *
	     * @returns A `dataset` collection for use within virtual node attributes.
	     *
	     * #### Notes
	     * The return value can be used on its own as the value for the `dataset`
	     * attribute of a virtual element, or it can be added to an existing `dataset`
	     * as in the example below.
	     *
	     * #### Example
	     * ```typescript
	     * let command = 'some:command-id';
	     * let args = { alpha: 'beta' };
	     * let anchor = h.a({
	     *   className: 'some-class',
	     *   dataset: {
	     *     foo: '1',
	     *     bar: '2',
	     *     ../...linker.populateVNodeDataset(command, args)
	     *   }
	     * }, 'some text');
	     * ```
	     */
	    CommandLinker.prototype.populateVNodeDataset = function (command, args) {
	        var dataset = (_a = {}, _a[COMMAND_ATTR] = command, _a);
	        if (args !== void 0) {
	            dataset[ARGS_ATTR] = JSON.stringify(args);
	        }
	        return dataset;
	        var _a;
	    };
	    /**
	     * The global click handler that deploys commands/argument pairs that are
	     * attached to the node being clicked.
	     */
	    CommandLinker.prototype._evtClick = function (event) {
	        var target = event.target;
	        while (target && target.parentElement) {
	            if (target.hasAttribute("data-" + COMMAND_ATTR)) {
	                event.preventDefault();
	                var command = target.getAttribute("data-" + COMMAND_ATTR);
	                var argsValue = target.getAttribute("data-" + ARGS_ATTR);
	                var args = void 0;
	                if (argsValue) {
	                    args = JSON.parse(argsValue);
	                }
	                this._commands.execute(command, args);
	                return;
	            }
	            target = target.parentElement;
	        }
	    };
	    return CommandLinker;
	}());
	exports.CommandLinker = CommandLinker;
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/commandlinker.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/commandpalette.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/commandpalette.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) Jupyter Development Team.
	| Distributed under the terms of the Modified BSD License.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	/* tslint:disable */
	/**
	 * The command palette token.
	 */
	exports.ICommandPalette = new coreutils_1.Token('jupyter.services.commandpalette');
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/commandpalette.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/dialog.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/dialog.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var virtualdom_1 = __jupyter_require__('@phosphor/virtualdom@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	var styling_1 = __jupyter_require__('@jupyterlab/apputils@0.3.1/lib/styling.js');
	/**
	 * Create and show a dialog.
	 *
	 * @param options - The dialog setup options.
	 *
	 * @returns A promise that resolves with whether the dialog was accepted.
	 */
	function showDialog(options) {
	    if (options === void 0) { options = {}; }
	    var dialog = new Dialog(options);
	    return dialog.launch().then(function (result) {
	        dialog.dispose();
	        return result;
	    });
	}
	exports.showDialog = showDialog;
	/**
	 * A modal dialog widget.
	 */
	var Dialog = (function (_super) {
	    __extends(Dialog, _super);
	    /**
	     * Create a dialog panel instance.
	     *
	     * @param options - The dialog setup options.
	     */
	    function Dialog(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this) || this;
	        _this.addClass('jp-Dialog');
	        options = Private.handleOptions(options);
	        var renderer = options.renderer;
	        _this._host = options.host;
	        _this._defaultButton = options.defaultButton;
	        _this._buttons = options.buttons;
	        _this._buttonNodes = algorithm_1.toArray(algorithm_1.map(_this._buttons, function (button) {
	            return renderer.createButtonNode(button);
	        }));
	        _this._primary = (options.primaryElement || _this._buttonNodes[_this._defaultButton]);
	        var layout = _this.layout = new widgets_1.PanelLayout();
	        var content = new widgets_1.Panel();
	        content.addClass('jp-Dialog-content');
	        layout.addWidget(content);
	        var header = renderer.createHeader(options.title);
	        var body = renderer.createBody(options.body);
	        var footer = renderer.createFooter(_this._buttonNodes);
	        content.addWidget(header);
	        content.addWidget(body);
	        content.addWidget(footer);
	        return _this;
	    }
	    /**
	     * Dispose of the resources used by the dialog.
	     */
	    Dialog.prototype.dispose = function () {
	        if (this._promise) {
	            var promise = this._promise;
	            this._promise = null;
	            promise.resolve(void 0);
	            algorithm_1.ArrayExt.removeFirstOf(Private.launchQueue, promise.promise);
	        }
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Launch the dialog as a modal window.
	     *
	     * @returns a promise that resolves with the button that was selected.
	     */
	    Dialog.prototype.launch = function () {
	        var _this = this;
	        // Return the existing dialog if already open.
	        if (this._promise) {
	            return this._promise.promise;
	        }
	        this._promise = new coreutils_1.PromiseDelegate();
	        var promise = Promise.all(Private.launchQueue);
	        Private.launchQueue.push(this._promise.promise);
	        return promise.then(function () {
	            widgets_1.Widget.attach(_this, _this._host);
	            return _this._promise.promise;
	        });
	    };
	    /**
	     * Resolve the current dialog.
	     *
	     * @param index - An optional index to the button to resolve.
	     *
	     * #### Notes
	     * Will default to the defaultIndex.
	     * Will resolve the current `show()` with the button value.
	     * Will be a no-op if the dialog is not shown.
	     */
	    Dialog.prototype.resolve = function (index) {
	        if (!this._promise) {
	            return;
	        }
	        if (index === undefined) {
	            index = this._defaultButton;
	        }
	        this._resolve(this._buttons[index]);
	    };
	    /**
	     * Reject the current dialog with a default reject value.
	     *
	     * #### Notes
	     * Will be a no-op if the dialog is not shown.
	     */
	    Dialog.prototype.reject = function () {
	        if (!this._promise) {
	            return;
	        }
	        this._resolve(Dialog.cancelButton());
	    };
	    /**
	     * Handle the DOM events for the directory listing.
	     *
	     * @param event - The DOM event sent to the widget.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    Dialog.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'keydown':
	                this._evtKeydown(event);
	                break;
	            case 'click':
	                this._evtClick(event);
	                break;
	            case 'focus':
	                this._evtFocus(event);
	                break;
	            case 'contextmenu':
	                event.preventDefault();
	                event.stopPropagation();
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     *  A message handler invoked on a `'before-attach'` message.
	     */
	    Dialog.prototype.onAfterAttach = function (msg) {
	        var node = this.node;
	        node.addEventListener('keydown', this, true);
	        node.addEventListener('contextmenu', this, true);
	        node.addEventListener('click', this, true);
	        document.addEventListener('focus', this, true);
	        this._first = Private.findFirstFocusable(this.node);
	        this._original = document.activeElement;
	        this._primary.focus();
	    };
	    /**
	     *  A message handler invoked on a `'after-detach'` message.
	     */
	    Dialog.prototype.onAfterDetach = function (msg) {
	        var node = this.node;
	        node.removeEventListener('keydown', this, true);
	        node.removeEventListener('contextmenu', this, true);
	        node.removeEventListener('click', this, true);
	        document.removeEventListener('focus', this, true);
	        this._original.focus();
	    };
	    /**
	     * A message handler invoked on a `'close-request'` message.
	     */
	    Dialog.prototype.onCloseRequest = function (msg) {
	        if (this._promise) {
	            this.reject();
	        }
	        _super.prototype.onCloseRequest.call(this, msg);
	    };
	    /**
	     * Handle the `'click'` event for a dialog button.
	     *
	     * @param event - The DOM event sent to the widget
	     */
	    Dialog.prototype._evtClick = function (event) {
	        var content = this.node.getElementsByClassName('jp-Dialog-content')[0];
	        if (!content.contains(event.target)) {
	            event.stopPropagation();
	            event.preventDefault();
	            return;
	        }
	        for (var _i = 0, _a = this._buttonNodes; _i < _a.length; _i++) {
	            var buttonNode = _a[_i];
	            if (buttonNode.contains(event.target)) {
	                var index = this._buttonNodes.indexOf(buttonNode);
	                this.resolve(index);
	            }
	        }
	    };
	    /**
	     * Handle the `'keydown'` event for the widget.
	     *
	     * @param event - The DOM event sent to the widget
	     */
	    Dialog.prototype._evtKeydown = function (event) {
	        // Check for escape key
	        switch (event.keyCode) {
	            case 27:
	                event.stopPropagation();
	                event.preventDefault();
	                this.reject();
	                break;
	            case 9:
	                // Handle a tab on the last button.
	                var node = this._buttonNodes[this._buttons.length - 1];
	                if (document.activeElement === node && !event.shiftKey) {
	                    event.stopPropagation();
	                    event.preventDefault();
	                    this._first.focus();
	                }
	                break;
	            case 13:
	                event.stopPropagation();
	                event.preventDefault();
	                this.resolve();
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle the `'focus'` event for the widget.
	     *
	     * @param event - The DOM event sent to the widget
	     */
	    Dialog.prototype._evtFocus = function (event) {
	        var target = event.target;
	        if (!this.node.contains(target)) {
	            event.stopPropagation();
	            this._buttonNodes[this._defaultButton].focus();
	        }
	    };
	    /**
	     * Resolve a button item.
	     */
	    Dialog.prototype._resolve = function (item) {
	        // Prevent loopback.
	        var promise = this._promise;
	        this._promise = null;
	        this.close();
	        algorithm_1.ArrayExt.removeFirstOf(Private.launchQueue, promise.promise);
	        promise.resolve(item);
	    };
	    return Dialog;
	}(widgets_1.Widget));
	exports.Dialog = Dialog;
	/**
	 * The namespace for Dialog class statics.
	 */
	(function (Dialog) {
	    /**
	     * Create an accept button.
	     */
	    function okButton(options) {
	        if (options === void 0) { options = {}; }
	        options.accept = true;
	        return createButton(options);
	    }
	    Dialog.okButton = okButton;
	    ;
	    /**
	     * Create a reject button.
	     */
	    function cancelButton(options) {
	        if (options === void 0) { options = {}; }
	        options.accept = false;
	        return createButton(options);
	    }
	    Dialog.cancelButton = cancelButton;
	    ;
	    /**
	     * Create a warn button.
	     */
	    function warnButton(options) {
	        if (options === void 0) { options = {}; }
	        options.displayType = 'warn';
	        return createButton(options);
	    }
	    Dialog.warnButton = warnButton;
	    ;
	    /**
	     * Create a button item.
	     */
	    function createButton(value) {
	        value.accept = value.accept !== false;
	        var defaultLabel = value.accept ? 'OK' : 'CANCEL';
	        return {
	            label: value.label || defaultLabel,
	            icon: value.icon || '',
	            caption: value.caption || '',
	            className: value.className || '',
	            accept: value.accept,
	            displayType: value.displayType || 'default'
	        };
	    }
	    Dialog.createButton = createButton;
	    /**
	     * The default implementation of a dialog renderer.
	     */
	    var Renderer = (function () {
	        function Renderer() {
	        }
	        /**
	         * Create the header of the dialog.
	         *
	         * @param title - The title of the dialog.
	         *
	         * @returns A widget for the dialog header.
	         */
	        Renderer.prototype.createHeader = function (title) {
	            var header = new widgets_1.Widget();
	            header.addClass('jp-Dialog-header');
	            var titleNode = document.createElement('span');
	            titleNode.textContent = title;
	            titleNode.className = 'jp-Dialog-title';
	            header.node.appendChild(titleNode);
	            return header;
	        };
	        /**
	         * Create the body of the dialog.
	         *
	         * @param value - The input value for the body.
	         *
	         * @returns A widget for the body.
	         */
	        Renderer.prototype.createBody = function (value) {
	            var body;
	            if (typeof value === 'string') {
	                body = new widgets_1.Widget({ node: document.createElement('span') });
	                body.node.textContent = value;
	            }
	            else if (value instanceof widgets_1.Widget) {
	                body = value;
	            }
	            else {
	                body = new widgets_1.Widget({ node: value });
	            }
	            body.addClass('jp-Dialog-body');
	            styling_1.Styling.styleNode(body.node);
	            return body;
	        };
	        /**
	         * Create the footer of the dialog.
	         *
	         * @param buttonNodes - The buttons nodes to add to the footer.
	         *
	         * @returns A widget for the footer.
	         */
	        Renderer.prototype.createFooter = function (buttons) {
	            var footer = new widgets_1.Widget();
	            footer.addClass('jp-Dialog-footer');
	            algorithm_1.each(buttons, function (button) {
	                footer.node.appendChild(button);
	            });
	            styling_1.Styling.styleNode(footer.node);
	            return footer;
	        };
	        /**
	         * Create a button node for the dialog.
	         *
	         * @param button - The button data.
	         *
	         * @returns A node for the button.
	         */
	        Renderer.prototype.createButtonNode = function (button) {
	            var className = this.createItemClass(button);
	            // We use realize here instead of creating
	            // nodes with document.createElement as a
	            // shorthand, and only because this is not
	            // called often.
	            return virtualdom_1.VirtualDOM.realize(virtualdom_1.h.button({ className: className }, this.renderIcon(button), this.renderLabel(button)));
	        };
	        /**
	         * Create the class name for the button.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the button.
	         */
	        Renderer.prototype.createItemClass = function (data) {
	            // Setup the initial class name.
	            var name = 'jp-Dialog-button';
	            // Add the other state classes.
	            if (data.accept) {
	                name += ' jp-mod-accept';
	            }
	            else {
	                name += ' jp-mod-reject';
	            }
	            if (data.displayType === 'warn') {
	                name += ' jp-mod-warn';
	            }
	            // Add the extra class.
	            var extra = data.className;
	            if (extra) {
	                name += " " + extra;
	            }
	            // Return the complete class name.
	            return name;
	        };
	        /**
	         * Render an icon element for a dialog item.
	         *
	         * @param data - The data to use for rendering the icon.
	         *
	         * @returns A virtual element representing the icon.
	         */
	        Renderer.prototype.renderIcon = function (data) {
	            return virtualdom_1.h.div({ className: this.createIconClass(data) });
	        };
	        /**
	         * Create the class name for the button icon.
	         *
	         * @param data - The data to use for the class name.
	         *
	         * @returns The full class name for the item icon.
	         */
	        Renderer.prototype.createIconClass = function (data) {
	            var name = 'jp-Dialog-buttonIcon';
	            var extra = data.icon;
	            return extra ? name + " " + extra : name;
	        };
	        /**
	         * Render the label element for a button.
	         *
	         * @param data - The data to use for rendering the label.
	         *
	         * @returns A virtual element representing the item label.
	         */
	        Renderer.prototype.renderLabel = function (data) {
	            var className = 'jp-Dialog-buttonLabel';
	            var title = data.caption;
	            return virtualdom_1.h.div({ className: className, title: title }, data.label);
	        };
	        return Renderer;
	    }());
	    Dialog.Renderer = Renderer;
	    /**
	     * The default renderer instance.
	     */
	    Dialog.defaultRenderer = new Renderer();
	})(Dialog = exports.Dialog || (exports.Dialog = {}));
	exports.Dialog = Dialog;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The queue for launching dialogs.
	     */
	    Private.launchQueue = [];
	    /**
	     * Handle the input options for a dialog.
	     *
	     * @param options - The input options.
	     *
	     * @returns A new options object with defaults applied.
	     */
	    function handleOptions(options) {
	        var newOptions = {};
	        newOptions.title = options.title || '';
	        newOptions.body = options.body || '';
	        newOptions.host = options.host || document.body;
	        newOptions.buttons = (options.buttons || [Dialog.cancelButton(), Dialog.okButton()]);
	        newOptions.defaultButton = options.defaultButton || newOptions.buttons.length - 1;
	        newOptions.renderer = options.renderer || Dialog.defaultRenderer;
	        newOptions.primaryElement = options.primaryElement;
	        return newOptions;
	    }
	    Private.handleOptions = handleOptions;
	    /**
	     *  Find the first focusable item in the dialog.
	     */
	    function findFirstFocusable(node) {
	        var candidateSelectors = [
	            'input',
	            'select',
	            'a[href]',
	            'textarea',
	            'button',
	            '[tabindex]',
	        ].join(',');
	        return node.querySelectorAll(candidateSelectors)[0];
	    }
	    Private.findFirstFocusable = findFirstFocusable;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/dialog.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/styling.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/styling.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A namespace for node styling.
	 */
	var Styling;
	(function (Styling) {
	    /**
	     * Style a node and its child elements with the default tag names.
	     *
	     * @param node - The base node.
	     *
	     * @param className - The optional CSS class to add to styled nodes.
	     */
	    function styleNode(node, className) {
	        if (className === void 0) { className = ''; }
	        styleNodeByTag(node, 'select', className);
	        styleNodeByTag(node, 'input', className);
	        styleNodeByTag(node, 'button', className);
	    }
	    Styling.styleNode = styleNode;
	    /**
	     * Style a node and its elements that have a given tag name.
	     *
	     * @param node - The base node.
	     *
	     * @param tagName - The html tag name to style.
	     *
	     * @param className - The optional CSS class to add to styled nodes.
	     */
	    function styleNodeByTag(node, tagName, className) {
	        if (className === void 0) { className = ''; }
	        if (node.localName === tagName) {
	            node.classList.add('jp-mod-styled');
	        }
	        if (node.localName === 'select') {
	            wrapSelect(node);
	        }
	        var nodes = node.getElementsByTagName(tagName);
	        for (var i = 0; i < nodes.length; i++) {
	            var child = nodes[i];
	            child.classList.add('jp-mod-styled');
	            if (className) {
	                child.classList.add(className);
	            }
	            if (tagName === 'select') {
	                wrapSelect(child);
	            }
	        }
	    }
	    Styling.styleNodeByTag = styleNodeByTag;
	    /**
	     * Wrap a select node.
	     */
	    function wrapSelect(node) {
	        var wrapper = document.createElement('div');
	        wrapper.classList.add('jp-select-wrapper');
	        node.addEventListener('focus', Private.onFocus);
	        node.addEventListener('blur', Private.onFocus);
	        node.classList.add('jp-mod-styled');
	        if (node.parentElement) {
	            node.parentElement.replaceChild(wrapper, node);
	        }
	        wrapper.appendChild(node);
	        return wrapper;
	    }
	    Styling.wrapSelect = wrapSelect;
	})(Styling = exports.Styling || (exports.Styling = {}));
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Handle a focus event on a styled select.
	     */
	    function onFocus(event) {
	        var target = event.target;
	        var parent = target.parentElement;
	        if (event.type === 'focus') {
	            parent.classList.add('jp-mod-focused');
	        }
	        else {
	            parent.classList.remove('jp-mod-focused');
	        }
	    }
	    Private.onFocus = onFocus;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/styling.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/domutils.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/domutils.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var domutils_1 = __jupyter_require__('@phosphor/domutils@^1.0.0/lib/index.js');
	/**
	 * The namespace for DOM utilities.
	 */
	var DOMUtils;
	(function (DOMUtils) {
	    /**
	     * Get the index of the node at a client position, or `-1`.
	     */
	    function hitTestNodes(nodes, x, y) {
	        return algorithm_1.ArrayExt.findFirstIndex(nodes, function (node) {
	            return domutils_1.ElementExt.hitTest(node, x, y);
	        });
	    }
	    DOMUtils.hitTestNodes = hitTestNodes;
	    /**
	     * Find the first element matching a class name.
	     */
	    function findElement(parent, className) {
	        return parent.querySelector("." + className);
	    }
	    DOMUtils.findElement = findElement;
	})(DOMUtils = exports.DOMUtils || (exports.DOMUtils = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/domutils.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/hoverbox.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/hoverbox.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * The class name added to all hover boxes.
	 */
	var HOVERBOX_CLASS = 'jp-HoverBox';
	/**
	 * The class name added to a hovering node that is scrolled out of view.
	 */
	var OUTOFVIEW_CLASS = 'jp-mod-outofview';
	/**
	 * A namespace for `HoverBox` members.
	 */
	var HoverBox;
	(function (HoverBox) {
	    /**
	     * Set the visible dimensions of a hovering box anchored to an editor cursor.
	     *
	     * @param options - The hover box geometry calculation options.
	     */
	    function setGeometry(options) {
	        var anchor = options.anchor, host = options.host, node = options.node;
	        // Add hover box class if it does not exist.
	        node.classList.add(HOVERBOX_CLASS);
	        // Hide the hover box before querying the DOM for the anchor coordinates.
	        node.classList.add(OUTOFVIEW_CLASS);
	        // If the current coordinates are not visible, bail.
	        if (!host.contains(document.elementFromPoint(anchor.left, anchor.top))) {
	            return;
	        }
	        // Clear any previously set max-height.
	        node.style.maxHeight = '';
	        // Clear any programmatically set margin-top.
	        node.style.marginTop = '';
	        // Make sure the node is visible so that its dimensions can be queried.
	        node.classList.remove(OUTOFVIEW_CLASS);
	        var style = window.getComputedStyle(node);
	        var innerHeight = window.innerHeight;
	        var spaceAbove = anchor.top;
	        var spaceBelow = innerHeight - anchor.bottom;
	        var marginTop = parseInt(style.marginTop, 10) || 0;
	        var minHeight = parseInt(style.minHeight, 10) || options.minHeight;
	        var maxHeight = parseInt(style.maxHeight, 10) || options.maxHeight;
	        // Determine whether to render above or below; check privilege.
	        var renderBelow = options.privilege === 'above' ?
	            spaceAbove < maxHeight && spaceAbove < spaceBelow
	            : spaceBelow >= maxHeight || spaceBelow >= spaceAbove;
	        if (renderBelow) {
	            maxHeight = Math.min(spaceBelow - marginTop, maxHeight);
	        }
	        else {
	            maxHeight = Math.min(spaceAbove, maxHeight);
	            // If the box renders above the text, its top margin is irrelevant.
	            node.style.marginTop = '0px';
	        }
	        node.style.maxHeight = maxHeight + "px";
	        // Make sure the box ought to be visible.
	        var withinBounds = maxHeight > minHeight &&
	            (spaceBelow >= minHeight || spaceAbove >= minHeight);
	        if (!withinBounds) {
	            node.classList.add(OUTOFVIEW_CLASS);
	            return;
	        }
	        // Position the box vertically.
	        var offsetAbove = options.offset && options.offset.vertical &&
	            options.offset.vertical.above || 0;
	        var offsetBelow = options.offset && options.offset.vertical &&
	            options.offset.vertical.below || 0;
	        var top = renderBelow ? (innerHeight - spaceBelow) + offsetBelow
	            : (spaceAbove - node.getBoundingClientRect().height) + offsetAbove;
	        node.style.top = Math.floor(top) + "px";
	        // Position the box horizontally.
	        var offsetHorizontal = options.offset && options.offset.horizontal || 0;
	        var left = anchor.left + offsetHorizontal;
	        node.style.left = Math.ceil(left) + "px";
	        node.style.width = 'auto';
	        // Expand the menu width by the scrollbar size, if present.
	        if (node.scrollHeight >= maxHeight) {
	            node.style.width = "" + (2 * node.offsetWidth - node.clientWidth);
	            node.scrollTop = 0;
	        }
	    }
	    HoverBox.setGeometry = setGeometry;
	})(HoverBox = exports.HoverBox || (exports.HoverBox = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/hoverbox.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/iframe.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/iframe.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	/**
	 * A phosphor widget which wraps an IFrame.
	 */
	var IFrameWidget = (function (_super) {
	    __extends(IFrameWidget, _super);
	    /**
	     * Create a new IFrame widget.
	     */
	    function IFrameWidget() {
	        var _this = _super.call(this, { node: Private.createNode() }) || this;
	        _this.addClass('jp-IFrameWidget');
	        return _this;
	    }
	    Object.defineProperty(IFrameWidget.prototype, "url", {
	        /**
	         * The url of the IFrame.
	         */
	        get: function () {
	            return this.node.querySelector('iframe').getAttribute('src');
	        },
	        set: function (url) {
	            this.node.querySelector('iframe').setAttribute('src', url);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return IFrameWidget;
	}(widgets_1.Widget));
	exports.IFrameWidget = IFrameWidget;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the main content node of an iframe widget.
	     */
	    function createNode() {
	        var node = document.createElement('div');
	        var iframe = document.createElement('iframe');
	        iframe.style.height = '100%';
	        iframe.style.width = '100%';
	        node.appendChild(iframe);
	        return node;
	    }
	    Private.createNode = createNode;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/iframe.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/instancetracker.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/instancetracker.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	/**
	 * A class that keeps track of widget instances on an Application shell.
	 *
	 * #### Notes
	 * The API surface area of this concrete implementation is substantially larger
	 * than the instance tracker interface it implements. The interface is intended
	 * for export by JupyterLab plugins that create widgets and have clients who may
	 * wish to keep track of newly created widgets. This class, however, can be used
	 * internally by plugins to restore state as well.
	 */
	var InstanceTracker = (function () {
	    /**
	     * Create a new instance tracker.
	     *
	     * @param options - The instantiation options for an instance tracker.
	     */
	    function InstanceTracker(options) {
	        this._restore = null;
	        this._tracker = new widgets_1.FocusTracker();
	        this._currentChanged = new signaling_1.Signal(this);
	        this._widgetAdded = new signaling_1.Signal(this);
	        this._widgets = [];
	        this._currentWidget = null;
	        this._shell = options.shell;
	        this.namespace = options.namespace;
	        this._tracker.currentChanged.connect(this._onCurrentChanged, this);
	    }
	    Object.defineProperty(InstanceTracker.prototype, "currentChanged", {
	        /**
	         * A signal emitted when the current widget changes.
	         */
	        get: function () {
	            return this._currentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(InstanceTracker.prototype, "widgetAdded", {
	        /**
	         * A signal emitted when a widget is added.
	         *
	         * #### Notes
	         * This signal will only fire when a widget is added to the tracker. It will
	         * not fire if a widget is injected into the tracker.
	         */
	        get: function () {
	            return this._widgetAdded;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(InstanceTracker.prototype, "currentWidget", {
	        /**
	         * The current widget is the most recently focused or added widget.
	         *
	         * #### Notes
	         * It is the most recently focused widget, or the most recently added
	         * widget if no widget has taken focus.
	         */
	        get: function () {
	            return this._currentWidget;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(InstanceTracker.prototype, "size", {
	        /**
	         * The number of widgets held by the tracker.
	         */
	        get: function () {
	            return this._tracker.widgets.length;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a new widget to the tracker.
	     *
	     * @param widget - The widget being added.
	     */
	    InstanceTracker.prototype.add = function (widget) {
	        if (this._tracker.has(widget)) {
	            var warning = widget.id + " already exists in the tracker.";
	            console.warn(warning);
	            return Promise.reject(warning);
	        }
	        this._tracker.add(widget);
	        this._widgets.push(widget);
	        var injected = Private.injectedProperty.get(widget);
	        var promise = Promise.resolve(void 0);
	        if (injected) {
	            return promise;
	        }
	        widget.disposed.connect(this._onWidgetDisposed, this);
	        // Handle widget state restoration.
	        if (this._restore) {
	            var state = this._restore.state;
	            var widgetName = this._restore.name(widget);
	            if (widgetName) {
	                var name_1 = this.namespace + ":" + widgetName;
	                var data = this._restore.args(widget);
	                Private.nameProperty.set(widget, name_1);
	                promise = state.save(name_1, { data: data });
	            }
	        }
	        // If there is no focused widget, set this as the current widget.
	        if (!this._tracker.currentWidget) {
	            this._currentWidget = widget;
	            this.onCurrentChanged(widget);
	            this._currentChanged.emit(widget);
	        }
	        // Emit the widget added signal.
	        this._widgetAdded.emit(widget);
	        return promise;
	    };
	    Object.defineProperty(InstanceTracker.prototype, "isDisposed", {
	        /**
	         * Test whether the tracker is disposed.
	         */
	        get: function () {
	            return this._tracker === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the tracker.
	     */
	    InstanceTracker.prototype.dispose = function () {
	        if (this._tracker === null) {
	            return;
	        }
	        var tracker = this._tracker;
	        this._tracker = null;
	        signaling_1.Signal.clearData(this);
	        tracker.dispose();
	    };
	    /**
	     * Find the first widget in the tracker that satisfies a filter function.
	     *
	     * @param - fn The filter function to call on each widget.
	     *
	     * #### Notes
	     * If no widget is found, the value returned is `undefined`.
	     */
	    InstanceTracker.prototype.find = function (fn) {
	        return algorithm_1.find(this._tracker.widgets, fn);
	    };
	    /**
	     * Iterate through each widget in the tracker.
	     *
	     * @param fn - The function to call on each widget.
	     */
	    InstanceTracker.prototype.forEach = function (fn) {
	        algorithm_1.each(this._tracker.widgets, function (widget) { fn(widget); });
	    };
	    /**
	     * Inject a foreign widget into the instance tracker.
	     *
	     * @param widget - The widget to inject into the tracker.
	     *
	     * #### Notes
	     * Any widgets injected into an instance tracker will not have their state
	     * saved by the tracker. The primary use case for widget injection is for a
	     * plugin that offers a sub-class of an extant plugin to have its instances
	     * share the same commands as the parent plugin (since most relevant commands
	     * will use the `currentWidget` of the parent plugin's instance tracker). In
	     * this situation, the sub-class plugin may well have its own instance tracker
	     * for layout and state restoration in addition to injecting its widgets into
	     * the parent plugin's instance tracker.
	     */
	    InstanceTracker.prototype.inject = function (widget) {
	        Private.injectedProperty.set(widget, true);
	        this.add(widget);
	    };
	    /**
	     * Check if this tracker has the specified widget.
	     *
	     * @param widget - The widget whose existence is being checked.
	     */
	    InstanceTracker.prototype.has = function (widget) {
	        return this._tracker.has(widget);
	    };
	    /**
	     * Activate the given widget in the application shell.
	     */
	    InstanceTracker.prototype.activate = function (widget) {
	        this._shell.activateById(widget.id);
	    };
	    /**
	     * Restore the widgets in this tracker's namespace.
	     *
	     * @param options - The configuration options that describe restoration.
	     *
	     * @returns A promise that resolves when restoration has completed.
	     *
	     * #### Notes
	     * This function should almost never be invoked by client code. Its primary
	     * use case is to be invoked by a layout restorer plugin that handles
	     * multiple instance trackers and, when ready, asks them each to restore their
	     * respective widgets.
	     */
	    InstanceTracker.prototype.restore = function (options) {
	        this._restore = options;
	        var command = options.command, registry = options.registry, state = options.state, when = options.when;
	        var namespace = this.namespace;
	        var promises = [state.fetchNamespace(namespace)];
	        if (when) {
	            promises = promises.concat(when);
	        }
	        return Promise.all(promises).then(function (_a) {
	            var saved = _a[0];
	            return Promise.all(saved.map(function (item) {
	                var args = item.value.data;
	                // Execute the command and if it fails, delete the state restore data.
	                return registry.execute(command, args)
	                    .catch(function () { state.remove(item.id); });
	            }));
	        });
	    };
	    /**
	     * Save the restore data for a given widget.
	     *
	     * @param widget - The widget being saved.
	     */
	    InstanceTracker.prototype.save = function (widget) {
	        var injected = Private.injectedProperty.get(widget);
	        if (!this._restore || !this.has(widget) || injected) {
	            return;
	        }
	        var state = this._restore.state;
	        var widgetName = this._restore.name(widget);
	        var oldName = Private.nameProperty.get(widget);
	        var newName = widgetName ? this.namespace + ":" + widgetName : null;
	        if (oldName && oldName !== newName) {
	            state.remove(oldName);
	        }
	        // Set the name property irrespective of whether the new name is null.
	        Private.nameProperty.set(widget, newName);
	        if (newName) {
	            var data = this._restore.args(widget);
	            state.save(newName, { data: data });
	        }
	    };
	    /**
	     * Handle the current change event.
	     *
	     * #### Notes
	     * The default implementation is a no-op.
	     */
	    InstanceTracker.prototype.onCurrentChanged = function (value) { };
	    /**
	     * Handle the current change signal from the internal focus tracker.
	     */
	    InstanceTracker.prototype._onCurrentChanged = function (sender, args) {
	        // Bail if the active widget did not change.
	        if (args.newValue === this._currentWidget) {
	            return;
	        }
	        this._currentWidget = args.newValue;
	        this.onCurrentChanged(args.newValue);
	        this._currentChanged.emit(args.newValue);
	    };
	    /**
	     * Clean up after disposed widgets.
	     */
	    InstanceTracker.prototype._onWidgetDisposed = function (widget) {
	        var injected = Private.injectedProperty.get(widget);
	        if (injected) {
	            return;
	        }
	        // Handle widget removal.
	        algorithm_1.ArrayExt.removeFirstOf(this._widgets, widget);
	        // Handle a current changed.
	        if (widget === this._currentWidget) {
	            this._currentWidget = (this._tracker.currentWidget ||
	                this._widgets[this._widgets.length - 1] ||
	                null);
	            this._currentChanged.emit(this._currentWidget);
	            this.onCurrentChanged(this._currentWidget);
	        }
	        if (!this._restore) {
	            return;
	        }
	        // If restore data was saved, delete it from the database.
	        var state = this._restore.state;
	        var name = Private.nameProperty.get(widget);
	        if (name) {
	            state.remove(name);
	        }
	    };
	    return InstanceTracker;
	}());
	exports.InstanceTracker = InstanceTracker;
	/*
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * An attached property to indicate whether a widget has been injected.
	     */
	    Private.injectedProperty = new properties_1.AttachedProperty({
	        name: 'injected',
	        create: function () { return false; }
	    });
	    /**
	     * An attached property for a widget's ID in the state database.
	     */
	    Private.nameProperty = new properties_1.AttachedProperty({
	        name: 'name',
	        create: function () { return ''; }
	    });
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/instancetracker.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/layoutrestorer.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/layoutrestorer.js', function (module, exports, __jupyter_require__) {
	"use strict";
	/*-----------------------------------------------------------------------------
	| Copyright (c) Jupyter Development Team.
	| Distributed under the terms of the Modified BSD License.
	|----------------------------------------------------------------------------*/
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.0.0/lib/index.js');
	/* tslint:disable */
	/**
	 * The layout restorer token.
	 */
	exports.ILayoutRestorer = new coreutils_1.Token('jupyter.services.layout-restorer');
	/**
	 * The state database key for restorer data.
	 */
	var KEY = 'layout-restorer:data';
	/**
	 * The default implementation of a layout restorer.
	 *
	 * #### Notes
	 * The lifecycle for state restoration is subtle. The sequence of events is:
	 *
	 * 1. The layout restorer plugin is instantiated. It installs itself as the
	 *    layout database that the application shell can use to `fetch` and `save`
	 *    layout restoration data.
	 *
	 * 2. Other plugins that care about state restoration require the layout
	 *    restorer as a dependency.
	 *
	 * 3. As each load-time plugin initializes (which happens before the lab
	 *    application has `started`), it instructs the layout restorer whether
	 *    the restorer ought to `restore` its state by passing in its tracker.
	 *    Alternatively, a plugin that does not require its own instance tracker
	 *    (because perhaps it only creates a single widget, like a command palette),
	 *    can simply `add` its widget along with a persistent unique name to the
	 *    layout restorer so that its layout state can be restored when the lab
	 *    application restores.
	 *
	 * 4. After all the load-time plugins have finished initializing, the lab
	 *    application `started` promise will resolve. This is the `first`
	 *    promise that the layout restorer waits for. By this point, all of the
	 *    plugins that care about restoration will have instructed the layout
	 *    restorer to `restore` their state.
	 *
	 * 5. The layout restorer will then instruct each plugin's instance tracker
	 *    to restore its state and reinstantiate whichever widgets it wants. The
	 *    tracker returns a promise to the layout restorer that resolves when it
	 *    has completed restoring the tracked widgets it cares about.
	 *
	 * 6. As each instance tracker finishes restoring the widget instances it cares
	 *    about, it resolves the promise that was made to the layout restorer
	 *    (in step 5). After all of the promises that the restorer is awaiting have
	 *    resolved, the restorer then resolves its `restored` promise allowing the
	 *    application shell to `fetch` the dehydrated layout state and rehydrate the
	 *    saved layout.
	 *
	 * Of particular note are steps 5 and 6: since state restoration of plugins
	 * is accomplished by executing commands, the command that is used to restore
	 * the state of each plugin must return a promise that only resolves when the
	 * widget has been created and added to the plugin's instance tracker.
	 */
	var LayoutRestorer = (function () {
	    /**
	     * Create a layout restorer.
	     */
	    function LayoutRestorer(options) {
	        var _this = this;
	        this._first = null;
	        this._promises = [];
	        this._restored = new coreutils_1.PromiseDelegate();
	        this._registry = null;
	        this._state = null;
	        this._trackers = new Set();
	        this._widgets = new Map();
	        this._registry = options.registry;
	        this._state = options.state;
	        this._first = options.first;
	        this._first.then(function () { return Promise.all(_this._promises); }).then(function () {
	            // Release the promises held in memory.
	            _this._promises = null;
	            // Release the tracker set.
	            _this._trackers.clear();
	            _this._trackers = null;
	        }).then(function () { _this._restored.resolve(void 0); });
	    }
	    Object.defineProperty(LayoutRestorer.prototype, "restored", {
	        /**
	         * A promise resolved when the layout restorer is ready to receive signals.
	         */
	        get: function () {
	            return this._restored.promise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Add a widget to be tracked by the layout restorer.
	     */
	    LayoutRestorer.prototype.add = function (widget, name) {
	        Private.nameProperty.set(widget, name);
	        this._widgets.set(name, widget);
	        widget.disposed.connect(this._onWidgetDisposed, this);
	    };
	    /**
	     * Fetch the layout state for the application.
	     *
	     * #### Notes
	     * Fetching the layout relies on all widget restoration to be complete, so
	     * calls to `fetch` are guaranteed to return after restoration is complete.
	     */
	    LayoutRestorer.prototype.fetch = function () {
	        var _this = this;
	        var blank = {
	            fresh: true, mainArea: null, leftArea: null, rightArea: null
	        };
	        var layout = this._state.fetch(KEY);
	        return Promise.all([layout, this.restored]).then(function (_a) {
	            var data = _a[0];
	            if (!data) {
	                return blank;
	            }
	            var _b = data, main = _b.main, left = _b.left, right = _b.right;
	            // If any data exists, then this is not a fresh session.
	            var fresh = false;
	            // Rehydrate main area.
	            var mainArea = _this._rehydrateMainArea(main);
	            // Rehydrate left area.
	            var leftArea = _this._rehydrateSideArea(left);
	            // Rehydrate right area.
	            var rightArea = _this._rehydrateSideArea(right);
	            return { fresh: fresh, mainArea: mainArea, leftArea: leftArea, rightArea: rightArea };
	        }).catch(function () { return blank; }); // Let fetch fail gracefully; return blank slate.
	    };
	    /**
	     * Restore the widgets of a particular instance tracker.
	     *
	     * @param tracker - The instance tracker whose widgets will be restored.
	     *
	     * @param options - The restoration options.
	     */
	    LayoutRestorer.prototype.restore = function (tracker, options) {
	        var _this = this;
	        if (!this._promises) {
	            var warning = 'restore() can only be called before `first` has resolved.';
	            console.warn(warning);
	            return Promise.reject(warning);
	        }
	        var namespace = tracker.namespace;
	        if (this._trackers.has(namespace)) {
	            var warning = "A tracker namespaced " + namespace + " was already restored.";
	            console.warn(warning);
	            return Promise.reject(warning);
	        }
	        var args = options.args, command = options.command, name = options.name, when = options.when;
	        // Add the tracker to the private trackers collection.
	        this._trackers.add(namespace);
	        // Whenever a new widget is added to the tracker, record its name.
	        tracker.widgetAdded.connect(function (sender, widget) {
	            var widgetName = name(widget);
	            if (widgetName) {
	                _this.add(widget, widgetName);
	            }
	        }, this);
	        var first = this._first;
	        var promise = tracker.restore({
	            args: args, command: command, name: name,
	            registry: this._registry,
	            state: this._state,
	            when: when ? [first].concat(when) : first
	        });
	        this._promises.push(promise);
	        return promise;
	    };
	    /**
	     * Save the layout state for the application.
	     */
	    LayoutRestorer.prototype.save = function (data) {
	        // If there are promises that are unresolved, bail.
	        if (this._promises) {
	            var warning = 'save() was called prematurely.';
	            console.warn(warning);
	            return Promise.reject(warning);
	        }
	        var dehydrated = {};
	        // Dehydrate main area.
	        dehydrated.main = this._dehydrateMainArea(data.mainArea);
	        // Dehydrate left area.
	        dehydrated.left = this._dehydrateSideArea(data.leftArea);
	        // Dehydrate right area.
	        dehydrated.right = this._dehydrateSideArea(data.rightArea);
	        return this._state.save(KEY, dehydrated);
	    };
	    /**
	     * Dehydrate a main area description into a serializable object.
	     */
	    LayoutRestorer.prototype._dehydrateMainArea = function (area) {
	        return Private.serializeMain(area);
	    };
	    /**
	     * Reydrate a serialized main area description object.
	     *
	     * #### Notes
	     * This function consumes data that can become corrupted, so it uses type
	     * coercion to guarantee the dehydrated object is safely processed.
	     */
	    LayoutRestorer.prototype._rehydrateMainArea = function (area) {
	        return Private.deserializeMain(area, this._widgets);
	    };
	    /**
	     * Dehydrate a side area description into a serializable object.
	     */
	    LayoutRestorer.prototype._dehydrateSideArea = function (area) {
	        var dehydrated = { collapsed: area.collapsed };
	        if (area.currentWidget) {
	            var current = Private.nameProperty.get(area.currentWidget);
	            if (current) {
	                dehydrated.current = current;
	            }
	        }
	        if (area.widgets) {
	            dehydrated.widgets = area.widgets
	                .map(function (widget) { return Private.nameProperty.get(widget); })
	                .filter(function (name) { return !!name; });
	        }
	        return dehydrated;
	    };
	    /**
	     * Reydrate a serialized side area description object.
	     *
	     * #### Notes
	     * This function consumes data that can become corrupted, so it uses type
	     * coercion to guarantee the dehydrated object is safely processed.
	     */
	    LayoutRestorer.prototype._rehydrateSideArea = function (area) {
	        if (!area) {
	            return { collapsed: true, currentWidget: null, widgets: null };
	        }
	        var internal = this._widgets;
	        var collapsed = area.hasOwnProperty('collapsed') ? !!area.collapsed
	            : false;
	        var currentWidget = area.current && internal.has("" + area.current) ?
	            internal.get("" + area.current) : null;
	        var widgets = !Array.isArray(area.widgets) ? null
	            : area.widgets
	                .map(function (name) { return internal.has("" + name) ? internal.get("" + name) : null; })
	                .filter(function (widget) { return !!widget; });
	        return { collapsed: collapsed, currentWidget: currentWidget, widgets: widgets };
	    };
	    /**
	     * Handle a widget disposal.
	     */
	    LayoutRestorer.prototype._onWidgetDisposed = function (widget) {
	        var name = Private.nameProperty.get(widget);
	        this._widgets.delete(name);
	    };
	    return LayoutRestorer;
	}());
	exports.LayoutRestorer = LayoutRestorer;
	/*
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * An attached property for a widget's ID in the state database.
	     */
	    Private.nameProperty = new properties_1.AttachedProperty({
	        name: 'name',
	        create: function (owner) { return ''; }
	    });
	    /**
	     * Serialize individual areas within the main area.
	     */
	    function serializeArea(area) {
	        if (!area || !area.type) {
	            return null;
	        }
	        if (area.type === 'tab-area') {
	            return {
	                type: 'tab-area',
	                currentIndex: area.currentIndex,
	                widgets: area.widgets
	                    .map(function (widget) { return Private.nameProperty.get(widget); })
	                    .filter(function (name) { return !!name; })
	            };
	        }
	        return {
	            type: 'split-area',
	            orientation: area.orientation,
	            sizes: area.sizes,
	            children: area.children.map(serializeArea)
	        };
	    }
	    /**
	     * Return a dehydrated, serializable version of the main dock panel.
	     */
	    function serializeMain(area) {
	        var dehydrated = {
	            dock: area && area.dock && serializeArea(area.dock.main) || null
	        };
	        if (area) {
	            dehydrated.mode = area.mode;
	            if (area.currentWidget) {
	                var current = Private.nameProperty.get(area.currentWidget);
	                if (current) {
	                    dehydrated.current = current;
	                }
	            }
	        }
	        return dehydrated;
	    }
	    Private.serializeMain = serializeMain;
	    /**
	     * Deserialize individual areas within the main area.
	     *
	     * #### Notes
	     * Because this data comes from a potentially unreliable foreign source, it is
	     * typed as a `JSONObject`; but the actual expected type is:
	     * `ITabArea | ISplitArea`.
	     *
	     * For fault tolerance, types are manually checked in deserialization.
	     */
	    function deserializeArea(area, names) {
	        if (!area) {
	            return null;
	        }
	        // Because this data is saved to a foreign data source, its type safety is
	        // not guaranteed when it is retrieved, so exhaustive checks are necessary.
	        var type = area.type || 'unknown';
	        if (type === 'unknown' || (type !== 'tab-area' && type !== 'split-area')) {
	            console.warn("Attempted to deserialize unknown type: " + type);
	            return null;
	        }
	        if (type === 'tab-area') {
	            var _a = area, currentIndex = _a.currentIndex, widgets = _a.widgets;
	            var hydrated_1 = {
	                type: 'tab-area',
	                currentIndex: currentIndex || 0,
	                widgets: widgets && widgets.map(function (widget) { return names.get(widget); })
	                    .filter(function (widget) { return !!widget; }) || []
	            };
	            // Make sure the current index is within bounds.
	            if (hydrated_1.currentIndex > hydrated_1.widgets.length - 1) {
	                hydrated_1.currentIndex = 0;
	            }
	            return hydrated_1;
	        }
	        var _b = area, orientation = _b.orientation, sizes = _b.sizes, children = _b.children;
	        var hydrated = {
	            type: 'split-area',
	            orientation: orientation,
	            sizes: sizes || [],
	            children: children &&
	                children.map(function (child) { return deserializeArea(child, names); })
	                    .filter(function (widget) { return !!widget; }) || []
	        };
	        return hydrated;
	    }
	    /**
	     * Return the hydrated version of the main dock panel, ready to restore.
	     *
	     * #### Notes
	     * Because this data comes from a potentially unreliable foreign source, it is
	     * typed as a `JSONObject`; but the actual expected type is: `IMainArea`.
	     *
	     * For fault tolerance, types are manually checked in deserialization.
	     */
	    function deserializeMain(area, names) {
	        if (!area) {
	            return null;
	        }
	        var name = area.current || null;
	        var dock = area.dock || null;
	        var mode = area.mode || null;
	        return {
	            currentWidget: name && names.has(name) && names.get(name) || null,
	            dock: dock ? { main: deserializeArea(dock, names) } : null,
	            mode: mode === 'multiple-document' || mode === 'single-document' ? mode
	                : null
	        };
	    }
	    Private.deserializeMain = deserializeMain;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/layoutrestorer.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/mainmenu.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/mainmenu.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	/* tslint:disable */
	/**
	 * The main menu token.
	 */
	exports.IMainMenu = new coreutils_1.Token('jupyter.services.main-menu');
	/**
	 * The main menu class.  It is intended to be used as a singleton.
	 */
	var MainMenu = (function (_super) {
	    __extends(MainMenu, _super);
	    function MainMenu() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._items = [];
	        return _this;
	    }
	    /**
	     * Add a new menu to the main menu bar.
	     */
	    MainMenu.prototype.addMenu = function (menu, options) {
	        if (options === void 0) { options = {}; }
	        if (algorithm_1.ArrayExt.firstIndexOf(this.menus, menu) > -1) {
	            return;
	        }
	        var rank = 'rank' in options ? options.rank : 100;
	        var rankItem = { menu: menu, rank: rank };
	        var index = algorithm_1.ArrayExt.upperBound(this._items, rankItem, Private.itemCmp);
	        // Upon disposal, remove the menu and its rank reference.
	        menu.disposed.connect(this._onMenuDisposed, this);
	        algorithm_1.ArrayExt.insert(this._items, index, rankItem);
	        this.insertMenu(index, menu);
	    };
	    /**
	     * Handle the disposal of a menu.
	     */
	    MainMenu.prototype._onMenuDisposed = function (menu) {
	        this.removeMenu(menu);
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._items, function (item) { return item.menu === menu; });
	        if (index !== -1) {
	            algorithm_1.ArrayExt.removeAt(this._items, index);
	        }
	    };
	    return MainMenu;
	}(widgets_1.MenuBar));
	exports.MainMenu = MainMenu;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A comparator function for menu rank items.
	     */
	    function itemCmp(first, second) {
	        return first.rank - second.rank;
	    }
	    Private.itemCmp = itemCmp;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/mainmenu.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/sanitizer.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/sanitizer.js', function (module, exports, __jupyter_require__) {
	"use strict";
	Object.defineProperty(exports, "__esModule", { value: true });
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var sanitize = __jupyter_require__('sanitize-html@^1.14.1/index.js');
	/**
	 * A class to sanitize HTML strings.
	 */
	var Sanitizer = (function () {
	    function Sanitizer() {
	        this._options = {
	            allowedTags: sanitize.defaults.allowedTags
	                .concat('svg', 'h1', 'h2', 'img', 'span'),
	            allowedAttributes: {
	                // Allow the "rel" attribute for <a> tags.
	                'a': sanitize.defaults.allowedAttributes['a'].concat('rel'),
	                // Allow the "src" attribute for <img> tags.
	                'img': ['src', 'height', 'width', 'alt'],
	                // Allow "class" attribute for <code> tags.
	                'code': ['class'],
	                // Allow "class" attribute for <span> tags.
	                'span': ['class']
	            },
	            transformTags: {
	                // Set the "rel" attribute for <a> tags to "nofollow".
	                'a': sanitize.simpleTransform('a', { 'rel': 'nofollow' })
	            }
	        };
	    }
	    /**
	     * Sanitize an HTML string.
	     */
	    Sanitizer.prototype.sanitize = function (dirty) {
	        return sanitize(dirty, this._options);
	    };
	    return Sanitizer;
	}());
	/**
	 * The default instance of an `ISanitizer` meant for use by user code.
	 */
	exports.defaultSanitizer = new Sanitizer();
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/sanitizer.js **/


/** START DEFINE BLOCK for sanitize-html@1.14.1/index.js **/
jupyter.define('sanitize-html@1.14.1/index.js', function (module, exports, __jupyter_require__) {
	var htmlparser = __jupyter_require__('htmlparser2@^3.9.0/lib/index.js');
	var extend = __jupyter_require__('xtend@^4.0.0/immutable.js');
	var quoteRegexp = __jupyter_require__('regexp-quote@0.0.0/regexp-quote.js');
	
	function each(obj, cb) {
	  if (obj) Object.keys(obj).forEach(function (key) {
	    cb(obj[key], key);
	  });
	}
	
	// Avoid false positives with .__proto__, .hasOwnProperty, etc.
	function has(obj, key) {
	  return ({}).hasOwnProperty.call(obj, key);
	}
	
	module.exports = sanitizeHtml;
	
	// Ignore the _recursing flag; it's there for recursive
	// invocation as a guard against this exploit:
	// https://github.com/fb55/htmlparser2/issues/105
	
	function sanitizeHtml(html, options, _recursing) {
	  var result = '';
	
	  function Frame(tag, attribs) {
	    var that = this;
	    this.tag = tag;
	    this.attribs = attribs || {};
	    this.tagPosition = result.length;
	    this.text = ''; // Node inner text
	
	    this.updateParentNodeText = function() {
	      if (stack.length) {
	          var parentFrame = stack[stack.length - 1];
	          parentFrame.text += that.text;
	      }
	    };
	  }
	
	  if (!options) {
	    options = sanitizeHtml.defaults;
	    options.parser = htmlParserDefaults;
	  } else {
	    options = extend(sanitizeHtml.defaults, options);
	    if (options.parser) {
	      options.parser = extend(htmlParserDefaults, options.parser);
	    } else {
	      options.parser = htmlParserDefaults;
	    }
	  }
	
	  // Tags that contain something other than HTML, or where discarding
	  // the text when the tag is disallowed makes sense for other reasons.
	  // If we are not allowing these tags, we should drop their content too.
	  // For other tags you would drop the tag but keep its content.
	  var nonTextTagsArray = options.nonTextTags || [ 'script', 'style', 'textarea' ];
	  var allowedAttributesMap;
	  var allowedAttributesGlobMap;
	  if(options.allowedAttributes) {
	    allowedAttributesMap = {};
	    allowedAttributesGlobMap = {};
	    each(options.allowedAttributes, function(attributes, tag) {
	      allowedAttributesMap[tag] = [];
	      var globRegex = [];
	      attributes.forEach(function(name) {
	        if(name.indexOf('*') >= 0) {
	          globRegex.push(quoteRegexp(name).replace(/\\\*/g, '.*'));
	        } else {
	          allowedAttributesMap[tag].push(name);
	        }
	      });
	      allowedAttributesGlobMap[tag] = new RegExp('^(' + globRegex.join('|') + ')$');
	    });
	  }
	  var allowedClassesMap = {};
	  each(options.allowedClasses, function(classes, tag) {
	    // Implicitly allows the class attribute
	    if(allowedAttributesMap) {
	      if (!has(allowedAttributesMap, tag)) {
	        allowedAttributesMap[tag] = [];
	      }
	      allowedAttributesMap[tag].push('class');
	    }
	
	    allowedClassesMap[tag] = classes;
	  });
	
	  var transformTagsMap = {};
	  var transformTagsAll;
	  each(options.transformTags, function(transform, tag) {
	    var transFun;
	    if (typeof transform === 'function') {
	      transFun = transform;
	    } else if (typeof transform === "string") {
	      transFun = sanitizeHtml.simpleTransform(transform);
	    }
	    if (tag === '*') {
	      transformTagsAll = transFun;
	    } else {
	      transformTagsMap[tag] = transFun;
	    }
	  });
	
	  var depth = 0;
	  var stack = [];
	  var skipMap = {};
	  var transformMap = {};
	  var skipText = false;
	  var skipTextDepth = 0;
	
	  var parser = new htmlparser.Parser({
	    onopentag: function(name, attribs) {
	      if (skipText) {
	        skipTextDepth++;
	        return;
	      }
	      var frame = new Frame(name, attribs);
	      stack.push(frame);
	
	      var skip = false;
	      var hasText = frame.text ? true : false;
	      var transformedTag;
	      if (has(transformTagsMap, name)) {
	        transformedTag = transformTagsMap[name](name, attribs);
	
	        frame.attribs = attribs = transformedTag.attribs;
	
	        if (transformedTag.text !== undefined) {
	          frame.innerText = transformedTag.text;
	        }
	
	        if (name !== transformedTag.tagName) {
	          frame.name = name = transformedTag.tagName;
	          transformMap[depth] = transformedTag.tagName;
	        }
	      }
	      if (transformTagsAll) {
	        transformedTag = transformTagsAll(name, attribs);
	
	        frame.attribs = attribs = transformedTag.attribs;
	        if (name !== transformedTag.tagName) {
	          frame.name = name = transformedTag.tagName;
	          transformMap[depth] = transformedTag.tagName;
	        }
	      }
	
	      if (options.allowedTags && options.allowedTags.indexOf(name) === -1) {
	        skip = true;
	        if (nonTextTagsArray.indexOf(name) !== -1) {
	          skipText = true;
	          skipTextDepth = 1;
	        }
	        skipMap[depth] = true;
	      }
	      depth++;
	      if (skip) {
	        // We want the contents but not this tag
	        return;
	      }
	      result += '<' + name;
	      if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
	        each(attribs, function(value, a) {
	          if (!allowedAttributesMap ||
	              (has(allowedAttributesMap, name) && allowedAttributesMap[name].indexOf(a) !== -1 ) ||
	              (allowedAttributesMap['*'] && allowedAttributesMap['*'].indexOf(a) !== -1 ) ||
	              (has(allowedAttributesGlobMap, name) && allowedAttributesGlobMap[name].test(a)) ||
	              (allowedAttributesGlobMap['*'] && allowedAttributesGlobMap['*'].test(a))) {
	            if ((a === 'href') || (a === 'src')) {
	              if (naughtyHref(name, value)) {
	                delete frame.attribs[a];
	                return;
	              }
	            }
	            if (a === 'class') {
	              value = filterClasses(value, allowedClassesMap[name]);
	              if (!value.length) {
	                delete frame.attribs[a];
	                return;
	              }
	            }
	            result += ' ' + a;
	            if (value.length) {
	              result += '="' + escapeHtml(value) + '"';
	            }
	          } else {
	            delete frame.attribs[a];
	          }
	        });
	      }
	      if (options.selfClosing.indexOf(name) !== -1) {
	        result += " />";
	      } else {
	        result += ">";
	        if (frame.innerText && !hasText && !options.textFilter) {
	          result += frame.innerText;
	        }
	      }
	    },
	    ontext: function(text) {
	      if (skipText) {
	        return;
	      }
	      var lastFrame = stack[stack.length-1];
	      var tag;
	
	      if (lastFrame) {
	        tag = lastFrame.tag;
	        // If inner text was set by transform function then let's use it
	        text = lastFrame.innerText !== undefined ? lastFrame.innerText : text;
	      }
	
	      if ((tag === 'script') || (tag === 'style')) {
	        // htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing
	        // script tags is, by definition, game over for XSS protection, so if that's
	        // your concern, don't allow them. The same is essentially true for style tags
	        // which have their own collection of XSS vectors.
	        result += text;
	      } else {
	        var escaped = escapeHtml(text);
	        if (options.textFilter) {
	          result += options.textFilter(escaped);
	        } else {
	          result += escaped;
	        }
	      }
	      if (stack.length) {
	           var frame = stack[stack.length - 1];
	           frame.text += text;
	      }
	    },
	    onclosetag: function(name) {
	
	      if (skipText) {
	        skipTextDepth--;
	        if (!skipTextDepth) {
	          skipText = false;
	        } else {
	          return;
	        }
	      }
	
	      var frame = stack.pop();
	      if (!frame) {
	        // Do not crash on bad markup
	        return;
	      }
	      skipText = false;
	      depth--;
	      if (skipMap[depth]) {
	        delete skipMap[depth];
	        frame.updateParentNodeText();
	        return;
	      }
	
	      if (transformMap[depth]) {
	        name = transformMap[depth];
	        delete transformMap[depth];
	      }
	
	      if (options.exclusiveFilter && options.exclusiveFilter(frame)) {
	         result = result.substr(0, frame.tagPosition);
	         return;
	      }
	
	      frame.updateParentNodeText();
	
	      if (options.selfClosing.indexOf(name) !== -1) {
	         // Already output />
	         return;
	      }
	
	      result += "</" + name + ">";
	    }
	  }, options.parser);
	  parser.write(html);
	  parser.end();
	
	  return result;
	
	  function escapeHtml(s) {
	    if (typeof(s) !== 'string') {
	      s = s + '';
	    }
	    return s.replace(/\&/g, '&amp;').replace(/</g, '&lt;').replace(/\>/g, '&gt;').replace(/\"/g, '&quot;');
	  }
	
	  function naughtyHref(name, href) {
	    // Browsers ignore character codes of 32 (space) and below in a surprising
	    // number of situations. Start reading here:
	    // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_tab
	    href = href.replace(/[\x00-\x20]+/g, '');
	    // Clobber any comments in URLs, which the browser might
	    // interpret inside an XML data island, allowing
	    // a javascript: URL to be snuck through
	    href = href.replace(/<\!\-\-.*?\-\-\>/g, '');
	    // Case insensitive so we don't get faked out by JAVASCRIPT #1
	    var matches = href.match(/^([a-zA-Z]+)\:/);
	    if (!matches) {
	      // Protocol-relative URL: "//some.evil.com/nasty"
	      if (href.match(/^\/\//)) {
	        return !options.allowProtocolRelative;
	      }
	
	      // No scheme
	      return false;
	    }
	    var scheme = matches[1].toLowerCase();
	
	    if (has(options.allowedSchemesByTag, name)) {
	      return options.allowedSchemesByTag[name].indexOf(scheme) === -1;
	    }
	
	    return !options.allowedSchemes || options.allowedSchemes.indexOf(scheme) === -1;
	  }
	
	  function filterClasses(classes, allowed) {
	    if (!allowed) {
	      // The class attribute is allowed without filtering on this tag
	      return classes;
	    }
	    classes = classes.split(/\s+/);
	    return classes.filter(function(clss) {
	      return allowed.indexOf(clss) !== -1;
	    }).join(' ');
	  }
	}
	
	// Defaults are accessible to you so that you can use them as a starting point
	// programmatically if you wish
	
	var htmlParserDefaults = {
	  decodeEntities: true
	};
	sanitizeHtml.defaults = {
	  allowedTags: [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
	    'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
	    'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre' ],
	  allowedAttributes: {
	    a: [ 'href', 'name', 'target' ],
	    // We don't currently allow img itself by default, but this
	    // would make sense if we did
	    img: [ 'src' ]
	  },
	  // Lots of these won't come up by default because we don't allow them
	  selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],
	  // URL schemes we permit
	  allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
	  allowedSchemesByTag: {},
	  allowProtocolRelative: true
	};
	
	sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) {
	  merge = (merge === undefined) ? true : merge;
	  newAttribs = newAttribs || {};
	
	  return function(tagName, attribs) {
	    var attrib;
	    if (merge) {
	      for (attrib in newAttribs) {
	        attribs[attrib] = newAttribs[attrib];
	      }
	    } else {
	      attribs = newAttribs;
	    }
	
	    return {
	      tagName: newTagName,
	      attribs: attribs
	    };
	  };
	};
	
})
/** END DEFINE BLOCK for sanitize-html@1.14.1/index.js **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/index.js **/
jupyter.define('htmlparser2@3.9.2/lib/index.js', function (module, exports, __jupyter_require__) {
	var Parser = __jupyter_require__('htmlparser2@3.9.2/lib/Parser.js'),
	    DomHandler = __jupyter_require__('domhandler@^2.3.0/index.js');
	
	function defineProp(name, value){
		delete module.exports[name];
		module.exports[name] = value;
		return value;
	}
	
	module.exports = {
		Parser: Parser,
		Tokenizer: __jupyter_require__('htmlparser2@3.9.2/lib/Tokenizer.js'),
		ElementType: __jupyter_require__('domelementtype@^1.3.0/index.js'),
		DomHandler: DomHandler,
		get FeedHandler(){
			return defineProp("FeedHandler", __jupyter_require__('htmlparser2@3.9.2/lib/FeedHandler.js'));
		},
		get Stream(){
			return defineProp("Stream", __jupyter_require__('htmlparser2@3.9.2/lib/Stream.js'));
		},
		get WritableStream(){
			return defineProp("WritableStream", __jupyter_require__('htmlparser2@3.9.2/lib/WritableStream.js'));
		},
		get ProxyHandler(){
			return defineProp("ProxyHandler", __jupyter_require__('htmlparser2@3.9.2/lib/ProxyHandler.js'));
		},
		get DomUtils(){
			return defineProp("DomUtils", __jupyter_require__('domutils@^1.5.1/index.js'));
		},
		get CollectingHandler(){
			return defineProp("CollectingHandler", __jupyter_require__('htmlparser2@3.9.2/lib/CollectingHandler.js'));
		},
		// For legacy support
		DefaultHandler: DomHandler,
		get RssHandler(){
			return defineProp("RssHandler", this.FeedHandler);
		},
		//helper methods
		parseDOM: function(data, options){
			var handler = new DomHandler(options);
			new Parser(handler, options).end(data);
			return handler.dom;
		},
		parseFeed: function(feed, options){
			var handler = new module.exports.FeedHandler(options);
			new Parser(handler, options).end(feed);
			return handler.dom;
		},
		createDomStream: function(cb, options, elementCb){
			var handler = new DomHandler(cb, options, elementCb);
			return new Parser(handler, options);
		},
		// List of all events that the parser emits
		EVENTS: { /* Format: eventname: number of arguments */
			attribute: 2,
			cdatastart: 0,
			cdataend: 0,
			text: 1,
			processinginstruction: 2,
			comment: 1,
			commentend: 0,
			closetag: 1,
			opentag: 2,
			opentagname: 1,
			error: 1,
			end: 0
		}
	};
	
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/index.js **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/Parser.js **/
jupyter.define('htmlparser2@3.9.2/lib/Parser.js', function (module, exports, __jupyter_require__) {
	var Tokenizer = __jupyter_require__('htmlparser2@3.9.2/lib/Tokenizer.js');
	
	/*
		Options:
	
		xmlMode: Disables the special behavior for script/style tags (false by default)
		lowerCaseAttributeNames: call .toLowerCase for each attribute name (true if xmlMode is `false`)
		lowerCaseTags: call .toLowerCase for each tag name (true if xmlMode is `false`)
	*/
	
	/*
		Callbacks:
	
		oncdataend,
		oncdatastart,
		onclosetag,
		oncomment,
		oncommentend,
		onerror,
		onopentag,
		onprocessinginstruction,
		onreset,
		ontext
	*/
	
	var formTags = {
		input: true,
		option: true,
		optgroup: true,
		select: true,
		button: true,
		datalist: true,
		textarea: true
	};
	
	var openImpliesClose = {
		tr      : { tr:true, th:true, td:true },
		th      : { th:true },
		td      : { thead:true, th:true, td:true },
		body    : { head:true, link:true, script:true },
		li      : { li:true },
		p       : { p:true },
		h1      : { p:true },
		h2      : { p:true },
		h3      : { p:true },
		h4      : { p:true },
		h5      : { p:true },
		h6      : { p:true },
		select  : formTags,
		input   : formTags,
		output  : formTags,
		button  : formTags,
		datalist: formTags,
		textarea: formTags,
		option  : { option:true },
		optgroup: { optgroup:true }
	};
	
	var voidElements = {
		__proto__: null,
		area: true,
		base: true,
		basefont: true,
		br: true,
		col: true,
		command: true,
		embed: true,
		frame: true,
		hr: true,
		img: true,
		input: true,
		isindex: true,
		keygen: true,
		link: true,
		meta: true,
		param: true,
		source: true,
		track: true,
		wbr: true,
	
		//common self closing svg elements
		path: true,
		circle: true,
		ellipse: true,
		line: true,
		rect: true,
		use: true,
		stop: true,
		polyline: true,
		polygon: true
	};
	
	var re_nameEnd = /\s|\//;
	
	function Parser(cbs, options){
		this._options = options || {};
		this._cbs = cbs || {};
	
		this._tagname = "";
		this._attribname = "";
		this._attribvalue = "";
		this._attribs = null;
		this._stack = [];
	
		this.startIndex = 0;
		this.endIndex = null;
	
		this._lowerCaseTagNames = "lowerCaseTags" in this._options ?
										!!this._options.lowerCaseTags :
										!this._options.xmlMode;
		this._lowerCaseAttributeNames = "lowerCaseAttributeNames" in this._options ?
										!!this._options.lowerCaseAttributeNames :
										!this._options.xmlMode;
	
		if(this._options.Tokenizer) {
			Tokenizer = this._options.Tokenizer;
		}
		this._tokenizer = new Tokenizer(this._options, this);
	
		if(this._cbs.onparserinit) this._cbs.onparserinit(this);
	}
	
	__jupyter_require__('inherits@^2.0.1/inherits_browser.js')(Parser, __jupyter_require__('events@1.1.1/events.js').EventEmitter);
	
	Parser.prototype._updatePosition = function(initialOffset){
		if(this.endIndex === null){
			if(this._tokenizer._sectionStart <= initialOffset){
				this.startIndex = 0;
			} else {
				this.startIndex = this._tokenizer._sectionStart - initialOffset;
			}
		}
		else this.startIndex = this.endIndex + 1;
		this.endIndex = this._tokenizer.getAbsoluteIndex();
	};
	
	//Tokenizer event handlers
	Parser.prototype.ontext = function(data){
		this._updatePosition(1);
		this.endIndex--;
	
		if(this._cbs.ontext) this._cbs.ontext(data);
	};
	
	Parser.prototype.onopentagname = function(name){
		if(this._lowerCaseTagNames){
			name = name.toLowerCase();
		}
	
		this._tagname = name;
	
		if(!this._options.xmlMode && name in openImpliesClose) {
			for(
				var el;
				(el = this._stack[this._stack.length - 1]) in openImpliesClose[name];
				this.onclosetag(el)
			);
		}
	
		if(this._options.xmlMode || !(name in voidElements)){
			this._stack.push(name);
		}
	
		if(this._cbs.onopentagname) this._cbs.onopentagname(name);
		if(this._cbs.onopentag) this._attribs = {};
	};
	
	Parser.prototype.onopentagend = function(){
		this._updatePosition(1);
	
		if(this._attribs){
			if(this._cbs.onopentag) this._cbs.onopentag(this._tagname, this._attribs);
			this._attribs = null;
		}
	
		if(!this._options.xmlMode && this._cbs.onclosetag && this._tagname in voidElements){
			this._cbs.onclosetag(this._tagname);
		}
	
		this._tagname = "";
	};
	
	Parser.prototype.onclosetag = function(name){
		this._updatePosition(1);
	
		if(this._lowerCaseTagNames){
			name = name.toLowerCase();
		}
	
		if(this._stack.length && (!(name in voidElements) || this._options.xmlMode)){
			var pos = this._stack.lastIndexOf(name);
			if(pos !== -1){
				if(this._cbs.onclosetag){
					pos = this._stack.length - pos;
					while(pos--) this._cbs.onclosetag(this._stack.pop());
				}
				else this._stack.length = pos;
			} else if(name === "p" && !this._options.xmlMode){
				this.onopentagname(name);
				this._closeCurrentTag();
			}
		} else if(!this._options.xmlMode && (name === "br" || name === "p")){
			this.onopentagname(name);
			this._closeCurrentTag();
		}
	};
	
	Parser.prototype.onselfclosingtag = function(){
		if(this._options.xmlMode || this._options.recognizeSelfClosing){
			this._closeCurrentTag();
		} else {
			this.onopentagend();
		}
	};
	
	Parser.prototype._closeCurrentTag = function(){
		var name = this._tagname;
	
		this.onopentagend();
	
		//self-closing tags will be on the top of the stack
		//(cheaper check than in onclosetag)
		if(this._stack[this._stack.length - 1] === name){
			if(this._cbs.onclosetag){
				this._cbs.onclosetag(name);
			}
			this._stack.pop();
		}
	};
	
	Parser.prototype.onattribname = function(name){
		if(this._lowerCaseAttributeNames){
			name = name.toLowerCase();
		}
		this._attribname = name;
	};
	
	Parser.prototype.onattribdata = function(value){
		this._attribvalue += value;
	};
	
	Parser.prototype.onattribend = function(){
		if(this._cbs.onattribute) this._cbs.onattribute(this._attribname, this._attribvalue);
		if(
			this._attribs &&
			!Object.prototype.hasOwnProperty.call(this._attribs, this._attribname)
		){
			this._attribs[this._attribname] = this._attribvalue;
		}
		this._attribname = "";
		this._attribvalue = "";
	};
	
	Parser.prototype._getInstructionName = function(value){
		var idx = value.search(re_nameEnd),
		    name = idx < 0 ? value : value.substr(0, idx);
	
		if(this._lowerCaseTagNames){
			name = name.toLowerCase();
		}
	
		return name;
	};
	
	Parser.prototype.ondeclaration = function(value){
		if(this._cbs.onprocessinginstruction){
			var name = this._getInstructionName(value);
			this._cbs.onprocessinginstruction("!" + name, "!" + value);
		}
	};
	
	Parser.prototype.onprocessinginstruction = function(value){
		if(this._cbs.onprocessinginstruction){
			var name = this._getInstructionName(value);
			this._cbs.onprocessinginstruction("?" + name, "?" + value);
		}
	};
	
	Parser.prototype.oncomment = function(value){
		this._updatePosition(4);
	
		if(this._cbs.oncomment) this._cbs.oncomment(value);
		if(this._cbs.oncommentend) this._cbs.oncommentend();
	};
	
	Parser.prototype.oncdata = function(value){
		this._updatePosition(1);
	
		if(this._options.xmlMode || this._options.recognizeCDATA){
			if(this._cbs.oncdatastart) this._cbs.oncdatastart();
			if(this._cbs.ontext) this._cbs.ontext(value);
			if(this._cbs.oncdataend) this._cbs.oncdataend();
		} else {
			this.oncomment("[CDATA[" + value + "]]");
		}
	};
	
	Parser.prototype.onerror = function(err){
		if(this._cbs.onerror) this._cbs.onerror(err);
	};
	
	Parser.prototype.onend = function(){
		if(this._cbs.onclosetag){
			for(
				var i = this._stack.length;
				i > 0;
				this._cbs.onclosetag(this._stack[--i])
			);
		}
		if(this._cbs.onend) this._cbs.onend();
	};
	
	
	//Resets the parser to a blank state, ready to parse a new HTML document
	Parser.prototype.reset = function(){
		if(this._cbs.onreset) this._cbs.onreset();
		this._tokenizer.reset();
	
		this._tagname = "";
		this._attribname = "";
		this._attribs = null;
		this._stack = [];
	
		if(this._cbs.onparserinit) this._cbs.onparserinit(this);
	};
	
	//Parses a complete HTML document and pushes it to the handler
	Parser.prototype.parseComplete = function(data){
		this.reset();
		this.end(data);
	};
	
	Parser.prototype.write = function(chunk){
		this._tokenizer.write(chunk);
	};
	
	Parser.prototype.end = function(chunk){
		this._tokenizer.end(chunk);
	};
	
	Parser.prototype.pause = function(){
		this._tokenizer.pause();
	};
	
	Parser.prototype.resume = function(){
		this._tokenizer.resume();
	};
	
	//alias for backwards compat
	Parser.prototype.parseChunk = Parser.prototype.write;
	Parser.prototype.done = Parser.prototype.end;
	
	module.exports = Parser;
	
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/Parser.js **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/Tokenizer.js **/
jupyter.define('htmlparser2@3.9.2/lib/Tokenizer.js', function (module, exports, __jupyter_require__) {
	module.exports = Tokenizer;
	
	var decodeCodePoint = __jupyter_require__('entities@^1.1.1/lib/decode_codepoint.js'),
	    entityMap = __jupyter_require__('entities@^1.1.1/maps/entities.json'),
	    legacyMap = __jupyter_require__('entities@^1.1.1/maps/legacy.json'),
	    xmlMap    = __jupyter_require__('entities@^1.1.1/maps/xml.json'),
	
	    i = 0,
	
	    TEXT                      = i++,
	    BEFORE_TAG_NAME           = i++, //after <
	    IN_TAG_NAME               = i++,
	    IN_SELF_CLOSING_TAG       = i++,
	    BEFORE_CLOSING_TAG_NAME   = i++,
	    IN_CLOSING_TAG_NAME       = i++,
	    AFTER_CLOSING_TAG_NAME    = i++,
	
	    //attributes
	    BEFORE_ATTRIBUTE_NAME     = i++,
	    IN_ATTRIBUTE_NAME         = i++,
	    AFTER_ATTRIBUTE_NAME      = i++,
	    BEFORE_ATTRIBUTE_VALUE    = i++,
	    IN_ATTRIBUTE_VALUE_DQ     = i++, // "
	    IN_ATTRIBUTE_VALUE_SQ     = i++, // '
	    IN_ATTRIBUTE_VALUE_NQ     = i++,
	
	    //declarations
	    BEFORE_DECLARATION        = i++, // !
	    IN_DECLARATION            = i++,
	
	    //processing instructions
	    IN_PROCESSING_INSTRUCTION = i++, // ?
	
	    //comments
	    BEFORE_COMMENT            = i++,
	    IN_COMMENT                = i++,
	    AFTER_COMMENT_1           = i++,
	    AFTER_COMMENT_2           = i++,
	
	    //cdata
	    BEFORE_CDATA_1            = i++, // [
	    BEFORE_CDATA_2            = i++, // C
	    BEFORE_CDATA_3            = i++, // D
	    BEFORE_CDATA_4            = i++, // A
	    BEFORE_CDATA_5            = i++, // T
	    BEFORE_CDATA_6            = i++, // A
	    IN_CDATA                  = i++, // [
	    AFTER_CDATA_1             = i++, // ]
	    AFTER_CDATA_2             = i++, // ]
	
	    //special tags
	    BEFORE_SPECIAL            = i++, //S
	    BEFORE_SPECIAL_END        = i++,   //S
	
	    BEFORE_SCRIPT_1           = i++, //C
	    BEFORE_SCRIPT_2           = i++, //R
	    BEFORE_SCRIPT_3           = i++, //I
	    BEFORE_SCRIPT_4           = i++, //P
	    BEFORE_SCRIPT_5           = i++, //T
	    AFTER_SCRIPT_1            = i++, //C
	    AFTER_SCRIPT_2            = i++, //R
	    AFTER_SCRIPT_3            = i++, //I
	    AFTER_SCRIPT_4            = i++, //P
	    AFTER_SCRIPT_5            = i++, //T
	
	    BEFORE_STYLE_1            = i++, //T
	    BEFORE_STYLE_2            = i++, //Y
	    BEFORE_STYLE_3            = i++, //L
	    BEFORE_STYLE_4            = i++, //E
	    AFTER_STYLE_1             = i++, //T
	    AFTER_STYLE_2             = i++, //Y
	    AFTER_STYLE_3             = i++, //L
	    AFTER_STYLE_4             = i++, //E
	
	    BEFORE_ENTITY             = i++, //&
	    BEFORE_NUMERIC_ENTITY     = i++, //#
	    IN_NAMED_ENTITY           = i++,
	    IN_NUMERIC_ENTITY         = i++,
	    IN_HEX_ENTITY             = i++, //X
	
	    j = 0,
	
	    SPECIAL_NONE              = j++,
	    SPECIAL_SCRIPT            = j++,
	    SPECIAL_STYLE             = j++;
	
	function whitespace(c){
		return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
	}
	
	function characterState(char, SUCCESS){
		return function(c){
			if(c === char) this._state = SUCCESS;
		};
	}
	
	function ifElseState(upper, SUCCESS, FAILURE){
		var lower = upper.toLowerCase();
	
		if(upper === lower){
			return function(c){
				if(c === lower){
					this._state = SUCCESS;
				} else {
					this._state = FAILURE;
					this._index--;
				}
			};
		} else {
			return function(c){
				if(c === lower || c === upper){
					this._state = SUCCESS;
				} else {
					this._state = FAILURE;
					this._index--;
				}
			};
		}
	}
	
	function consumeSpecialNameChar(upper, NEXT_STATE){
		var lower = upper.toLowerCase();
	
		return function(c){
			if(c === lower || c === upper){
				this._state = NEXT_STATE;
			} else {
				this._state = IN_TAG_NAME;
				this._index--; //consume the token again
			}
		};
	}
	
	function Tokenizer(options, cbs){
		this._state = TEXT;
		this._buffer = "";
		this._sectionStart = 0;
		this._index = 0;
		this._bufferOffset = 0; //chars removed from _buffer
		this._baseState = TEXT;
		this._special = SPECIAL_NONE;
		this._cbs = cbs;
		this._running = true;
		this._ended = false;
		this._xmlMode = !!(options && options.xmlMode);
		this._decodeEntities = !!(options && options.decodeEntities);
	}
	
	Tokenizer.prototype._stateText = function(c){
		if(c === "<"){
			if(this._index > this._sectionStart){
				this._cbs.ontext(this._getSection());
			}
			this._state = BEFORE_TAG_NAME;
			this._sectionStart = this._index;
		} else if(this._decodeEntities && this._special === SPECIAL_NONE && c === "&"){
			if(this._index > this._sectionStart){
				this._cbs.ontext(this._getSection());
			}
			this._baseState = TEXT;
			this._state = BEFORE_ENTITY;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateBeforeTagName = function(c){
		if(c === "/"){
			this._state = BEFORE_CLOSING_TAG_NAME;
		} else if(c === "<"){
			this._cbs.ontext(this._getSection());
			this._sectionStart = this._index;
		} else if(c === ">" || this._special !== SPECIAL_NONE || whitespace(c)) {
			this._state = TEXT;
		} else if(c === "!"){
			this._state = BEFORE_DECLARATION;
			this._sectionStart = this._index + 1;
		} else if(c === "?"){
			this._state = IN_PROCESSING_INSTRUCTION;
			this._sectionStart = this._index + 1;
		} else {
			this._state = (!this._xmlMode && (c === "s" || c === "S")) ?
							BEFORE_SPECIAL : IN_TAG_NAME;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateInTagName = function(c){
		if(c === "/" || c === ">" || whitespace(c)){
			this._emitToken("onopentagname");
			this._state = BEFORE_ATTRIBUTE_NAME;
			this._index--;
		}
	};
	
	Tokenizer.prototype._stateBeforeCloseingTagName = function(c){
		if(whitespace(c));
		else if(c === ">"){
			this._state = TEXT;
		} else if(this._special !== SPECIAL_NONE){
			if(c === "s" || c === "S"){
				this._state = BEFORE_SPECIAL_END;
			} else {
				this._state = TEXT;
				this._index--;
			}
		} else {
			this._state = IN_CLOSING_TAG_NAME;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateInCloseingTagName = function(c){
		if(c === ">" || whitespace(c)){
			this._emitToken("onclosetag");
			this._state = AFTER_CLOSING_TAG_NAME;
			this._index--;
		}
	};
	
	Tokenizer.prototype._stateAfterCloseingTagName = function(c){
		//skip everything until ">"
		if(c === ">"){
			this._state = TEXT;
			this._sectionStart = this._index + 1;
		}
	};
	
	Tokenizer.prototype._stateBeforeAttributeName = function(c){
		if(c === ">"){
			this._cbs.onopentagend();
			this._state = TEXT;
			this._sectionStart = this._index + 1;
		} else if(c === "/"){
			this._state = IN_SELF_CLOSING_TAG;
		} else if(!whitespace(c)){
			this._state = IN_ATTRIBUTE_NAME;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateInSelfClosingTag = function(c){
		if(c === ">"){
			this._cbs.onselfclosingtag();
			this._state = TEXT;
			this._sectionStart = this._index + 1;
		} else if(!whitespace(c)){
			this._state = BEFORE_ATTRIBUTE_NAME;
			this._index--;
		}
	};
	
	Tokenizer.prototype._stateInAttributeName = function(c){
		if(c === "=" || c === "/" || c === ">" || whitespace(c)){
			this._cbs.onattribname(this._getSection());
			this._sectionStart = -1;
			this._state = AFTER_ATTRIBUTE_NAME;
			this._index--;
		}
	};
	
	Tokenizer.prototype._stateAfterAttributeName = function(c){
		if(c === "="){
			this._state = BEFORE_ATTRIBUTE_VALUE;
		} else if(c === "/" || c === ">"){
			this._cbs.onattribend();
			this._state = BEFORE_ATTRIBUTE_NAME;
			this._index--;
		} else if(!whitespace(c)){
			this._cbs.onattribend();
			this._state = IN_ATTRIBUTE_NAME;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateBeforeAttributeValue = function(c){
		if(c === "\""){
			this._state = IN_ATTRIBUTE_VALUE_DQ;
			this._sectionStart = this._index + 1;
		} else if(c === "'"){
			this._state = IN_ATTRIBUTE_VALUE_SQ;
			this._sectionStart = this._index + 1;
		} else if(!whitespace(c)){
			this._state = IN_ATTRIBUTE_VALUE_NQ;
			this._sectionStart = this._index;
			this._index--; //reconsume token
		}
	};
	
	Tokenizer.prototype._stateInAttributeValueDoubleQuotes = function(c){
		if(c === "\""){
			this._emitToken("onattribdata");
			this._cbs.onattribend();
			this._state = BEFORE_ATTRIBUTE_NAME;
		} else if(this._decodeEntities && c === "&"){
			this._emitToken("onattribdata");
			this._baseState = this._state;
			this._state = BEFORE_ENTITY;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateInAttributeValueSingleQuotes = function(c){
		if(c === "'"){
			this._emitToken("onattribdata");
			this._cbs.onattribend();
			this._state = BEFORE_ATTRIBUTE_NAME;
		} else if(this._decodeEntities && c === "&"){
			this._emitToken("onattribdata");
			this._baseState = this._state;
			this._state = BEFORE_ENTITY;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateInAttributeValueNoQuotes = function(c){
		if(whitespace(c) || c === ">"){
			this._emitToken("onattribdata");
			this._cbs.onattribend();
			this._state = BEFORE_ATTRIBUTE_NAME;
			this._index--;
		} else if(this._decodeEntities && c === "&"){
			this._emitToken("onattribdata");
			this._baseState = this._state;
			this._state = BEFORE_ENTITY;
			this._sectionStart = this._index;
		}
	};
	
	Tokenizer.prototype._stateBeforeDeclaration = function(c){
		this._state = c === "[" ? BEFORE_CDATA_1 :
						c === "-" ? BEFORE_COMMENT :
							IN_DECLARATION;
	};
	
	Tokenizer.prototype._stateInDeclaration = function(c){
		if(c === ">"){
			this._cbs.ondeclaration(this._getSection());
			this._state = TEXT;
			this._sectionStart = this._index + 1;
		}
	};
	
	Tokenizer.prototype._stateInProcessingInstruction = function(c){
		if(c === ">"){
			this._cbs.onprocessinginstruction(this._getSection());
			this._state = TEXT;
			this._sectionStart = this._index + 1;
		}
	};
	
	Tokenizer.prototype._stateBeforeComment = function(c){
		if(c === "-"){
			this._state = IN_COMMENT;
			this._sectionStart = this._index + 1;
		} else {
			this._state = IN_DECLARATION;
		}
	};
	
	Tokenizer.prototype._stateInComment = function(c){
		if(c === "-") this._state = AFTER_COMMENT_1;
	};
	
	Tokenizer.prototype._stateAfterComment1 = function(c){
		if(c === "-"){
			this._state = AFTER_COMMENT_2;
		} else {
			this._state = IN_COMMENT;
		}
	};
	
	Tokenizer.prototype._stateAfterComment2 = function(c){
		if(c === ">"){
			//remove 2 trailing chars
			this._cbs.oncomment(this._buffer.substring(this._sectionStart, this._index - 2));
			this._state = TEXT;
			this._sectionStart = this._index + 1;
		} else if(c !== "-"){
			this._state = IN_COMMENT;
		}
		// else: stay in AFTER_COMMENT_2 (`--->`)
	};
	
	Tokenizer.prototype._stateBeforeCdata1 = ifElseState("C", BEFORE_CDATA_2, IN_DECLARATION);
	Tokenizer.prototype._stateBeforeCdata2 = ifElseState("D", BEFORE_CDATA_3, IN_DECLARATION);
	Tokenizer.prototype._stateBeforeCdata3 = ifElseState("A", BEFORE_CDATA_4, IN_DECLARATION);
	Tokenizer.prototype._stateBeforeCdata4 = ifElseState("T", BEFORE_CDATA_5, IN_DECLARATION);
	Tokenizer.prototype._stateBeforeCdata5 = ifElseState("A", BEFORE_CDATA_6, IN_DECLARATION);
	
	Tokenizer.prototype._stateBeforeCdata6 = function(c){
		if(c === "["){
			this._state = IN_CDATA;
			this._sectionStart = this._index + 1;
		} else {
			this._state = IN_DECLARATION;
			this._index--;
		}
	};
	
	Tokenizer.prototype._stateInCdata = function(c){
		if(c === "]") this._state = AFTER_CDATA_1;
	};
	
	Tokenizer.prototype._stateAfterCdata1 = characterState("]", AFTER_CDATA_2);
	
	Tokenizer.prototype._stateAfterCdata2 = function(c){
		if(c === ">"){
			//remove 2 trailing chars
			this._cbs.oncdata(this._buffer.substring(this._sectionStart, this._index - 2));
			this._state = TEXT;
			this._sectionStart = this._index + 1;
		} else if(c !== "]") {
			this._state = IN_CDATA;
		}
		//else: stay in AFTER_CDATA_2 (`]]]>`)
	};
	
	Tokenizer.prototype._stateBeforeSpecial = function(c){
		if(c === "c" || c === "C"){
			this._state = BEFORE_SCRIPT_1;
		} else if(c === "t" || c === "T"){
			this._state = BEFORE_STYLE_1;
		} else {
			this._state = IN_TAG_NAME;
			this._index--; //consume the token again
		}
	};
	
	Tokenizer.prototype._stateBeforeSpecialEnd = function(c){
		if(this._special === SPECIAL_SCRIPT && (c === "c" || c === "C")){
			this._state = AFTER_SCRIPT_1;
		} else if(this._special === SPECIAL_STYLE && (c === "t" || c === "T")){
			this._state = AFTER_STYLE_1;
		}
		else this._state = TEXT;
	};
	
	Tokenizer.prototype._stateBeforeScript1 = consumeSpecialNameChar("R", BEFORE_SCRIPT_2);
	Tokenizer.prototype._stateBeforeScript2 = consumeSpecialNameChar("I", BEFORE_SCRIPT_3);
	Tokenizer.prototype._stateBeforeScript3 = consumeSpecialNameChar("P", BEFORE_SCRIPT_4);
	Tokenizer.prototype._stateBeforeScript4 = consumeSpecialNameChar("T", BEFORE_SCRIPT_5);
	
	Tokenizer.prototype._stateBeforeScript5 = function(c){
		if(c === "/" || c === ">" || whitespace(c)){
			this._special = SPECIAL_SCRIPT;
		}
		this._state = IN_TAG_NAME;
		this._index--; //consume the token again
	};
	
	Tokenizer.prototype._stateAfterScript1 = ifElseState("R", AFTER_SCRIPT_2, TEXT);
	Tokenizer.prototype._stateAfterScript2 = ifElseState("I", AFTER_SCRIPT_3, TEXT);
	Tokenizer.prototype._stateAfterScript3 = ifElseState("P", AFTER_SCRIPT_4, TEXT);
	Tokenizer.prototype._stateAfterScript4 = ifElseState("T", AFTER_SCRIPT_5, TEXT);
	
	Tokenizer.prototype._stateAfterScript5 = function(c){
		if(c === ">" || whitespace(c)){
			this._special = SPECIAL_NONE;
			this._state = IN_CLOSING_TAG_NAME;
			this._sectionStart = this._index - 6;
			this._index--; //reconsume the token
		}
		else this._state = TEXT;
	};
	
	Tokenizer.prototype._stateBeforeStyle1 = consumeSpecialNameChar("Y", BEFORE_STYLE_2);
	Tokenizer.prototype._stateBeforeStyle2 = consumeSpecialNameChar("L", BEFORE_STYLE_3);
	Tokenizer.prototype._stateBeforeStyle3 = consumeSpecialNameChar("E", BEFORE_STYLE_4);
	
	Tokenizer.prototype._stateBeforeStyle4 = function(c){
		if(c === "/" || c === ">" || whitespace(c)){
			this._special = SPECIAL_STYLE;
		}
		this._state = IN_TAG_NAME;
		this._index--; //consume the token again
	};
	
	Tokenizer.prototype._stateAfterStyle1 = ifElseState("Y", AFTER_STYLE_2, TEXT);
	Tokenizer.prototype._stateAfterStyle2 = ifElseState("L", AFTER_STYLE_3, TEXT);
	Tokenizer.prototype._stateAfterStyle3 = ifElseState("E", AFTER_STYLE_4, TEXT);
	
	Tokenizer.prototype._stateAfterStyle4 = function(c){
		if(c === ">" || whitespace(c)){
			this._special = SPECIAL_NONE;
			this._state = IN_CLOSING_TAG_NAME;
			this._sectionStart = this._index - 5;
			this._index--; //reconsume the token
		}
		else this._state = TEXT;
	};
	
	Tokenizer.prototype._stateBeforeEntity = ifElseState("#", BEFORE_NUMERIC_ENTITY, IN_NAMED_ENTITY);
	Tokenizer.prototype._stateBeforeNumericEntity = ifElseState("X", IN_HEX_ENTITY, IN_NUMERIC_ENTITY);
	
	//for entities terminated with a semicolon
	Tokenizer.prototype._parseNamedEntityStrict = function(){
		//offset = 1
		if(this._sectionStart + 1 < this._index){
			var entity = this._buffer.substring(this._sectionStart + 1, this._index),
			    map = this._xmlMode ? xmlMap : entityMap;
	
			if(map.hasOwnProperty(entity)){
				this._emitPartial(map[entity]);
				this._sectionStart = this._index + 1;
			}
		}
	};
	
	
	//parses legacy entities (without trailing semicolon)
	Tokenizer.prototype._parseLegacyEntity = function(){
		var start = this._sectionStart + 1,
		    limit = this._index - start;
	
		if(limit > 6) limit = 6; //the max length of legacy entities is 6
	
		while(limit >= 2){ //the min length of legacy entities is 2
			var entity = this._buffer.substr(start, limit);
	
			if(legacyMap.hasOwnProperty(entity)){
				this._emitPartial(legacyMap[entity]);
				this._sectionStart += limit + 1;
				return;
			} else {
				limit--;
			}
		}
	};
	
	Tokenizer.prototype._stateInNamedEntity = function(c){
		if(c === ";"){
			this._parseNamedEntityStrict();
			if(this._sectionStart + 1 < this._index && !this._xmlMode){
				this._parseLegacyEntity();
			}
			this._state = this._baseState;
		} else if((c < "a" || c > "z") && (c < "A" || c > "Z") && (c < "0" || c > "9")){
			if(this._xmlMode);
			else if(this._sectionStart + 1 === this._index);
			else if(this._baseState !== TEXT){
				if(c !== "="){
					this._parseNamedEntityStrict();
				}
			} else {
				this._parseLegacyEntity();
			}
	
			this._state = this._baseState;
			this._index--;
		}
	};
	
	Tokenizer.prototype._decodeNumericEntity = function(offset, base){
		var sectionStart = this._sectionStart + offset;
	
		if(sectionStart !== this._index){
			//parse entity
			var entity = this._buffer.substring(sectionStart, this._index);
			var parsed = parseInt(entity, base);
	
			this._emitPartial(decodeCodePoint(parsed));
			this._sectionStart = this._index;
		} else {
			this._sectionStart--;
		}
	
		this._state = this._baseState;
	};
	
	Tokenizer.prototype._stateInNumericEntity = function(c){
		if(c === ";"){
			this._decodeNumericEntity(2, 10);
			this._sectionStart++;
		} else if(c < "0" || c > "9"){
			if(!this._xmlMode){
				this._decodeNumericEntity(2, 10);
			} else {
				this._state = this._baseState;
			}
			this._index--;
		}
	};
	
	Tokenizer.prototype._stateInHexEntity = function(c){
		if(c === ";"){
			this._decodeNumericEntity(3, 16);
			this._sectionStart++;
		} else if((c < "a" || c > "f") && (c < "A" || c > "F") && (c < "0" || c > "9")){
			if(!this._xmlMode){
				this._decodeNumericEntity(3, 16);
			} else {
				this._state = this._baseState;
			}
			this._index--;
		}
	};
	
	Tokenizer.prototype._cleanup = function (){
		if(this._sectionStart < 0){
			this._buffer = "";
			this._bufferOffset += this._index;
			this._index = 0;
		} else if(this._running){
			if(this._state === TEXT){
				if(this._sectionStart !== this._index){
					this._cbs.ontext(this._buffer.substr(this._sectionStart));
				}
				this._buffer = "";
				this._bufferOffset += this._index;
				this._index = 0;
			} else if(this._sectionStart === this._index){
				//the section just started
				this._buffer = "";
				this._bufferOffset += this._index;
				this._index = 0;
			} else {
				//remove everything unnecessary
				this._buffer = this._buffer.substr(this._sectionStart);
				this._index -= this._sectionStart;
				this._bufferOffset += this._sectionStart;
			}
	
			this._sectionStart = 0;
		}
	};
	
	//TODO make events conditional
	Tokenizer.prototype.write = function(chunk){
		if(this._ended) this._cbs.onerror(Error(".write() after done!"));
	
		this._buffer += chunk;
		this._parse();
	};
	
	Tokenizer.prototype._parse = function(){
		while(this._index < this._buffer.length && this._running){
			var c = this._buffer.charAt(this._index);
			if(this._state === TEXT) {
				this._stateText(c);
			} else if(this._state === BEFORE_TAG_NAME){
				this._stateBeforeTagName(c);
			} else if(this._state === IN_TAG_NAME) {
				this._stateInTagName(c);
			} else if(this._state === BEFORE_CLOSING_TAG_NAME){
				this._stateBeforeCloseingTagName(c);
			} else if(this._state === IN_CLOSING_TAG_NAME){
				this._stateInCloseingTagName(c);
			} else if(this._state === AFTER_CLOSING_TAG_NAME){
				this._stateAfterCloseingTagName(c);
			} else if(this._state === IN_SELF_CLOSING_TAG){
				this._stateInSelfClosingTag(c);
			}
	
			/*
			*	attributes
			*/
			else if(this._state === BEFORE_ATTRIBUTE_NAME){
				this._stateBeforeAttributeName(c);
			} else if(this._state === IN_ATTRIBUTE_NAME){
				this._stateInAttributeName(c);
			} else if(this._state === AFTER_ATTRIBUTE_NAME){
				this._stateAfterAttributeName(c);
			} else if(this._state === BEFORE_ATTRIBUTE_VALUE){
				this._stateBeforeAttributeValue(c);
			} else if(this._state === IN_ATTRIBUTE_VALUE_DQ){
				this._stateInAttributeValueDoubleQuotes(c);
			} else if(this._state === IN_ATTRIBUTE_VALUE_SQ){
				this._stateInAttributeValueSingleQuotes(c);
			} else if(this._state === IN_ATTRIBUTE_VALUE_NQ){
				this._stateInAttributeValueNoQuotes(c);
			}
	
			/*
			*	declarations
			*/
			else if(this._state === BEFORE_DECLARATION){
				this._stateBeforeDeclaration(c);
			} else if(this._state === IN_DECLARATION){
				this._stateInDeclaration(c);
			}
	
			/*
			*	processing instructions
			*/
			else if(this._state === IN_PROCESSING_INSTRUCTION){
				this._stateInProcessingInstruction(c);
			}
	
			/*
			*	comments
			*/
			else if(this._state === BEFORE_COMMENT){
				this._stateBeforeComment(c);
			} else if(this._state === IN_COMMENT){
				this._stateInComment(c);
			} else if(this._state === AFTER_COMMENT_1){
				this._stateAfterComment1(c);
			} else if(this._state === AFTER_COMMENT_2){
				this._stateAfterComment2(c);
			}
	
			/*
			*	cdata
			*/
			else if(this._state === BEFORE_CDATA_1){
				this._stateBeforeCdata1(c);
			} else if(this._state === BEFORE_CDATA_2){
				this._stateBeforeCdata2(c);
			} else if(this._state === BEFORE_CDATA_3){
				this._stateBeforeCdata3(c);
			} else if(this._state === BEFORE_CDATA_4){
				this._stateBeforeCdata4(c);
			} else if(this._state === BEFORE_CDATA_5){
				this._stateBeforeCdata5(c);
			} else if(this._state === BEFORE_CDATA_6){
				this._stateBeforeCdata6(c);
			} else if(this._state === IN_CDATA){
				this._stateInCdata(c);
			} else if(this._state === AFTER_CDATA_1){
				this._stateAfterCdata1(c);
			} else if(this._state === AFTER_CDATA_2){
				this._stateAfterCdata2(c);
			}
	
			/*
			* special tags
			*/
			else if(this._state === BEFORE_SPECIAL){
				this._stateBeforeSpecial(c);
			} else if(this._state === BEFORE_SPECIAL_END){
				this._stateBeforeSpecialEnd(c);
			}
	
			/*
			* script
			*/
			else if(this._state === BEFORE_SCRIPT_1){
				this._stateBeforeScript1(c);
			} else if(this._state === BEFORE_SCRIPT_2){
				this._stateBeforeScript2(c);
			} else if(this._state === BEFORE_SCRIPT_3){
				this._stateBeforeScript3(c);
			} else if(this._state === BEFORE_SCRIPT_4){
				this._stateBeforeScript4(c);
			} else if(this._state === BEFORE_SCRIPT_5){
				this._stateBeforeScript5(c);
			}
	
			else if(this._state === AFTER_SCRIPT_1){
				this._stateAfterScript1(c);
			} else if(this._state === AFTER_SCRIPT_2){
				this._stateAfterScript2(c);
			} else if(this._state === AFTER_SCRIPT_3){
				this._stateAfterScript3(c);
			} else if(this._state === AFTER_SCRIPT_4){
				this._stateAfterScript4(c);
			} else if(this._state === AFTER_SCRIPT_5){
				this._stateAfterScript5(c);
			}
	
			/*
			* style
			*/
			else if(this._state === BEFORE_STYLE_1){
				this._stateBeforeStyle1(c);
			} else if(this._state === BEFORE_STYLE_2){
				this._stateBeforeStyle2(c);
			} else if(this._state === BEFORE_STYLE_3){
				this._stateBeforeStyle3(c);
			} else if(this._state === BEFORE_STYLE_4){
				this._stateBeforeStyle4(c);
			}
	
			else if(this._state === AFTER_STYLE_1){
				this._stateAfterStyle1(c);
			} else if(this._state === AFTER_STYLE_2){
				this._stateAfterStyle2(c);
			} else if(this._state === AFTER_STYLE_3){
				this._stateAfterStyle3(c);
			} else if(this._state === AFTER_STYLE_4){
				this._stateAfterStyle4(c);
			}
	
			/*
			* entities
			*/
			else if(this._state === BEFORE_ENTITY){
				this._stateBeforeEntity(c);
			} else if(this._state === BEFORE_NUMERIC_ENTITY){
				this._stateBeforeNumericEntity(c);
			} else if(this._state === IN_NAMED_ENTITY){
				this._stateInNamedEntity(c);
			} else if(this._state === IN_NUMERIC_ENTITY){
				this._stateInNumericEntity(c);
			} else if(this._state === IN_HEX_ENTITY){
				this._stateInHexEntity(c);
			}
	
			else {
				this._cbs.onerror(Error("unknown _state"), this._state);
			}
	
			this._index++;
		}
	
		this._cleanup();
	};
	
	Tokenizer.prototype.pause = function(){
		this._running = false;
	};
	Tokenizer.prototype.resume = function(){
		this._running = true;
	
		if(this._index < this._buffer.length){
			this._parse();
		}
		if(this._ended){
			this._finish();
		}
	};
	
	Tokenizer.prototype.end = function(chunk){
		if(this._ended) this._cbs.onerror(Error(".end() after done!"));
		if(chunk) this.write(chunk);
	
		this._ended = true;
	
		if(this._running) this._finish();
	};
	
	Tokenizer.prototype._finish = function(){
		//if there is remaining data, emit it in a reasonable way
		if(this._sectionStart < this._index){
			this._handleTrailingData();
		}
	
		this._cbs.onend();
	};
	
	Tokenizer.prototype._handleTrailingData = function(){
		var data = this._buffer.substr(this._sectionStart);
	
		if(this._state === IN_CDATA || this._state === AFTER_CDATA_1 || this._state === AFTER_CDATA_2){
			this._cbs.oncdata(data);
		} else if(this._state === IN_COMMENT || this._state === AFTER_COMMENT_1 || this._state === AFTER_COMMENT_2){
			this._cbs.oncomment(data);
		} else if(this._state === IN_NAMED_ENTITY && !this._xmlMode){
			this._parseLegacyEntity();
			if(this._sectionStart < this._index){
				this._state = this._baseState;
				this._handleTrailingData();
			}
		} else if(this._state === IN_NUMERIC_ENTITY && !this._xmlMode){
			this._decodeNumericEntity(2, 10);
			if(this._sectionStart < this._index){
				this._state = this._baseState;
				this._handleTrailingData();
			}
		} else if(this._state === IN_HEX_ENTITY && !this._xmlMode){
			this._decodeNumericEntity(3, 16);
			if(this._sectionStart < this._index){
				this._state = this._baseState;
				this._handleTrailingData();
			}
		} else if(
			this._state !== IN_TAG_NAME &&
			this._state !== BEFORE_ATTRIBUTE_NAME &&
			this._state !== BEFORE_ATTRIBUTE_VALUE &&
			this._state !== AFTER_ATTRIBUTE_NAME &&
			this._state !== IN_ATTRIBUTE_NAME &&
			this._state !== IN_ATTRIBUTE_VALUE_SQ &&
			this._state !== IN_ATTRIBUTE_VALUE_DQ &&
			this._state !== IN_ATTRIBUTE_VALUE_NQ &&
			this._state !== IN_CLOSING_TAG_NAME
		){
			this._cbs.ontext(data);
		}
		//else, ignore remaining data
		//TODO add a way to remove current tag
	};
	
	Tokenizer.prototype.reset = function(){
		Tokenizer.call(this, {xmlMode: this._xmlMode, decodeEntities: this._decodeEntities}, this._cbs);
	};
	
	Tokenizer.prototype.getAbsoluteIndex = function(){
		return this._bufferOffset + this._index;
	};
	
	Tokenizer.prototype._getSection = function(){
		return this._buffer.substring(this._sectionStart, this._index);
	};
	
	Tokenizer.prototype._emitToken = function(name){
		this._cbs[name](this._getSection());
		this._sectionStart = -1;
	};
	
	Tokenizer.prototype._emitPartial = function(value){
		if(this._baseState !== TEXT){
			this._cbs.onattribdata(value); //TODO implement the new event
		} else {
			this._cbs.ontext(value);
		}
	};
	
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/Tokenizer.js **/


/** START DEFINE BLOCK for entities@1.1.1/lib/decode_codepoint.js **/
jupyter.define('entities@1.1.1/lib/decode_codepoint.js', function (module, exports, __jupyter_require__) {
	var decodeMap = __jupyter_require__('entities@1.1.1/maps/decode.json');
	
	module.exports = decodeCodePoint;
	
	// modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
	function decodeCodePoint(codePoint){
	
		if((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF){
			return "\uFFFD";
		}
	
		if(codePoint in decodeMap){
			codePoint = decodeMap[codePoint];
		}
	
		var output = "";
	
		if(codePoint > 0xFFFF){
			codePoint -= 0x10000;
			output += String.fromCharCode(codePoint >>> 10 & 0x3FF | 0xD800);
			codePoint = 0xDC00 | codePoint & 0x3FF;
		}
	
		output += String.fromCharCode(codePoint);
		return output;
	}
	
})
/** END DEFINE BLOCK for entities@1.1.1/lib/decode_codepoint.js **/


/** START DEFINE BLOCK for entities@1.1.1/maps/decode.json **/
jupyter.define('entities@1.1.1/maps/decode.json', function (module, exports, __jupyter_require__) {
	module.exports = {
		"0": 65533,
		"128": 8364,
		"130": 8218,
		"131": 402,
		"132": 8222,
		"133": 8230,
		"134": 8224,
		"135": 8225,
		"136": 710,
		"137": 8240,
		"138": 352,
		"139": 8249,
		"140": 338,
		"142": 381,
		"145": 8216,
		"146": 8217,
		"147": 8220,
		"148": 8221,
		"149": 8226,
		"150": 8211,
		"151": 8212,
		"152": 732,
		"153": 8482,
		"154": 353,
		"155": 8250,
		"156": 339,
		"158": 382,
		"159": 376
	};
})
/** END DEFINE BLOCK for entities@1.1.1/maps/decode.json **/


/** START DEFINE BLOCK for entities@1.1.1/maps/entities.json **/
jupyter.define('entities@1.1.1/maps/entities.json', function (module, exports, __jupyter_require__) {
	module.exports = {
		"Aacute": "Á",
		"aacute": "á",
		"Abreve": "Ă",
		"abreve": "ă",
		"ac": "∾",
		"acd": "∿",
		"acE": "∾̳",
		"Acirc": "Â",
		"acirc": "â",
		"acute": "´",
		"Acy": "А",
		"acy": "а",
		"AElig": "Æ",
		"aelig": "æ",
		"af": "⁡",
		"Afr": "𝔄",
		"afr": "𝔞",
		"Agrave": "À",
		"agrave": "à",
		"alefsym": "ℵ",
		"aleph": "ℵ",
		"Alpha": "Α",
		"alpha": "α",
		"Amacr": "Ā",
		"amacr": "ā",
		"amalg": "⨿",
		"amp": "&",
		"AMP": "&",
		"andand": "⩕",
		"And": "⩓",
		"and": "∧",
		"andd": "⩜",
		"andslope": "⩘",
		"andv": "⩚",
		"ang": "∠",
		"ange": "⦤",
		"angle": "∠",
		"angmsdaa": "⦨",
		"angmsdab": "⦩",
		"angmsdac": "⦪",
		"angmsdad": "⦫",
		"angmsdae": "⦬",
		"angmsdaf": "⦭",
		"angmsdag": "⦮",
		"angmsdah": "⦯",
		"angmsd": "∡",
		"angrt": "∟",
		"angrtvb": "⊾",
		"angrtvbd": "⦝",
		"angsph": "∢",
		"angst": "Å",
		"angzarr": "⍼",
		"Aogon": "Ą",
		"aogon": "ą",
		"Aopf": "𝔸",
		"aopf": "𝕒",
		"apacir": "⩯",
		"ap": "≈",
		"apE": "⩰",
		"ape": "≊",
		"apid": "≋",
		"apos": "'",
		"ApplyFunction": "⁡",
		"approx": "≈",
		"approxeq": "≊",
		"Aring": "Å",
		"aring": "å",
		"Ascr": "𝒜",
		"ascr": "𝒶",
		"Assign": "≔",
		"ast": "*",
		"asymp": "≈",
		"asympeq": "≍",
		"Atilde": "Ã",
		"atilde": "ã",
		"Auml": "Ä",
		"auml": "ä",
		"awconint": "∳",
		"awint": "⨑",
		"backcong": "≌",
		"backepsilon": "϶",
		"backprime": "‵",
		"backsim": "∽",
		"backsimeq": "⋍",
		"Backslash": "∖",
		"Barv": "⫧",
		"barvee": "⊽",
		"barwed": "⌅",
		"Barwed": "⌆",
		"barwedge": "⌅",
		"bbrk": "⎵",
		"bbrktbrk": "⎶",
		"bcong": "≌",
		"Bcy": "Б",
		"bcy": "б",
		"bdquo": "„",
		"becaus": "∵",
		"because": "∵",
		"Because": "∵",
		"bemptyv": "⦰",
		"bepsi": "϶",
		"bernou": "ℬ",
		"Bernoullis": "ℬ",
		"Beta": "Β",
		"beta": "β",
		"beth": "ℶ",
		"between": "≬",
		"Bfr": "𝔅",
		"bfr": "𝔟",
		"bigcap": "⋂",
		"bigcirc": "◯",
		"bigcup": "⋃",
		"bigodot": "⨀",
		"bigoplus": "⨁",
		"bigotimes": "⨂",
		"bigsqcup": "⨆",
		"bigstar": "★",
		"bigtriangledown": "▽",
		"bigtriangleup": "△",
		"biguplus": "⨄",
		"bigvee": "⋁",
		"bigwedge": "⋀",
		"bkarow": "⤍",
		"blacklozenge": "⧫",
		"blacksquare": "▪",
		"blacktriangle": "▴",
		"blacktriangledown": "▾",
		"blacktriangleleft": "◂",
		"blacktriangleright": "▸",
		"blank": "␣",
		"blk12": "▒",
		"blk14": "░",
		"blk34": "▓",
		"block": "█",
		"bne": "=⃥",
		"bnequiv": "≡⃥",
		"bNot": "⫭",
		"bnot": "⌐",
		"Bopf": "𝔹",
		"bopf": "𝕓",
		"bot": "⊥",
		"bottom": "⊥",
		"bowtie": "⋈",
		"boxbox": "⧉",
		"boxdl": "┐",
		"boxdL": "╕",
		"boxDl": "╖",
		"boxDL": "╗",
		"boxdr": "┌",
		"boxdR": "╒",
		"boxDr": "╓",
		"boxDR": "╔",
		"boxh": "─",
		"boxH": "═",
		"boxhd": "┬",
		"boxHd": "╤",
		"boxhD": "╥",
		"boxHD": "╦",
		"boxhu": "┴",
		"boxHu": "╧",
		"boxhU": "╨",
		"boxHU": "╩",
		"boxminus": "⊟",
		"boxplus": "⊞",
		"boxtimes": "⊠",
		"boxul": "┘",
		"boxuL": "╛",
		"boxUl": "╜",
		"boxUL": "╝",
		"boxur": "└",
		"boxuR": "╘",
		"boxUr": "╙",
		"boxUR": "╚",
		"boxv": "│",
		"boxV": "║",
		"boxvh": "┼",
		"boxvH": "╪",
		"boxVh": "╫",
		"boxVH": "╬",
		"boxvl": "┤",
		"boxvL": "╡",
		"boxVl": "╢",
		"boxVL": "╣",
		"boxvr": "├",
		"boxvR": "╞",
		"boxVr": "╟",
		"boxVR": "╠",
		"bprime": "‵",
		"breve": "˘",
		"Breve": "˘",
		"brvbar": "¦",
		"bscr": "𝒷",
		"Bscr": "ℬ",
		"bsemi": "⁏",
		"bsim": "∽",
		"bsime": "⋍",
		"bsolb": "⧅",
		"bsol": "\\",
		"bsolhsub": "⟈",
		"bull": "•",
		"bullet": "•",
		"bump": "≎",
		"bumpE": "⪮",
		"bumpe": "≏",
		"Bumpeq": "≎",
		"bumpeq": "≏",
		"Cacute": "Ć",
		"cacute": "ć",
		"capand": "⩄",
		"capbrcup": "⩉",
		"capcap": "⩋",
		"cap": "∩",
		"Cap": "⋒",
		"capcup": "⩇",
		"capdot": "⩀",
		"CapitalDifferentialD": "ⅅ",
		"caps": "∩︀",
		"caret": "⁁",
		"caron": "ˇ",
		"Cayleys": "ℭ",
		"ccaps": "⩍",
		"Ccaron": "Č",
		"ccaron": "č",
		"Ccedil": "Ç",
		"ccedil": "ç",
		"Ccirc": "Ĉ",
		"ccirc": "ĉ",
		"Cconint": "∰",
		"ccups": "⩌",
		"ccupssm": "⩐",
		"Cdot": "Ċ",
		"cdot": "ċ",
		"cedil": "¸",
		"Cedilla": "¸",
		"cemptyv": "⦲",
		"cent": "¢",
		"centerdot": "·",
		"CenterDot": "·",
		"cfr": "𝔠",
		"Cfr": "ℭ",
		"CHcy": "Ч",
		"chcy": "ч",
		"check": "✓",
		"checkmark": "✓",
		"Chi": "Χ",
		"chi": "χ",
		"circ": "ˆ",
		"circeq": "≗",
		"circlearrowleft": "↺",
		"circlearrowright": "↻",
		"circledast": "⊛",
		"circledcirc": "⊚",
		"circleddash": "⊝",
		"CircleDot": "⊙",
		"circledR": "®",
		"circledS": "Ⓢ",
		"CircleMinus": "⊖",
		"CirclePlus": "⊕",
		"CircleTimes": "⊗",
		"cir": "○",
		"cirE": "⧃",
		"cire": "≗",
		"cirfnint": "⨐",
		"cirmid": "⫯",
		"cirscir": "⧂",
		"ClockwiseContourIntegral": "∲",
		"CloseCurlyDoubleQuote": "”",
		"CloseCurlyQuote": "’",
		"clubs": "♣",
		"clubsuit": "♣",
		"colon": ":",
		"Colon": "∷",
		"Colone": "⩴",
		"colone": "≔",
		"coloneq": "≔",
		"comma": ",",
		"commat": "@",
		"comp": "∁",
		"compfn": "∘",
		"complement": "∁",
		"complexes": "ℂ",
		"cong": "≅",
		"congdot": "⩭",
		"Congruent": "≡",
		"conint": "∮",
		"Conint": "∯",
		"ContourIntegral": "∮",
		"copf": "𝕔",
		"Copf": "ℂ",
		"coprod": "∐",
		"Coproduct": "∐",
		"copy": "©",
		"COPY": "©",
		"copysr": "℗",
		"CounterClockwiseContourIntegral": "∳",
		"crarr": "↵",
		"cross": "✗",
		"Cross": "⨯",
		"Cscr": "𝒞",
		"cscr": "𝒸",
		"csub": "⫏",
		"csube": "⫑",
		"csup": "⫐",
		"csupe": "⫒",
		"ctdot": "⋯",
		"cudarrl": "⤸",
		"cudarrr": "⤵",
		"cuepr": "⋞",
		"cuesc": "⋟",
		"cularr": "↶",
		"cularrp": "⤽",
		"cupbrcap": "⩈",
		"cupcap": "⩆",
		"CupCap": "≍",
		"cup": "∪",
		"Cup": "⋓",
		"cupcup": "⩊",
		"cupdot": "⊍",
		"cupor": "⩅",
		"cups": "∪︀",
		"curarr": "↷",
		"curarrm": "⤼",
		"curlyeqprec": "⋞",
		"curlyeqsucc": "⋟",
		"curlyvee": "⋎",
		"curlywedge": "⋏",
		"curren": "¤",
		"curvearrowleft": "↶",
		"curvearrowright": "↷",
		"cuvee": "⋎",
		"cuwed": "⋏",
		"cwconint": "∲",
		"cwint": "∱",
		"cylcty": "⌭",
		"dagger": "†",
		"Dagger": "‡",
		"daleth": "ℸ",
		"darr": "↓",
		"Darr": "↡",
		"dArr": "⇓",
		"dash": "‐",
		"Dashv": "⫤",
		"dashv": "⊣",
		"dbkarow": "⤏",
		"dblac": "˝",
		"Dcaron": "Ď",
		"dcaron": "ď",
		"Dcy": "Д",
		"dcy": "д",
		"ddagger": "‡",
		"ddarr": "⇊",
		"DD": "ⅅ",
		"dd": "ⅆ",
		"DDotrahd": "⤑",
		"ddotseq": "⩷",
		"deg": "°",
		"Del": "∇",
		"Delta": "Δ",
		"delta": "δ",
		"demptyv": "⦱",
		"dfisht": "⥿",
		"Dfr": "𝔇",
		"dfr": "𝔡",
		"dHar": "⥥",
		"dharl": "⇃",
		"dharr": "⇂",
		"DiacriticalAcute": "´",
		"DiacriticalDot": "˙",
		"DiacriticalDoubleAcute": "˝",
		"DiacriticalGrave": "`",
		"DiacriticalTilde": "˜",
		"diam": "⋄",
		"diamond": "⋄",
		"Diamond": "⋄",
		"diamondsuit": "♦",
		"diams": "♦",
		"die": "¨",
		"DifferentialD": "ⅆ",
		"digamma": "ϝ",
		"disin": "⋲",
		"div": "÷",
		"divide": "÷",
		"divideontimes": "⋇",
		"divonx": "⋇",
		"DJcy": "Ђ",
		"djcy": "ђ",
		"dlcorn": "⌞",
		"dlcrop": "⌍",
		"dollar": "$",
		"Dopf": "𝔻",
		"dopf": "𝕕",
		"Dot": "¨",
		"dot": "˙",
		"DotDot": "⃜",
		"doteq": "≐",
		"doteqdot": "≑",
		"DotEqual": "≐",
		"dotminus": "∸",
		"dotplus": "∔",
		"dotsquare": "⊡",
		"doublebarwedge": "⌆",
		"DoubleContourIntegral": "∯",
		"DoubleDot": "¨",
		"DoubleDownArrow": "⇓",
		"DoubleLeftArrow": "⇐",
		"DoubleLeftRightArrow": "⇔",
		"DoubleLeftTee": "⫤",
		"DoubleLongLeftArrow": "⟸",
		"DoubleLongLeftRightArrow": "⟺",
		"DoubleLongRightArrow": "⟹",
		"DoubleRightArrow": "⇒",
		"DoubleRightTee": "⊨",
		"DoubleUpArrow": "⇑",
		"DoubleUpDownArrow": "⇕",
		"DoubleVerticalBar": "∥",
		"DownArrowBar": "⤓",
		"downarrow": "↓",
		"DownArrow": "↓",
		"Downarrow": "⇓",
		"DownArrowUpArrow": "⇵",
		"DownBreve": "̑",
		"downdownarrows": "⇊",
		"downharpoonleft": "⇃",
		"downharpoonright": "⇂",
		"DownLeftRightVector": "⥐",
		"DownLeftTeeVector": "⥞",
		"DownLeftVectorBar": "⥖",
		"DownLeftVector": "↽",
		"DownRightTeeVector": "⥟",
		"DownRightVectorBar": "⥗",
		"DownRightVector": "⇁",
		"DownTeeArrow": "↧",
		"DownTee": "⊤",
		"drbkarow": "⤐",
		"drcorn": "⌟",
		"drcrop": "⌌",
		"Dscr": "𝒟",
		"dscr": "𝒹",
		"DScy": "Ѕ",
		"dscy": "ѕ",
		"dsol": "⧶",
		"Dstrok": "Đ",
		"dstrok": "đ",
		"dtdot": "⋱",
		"dtri": "▿",
		"dtrif": "▾",
		"duarr": "⇵",
		"duhar": "⥯",
		"dwangle": "⦦",
		"DZcy": "Џ",
		"dzcy": "џ",
		"dzigrarr": "⟿",
		"Eacute": "É",
		"eacute": "é",
		"easter": "⩮",
		"Ecaron": "Ě",
		"ecaron": "ě",
		"Ecirc": "Ê",
		"ecirc": "ê",
		"ecir": "≖",
		"ecolon": "≕",
		"Ecy": "Э",
		"ecy": "э",
		"eDDot": "⩷",
		"Edot": "Ė",
		"edot": "ė",
		"eDot": "≑",
		"ee": "ⅇ",
		"efDot": "≒",
		"Efr": "𝔈",
		"efr": "𝔢",
		"eg": "⪚",
		"Egrave": "È",
		"egrave": "è",
		"egs": "⪖",
		"egsdot": "⪘",
		"el": "⪙",
		"Element": "∈",
		"elinters": "⏧",
		"ell": "ℓ",
		"els": "⪕",
		"elsdot": "⪗",
		"Emacr": "Ē",
		"emacr": "ē",
		"empty": "∅",
		"emptyset": "∅",
		"EmptySmallSquare": "◻",
		"emptyv": "∅",
		"EmptyVerySmallSquare": "▫",
		"emsp13": " ",
		"emsp14": " ",
		"emsp": " ",
		"ENG": "Ŋ",
		"eng": "ŋ",
		"ensp": " ",
		"Eogon": "Ę",
		"eogon": "ę",
		"Eopf": "𝔼",
		"eopf": "𝕖",
		"epar": "⋕",
		"eparsl": "⧣",
		"eplus": "⩱",
		"epsi": "ε",
		"Epsilon": "Ε",
		"epsilon": "ε",
		"epsiv": "ϵ",
		"eqcirc": "≖",
		"eqcolon": "≕",
		"eqsim": "≂",
		"eqslantgtr": "⪖",
		"eqslantless": "⪕",
		"Equal": "⩵",
		"equals": "=",
		"EqualTilde": "≂",
		"equest": "≟",
		"Equilibrium": "⇌",
		"equiv": "≡",
		"equivDD": "⩸",
		"eqvparsl": "⧥",
		"erarr": "⥱",
		"erDot": "≓",
		"escr": "ℯ",
		"Escr": "ℰ",
		"esdot": "≐",
		"Esim": "⩳",
		"esim": "≂",
		"Eta": "Η",
		"eta": "η",
		"ETH": "Ð",
		"eth": "ð",
		"Euml": "Ë",
		"euml": "ë",
		"euro": "€",
		"excl": "!",
		"exist": "∃",
		"Exists": "∃",
		"expectation": "ℰ",
		"exponentiale": "ⅇ",
		"ExponentialE": "ⅇ",
		"fallingdotseq": "≒",
		"Fcy": "Ф",
		"fcy": "ф",
		"female": "♀",
		"ffilig": "ﬃ",
		"fflig": "ﬀ",
		"ffllig": "ﬄ",
		"Ffr": "𝔉",
		"ffr": "𝔣",
		"filig": "ﬁ",
		"FilledSmallSquare": "◼",
		"FilledVerySmallSquare": "▪",
		"fjlig": "fj",
		"flat": "♭",
		"fllig": "ﬂ",
		"fltns": "▱",
		"fnof": "ƒ",
		"Fopf": "𝔽",
		"fopf": "𝕗",
		"forall": "∀",
		"ForAll": "∀",
		"fork": "⋔",
		"forkv": "⫙",
		"Fouriertrf": "ℱ",
		"fpartint": "⨍",
		"frac12": "½",
		"frac13": "⅓",
		"frac14": "¼",
		"frac15": "⅕",
		"frac16": "⅙",
		"frac18": "⅛",
		"frac23": "⅔",
		"frac25": "⅖",
		"frac34": "¾",
		"frac35": "⅗",
		"frac38": "⅜",
		"frac45": "⅘",
		"frac56": "⅚",
		"frac58": "⅝",
		"frac78": "⅞",
		"frasl": "⁄",
		"frown": "⌢",
		"fscr": "𝒻",
		"Fscr": "ℱ",
		"gacute": "ǵ",
		"Gamma": "Γ",
		"gamma": "γ",
		"Gammad": "Ϝ",
		"gammad": "ϝ",
		"gap": "⪆",
		"Gbreve": "Ğ",
		"gbreve": "ğ",
		"Gcedil": "Ģ",
		"Gcirc": "Ĝ",
		"gcirc": "ĝ",
		"Gcy": "Г",
		"gcy": "г",
		"Gdot": "Ġ",
		"gdot": "ġ",
		"ge": "≥",
		"gE": "≧",
		"gEl": "⪌",
		"gel": "⋛",
		"geq": "≥",
		"geqq": "≧",
		"geqslant": "⩾",
		"gescc": "⪩",
		"ges": "⩾",
		"gesdot": "⪀",
		"gesdoto": "⪂",
		"gesdotol": "⪄",
		"gesl": "⋛︀",
		"gesles": "⪔",
		"Gfr": "𝔊",
		"gfr": "𝔤",
		"gg": "≫",
		"Gg": "⋙",
		"ggg": "⋙",
		"gimel": "ℷ",
		"GJcy": "Ѓ",
		"gjcy": "ѓ",
		"gla": "⪥",
		"gl": "≷",
		"glE": "⪒",
		"glj": "⪤",
		"gnap": "⪊",
		"gnapprox": "⪊",
		"gne": "⪈",
		"gnE": "≩",
		"gneq": "⪈",
		"gneqq": "≩",
		"gnsim": "⋧",
		"Gopf": "𝔾",
		"gopf": "𝕘",
		"grave": "`",
		"GreaterEqual": "≥",
		"GreaterEqualLess": "⋛",
		"GreaterFullEqual": "≧",
		"GreaterGreater": "⪢",
		"GreaterLess": "≷",
		"GreaterSlantEqual": "⩾",
		"GreaterTilde": "≳",
		"Gscr": "𝒢",
		"gscr": "ℊ",
		"gsim": "≳",
		"gsime": "⪎",
		"gsiml": "⪐",
		"gtcc": "⪧",
		"gtcir": "⩺",
		"gt": ">",
		"GT": ">",
		"Gt": "≫",
		"gtdot": "⋗",
		"gtlPar": "⦕",
		"gtquest": "⩼",
		"gtrapprox": "⪆",
		"gtrarr": "⥸",
		"gtrdot": "⋗",
		"gtreqless": "⋛",
		"gtreqqless": "⪌",
		"gtrless": "≷",
		"gtrsim": "≳",
		"gvertneqq": "≩︀",
		"gvnE": "≩︀",
		"Hacek": "ˇ",
		"hairsp": " ",
		"half": "½",
		"hamilt": "ℋ",
		"HARDcy": "Ъ",
		"hardcy": "ъ",
		"harrcir": "⥈",
		"harr": "↔",
		"hArr": "⇔",
		"harrw": "↭",
		"Hat": "^",
		"hbar": "ℏ",
		"Hcirc": "Ĥ",
		"hcirc": "ĥ",
		"hearts": "♥",
		"heartsuit": "♥",
		"hellip": "…",
		"hercon": "⊹",
		"hfr": "𝔥",
		"Hfr": "ℌ",
		"HilbertSpace": "ℋ",
		"hksearow": "⤥",
		"hkswarow": "⤦",
		"hoarr": "⇿",
		"homtht": "∻",
		"hookleftarrow": "↩",
		"hookrightarrow": "↪",
		"hopf": "𝕙",
		"Hopf": "ℍ",
		"horbar": "―",
		"HorizontalLine": "─",
		"hscr": "𝒽",
		"Hscr": "ℋ",
		"hslash": "ℏ",
		"Hstrok": "Ħ",
		"hstrok": "ħ",
		"HumpDownHump": "≎",
		"HumpEqual": "≏",
		"hybull": "⁃",
		"hyphen": "‐",
		"Iacute": "Í",
		"iacute": "í",
		"ic": "⁣",
		"Icirc": "Î",
		"icirc": "î",
		"Icy": "И",
		"icy": "и",
		"Idot": "İ",
		"IEcy": "Е",
		"iecy": "е",
		"iexcl": "¡",
		"iff": "⇔",
		"ifr": "𝔦",
		"Ifr": "ℑ",
		"Igrave": "Ì",
		"igrave": "ì",
		"ii": "ⅈ",
		"iiiint": "⨌",
		"iiint": "∭",
		"iinfin": "⧜",
		"iiota": "℩",
		"IJlig": "Ĳ",
		"ijlig": "ĳ",
		"Imacr": "Ī",
		"imacr": "ī",
		"image": "ℑ",
		"ImaginaryI": "ⅈ",
		"imagline": "ℐ",
		"imagpart": "ℑ",
		"imath": "ı",
		"Im": "ℑ",
		"imof": "⊷",
		"imped": "Ƶ",
		"Implies": "⇒",
		"incare": "℅",
		"in": "∈",
		"infin": "∞",
		"infintie": "⧝",
		"inodot": "ı",
		"intcal": "⊺",
		"int": "∫",
		"Int": "∬",
		"integers": "ℤ",
		"Integral": "∫",
		"intercal": "⊺",
		"Intersection": "⋂",
		"intlarhk": "⨗",
		"intprod": "⨼",
		"InvisibleComma": "⁣",
		"InvisibleTimes": "⁢",
		"IOcy": "Ё",
		"iocy": "ё",
		"Iogon": "Į",
		"iogon": "į",
		"Iopf": "𝕀",
		"iopf": "𝕚",
		"Iota": "Ι",
		"iota": "ι",
		"iprod": "⨼",
		"iquest": "¿",
		"iscr": "𝒾",
		"Iscr": "ℐ",
		"isin": "∈",
		"isindot": "⋵",
		"isinE": "⋹",
		"isins": "⋴",
		"isinsv": "⋳",
		"isinv": "∈",
		"it": "⁢",
		"Itilde": "Ĩ",
		"itilde": "ĩ",
		"Iukcy": "І",
		"iukcy": "і",
		"Iuml": "Ï",
		"iuml": "ï",
		"Jcirc": "Ĵ",
		"jcirc": "ĵ",
		"Jcy": "Й",
		"jcy": "й",
		"Jfr": "𝔍",
		"jfr": "𝔧",
		"jmath": "ȷ",
		"Jopf": "𝕁",
		"jopf": "𝕛",
		"Jscr": "𝒥",
		"jscr": "𝒿",
		"Jsercy": "Ј",
		"jsercy": "ј",
		"Jukcy": "Є",
		"jukcy": "є",
		"Kappa": "Κ",
		"kappa": "κ",
		"kappav": "ϰ",
		"Kcedil": "Ķ",
		"kcedil": "ķ",
		"Kcy": "К",
		"kcy": "к",
		"Kfr": "𝔎",
		"kfr": "𝔨",
		"kgreen": "ĸ",
		"KHcy": "Х",
		"khcy": "х",
		"KJcy": "Ќ",
		"kjcy": "ќ",
		"Kopf": "𝕂",
		"kopf": "𝕜",
		"Kscr": "𝒦",
		"kscr": "𝓀",
		"lAarr": "⇚",
		"Lacute": "Ĺ",
		"lacute": "ĺ",
		"laemptyv": "⦴",
		"lagran": "ℒ",
		"Lambda": "Λ",
		"lambda": "λ",
		"lang": "⟨",
		"Lang": "⟪",
		"langd": "⦑",
		"langle": "⟨",
		"lap": "⪅",
		"Laplacetrf": "ℒ",
		"laquo": "«",
		"larrb": "⇤",
		"larrbfs": "⤟",
		"larr": "←",
		"Larr": "↞",
		"lArr": "⇐",
		"larrfs": "⤝",
		"larrhk": "↩",
		"larrlp": "↫",
		"larrpl": "⤹",
		"larrsim": "⥳",
		"larrtl": "↢",
		"latail": "⤙",
		"lAtail": "⤛",
		"lat": "⪫",
		"late": "⪭",
		"lates": "⪭︀",
		"lbarr": "⤌",
		"lBarr": "⤎",
		"lbbrk": "❲",
		"lbrace": "{",
		"lbrack": "[",
		"lbrke": "⦋",
		"lbrksld": "⦏",
		"lbrkslu": "⦍",
		"Lcaron": "Ľ",
		"lcaron": "ľ",
		"Lcedil": "Ļ",
		"lcedil": "ļ",
		"lceil": "⌈",
		"lcub": "{",
		"Lcy": "Л",
		"lcy": "л",
		"ldca": "⤶",
		"ldquo": "“",
		"ldquor": "„",
		"ldrdhar": "⥧",
		"ldrushar": "⥋",
		"ldsh": "↲",
		"le": "≤",
		"lE": "≦",
		"LeftAngleBracket": "⟨",
		"LeftArrowBar": "⇤",
		"leftarrow": "←",
		"LeftArrow": "←",
		"Leftarrow": "⇐",
		"LeftArrowRightArrow": "⇆",
		"leftarrowtail": "↢",
		"LeftCeiling": "⌈",
		"LeftDoubleBracket": "⟦",
		"LeftDownTeeVector": "⥡",
		"LeftDownVectorBar": "⥙",
		"LeftDownVector": "⇃",
		"LeftFloor": "⌊",
		"leftharpoondown": "↽",
		"leftharpoonup": "↼",
		"leftleftarrows": "⇇",
		"leftrightarrow": "↔",
		"LeftRightArrow": "↔",
		"Leftrightarrow": "⇔",
		"leftrightarrows": "⇆",
		"leftrightharpoons": "⇋",
		"leftrightsquigarrow": "↭",
		"LeftRightVector": "⥎",
		"LeftTeeArrow": "↤",
		"LeftTee": "⊣",
		"LeftTeeVector": "⥚",
		"leftthreetimes": "⋋",
		"LeftTriangleBar": "⧏",
		"LeftTriangle": "⊲",
		"LeftTriangleEqual": "⊴",
		"LeftUpDownVector": "⥑",
		"LeftUpTeeVector": "⥠",
		"LeftUpVectorBar": "⥘",
		"LeftUpVector": "↿",
		"LeftVectorBar": "⥒",
		"LeftVector": "↼",
		"lEg": "⪋",
		"leg": "⋚",
		"leq": "≤",
		"leqq": "≦",
		"leqslant": "⩽",
		"lescc": "⪨",
		"les": "⩽",
		"lesdot": "⩿",
		"lesdoto": "⪁",
		"lesdotor": "⪃",
		"lesg": "⋚︀",
		"lesges": "⪓",
		"lessapprox": "⪅",
		"lessdot": "⋖",
		"lesseqgtr": "⋚",
		"lesseqqgtr": "⪋",
		"LessEqualGreater": "⋚",
		"LessFullEqual": "≦",
		"LessGreater": "≶",
		"lessgtr": "≶",
		"LessLess": "⪡",
		"lesssim": "≲",
		"LessSlantEqual": "⩽",
		"LessTilde": "≲",
		"lfisht": "⥼",
		"lfloor": "⌊",
		"Lfr": "𝔏",
		"lfr": "𝔩",
		"lg": "≶",
		"lgE": "⪑",
		"lHar": "⥢",
		"lhard": "↽",
		"lharu": "↼",
		"lharul": "⥪",
		"lhblk": "▄",
		"LJcy": "Љ",
		"ljcy": "љ",
		"llarr": "⇇",
		"ll": "≪",
		"Ll": "⋘",
		"llcorner": "⌞",
		"Lleftarrow": "⇚",
		"llhard": "⥫",
		"lltri": "◺",
		"Lmidot": "Ŀ",
		"lmidot": "ŀ",
		"lmoustache": "⎰",
		"lmoust": "⎰",
		"lnap": "⪉",
		"lnapprox": "⪉",
		"lne": "⪇",
		"lnE": "≨",
		"lneq": "⪇",
		"lneqq": "≨",
		"lnsim": "⋦",
		"loang": "⟬",
		"loarr": "⇽",
		"lobrk": "⟦",
		"longleftarrow": "⟵",
		"LongLeftArrow": "⟵",
		"Longleftarrow": "⟸",
		"longleftrightarrow": "⟷",
		"LongLeftRightArrow": "⟷",
		"Longleftrightarrow": "⟺",
		"longmapsto": "⟼",
		"longrightarrow": "⟶",
		"LongRightArrow": "⟶",
		"Longrightarrow": "⟹",
		"looparrowleft": "↫",
		"looparrowright": "↬",
		"lopar": "⦅",
		"Lopf": "𝕃",
		"lopf": "𝕝",
		"loplus": "⨭",
		"lotimes": "⨴",
		"lowast": "∗",
		"lowbar": "_",
		"LowerLeftArrow": "↙",
		"LowerRightArrow": "↘",
		"loz": "◊",
		"lozenge": "◊",
		"lozf": "⧫",
		"lpar": "(",
		"lparlt": "⦓",
		"lrarr": "⇆",
		"lrcorner": "⌟",
		"lrhar": "⇋",
		"lrhard": "⥭",
		"lrm": "‎",
		"lrtri": "⊿",
		"lsaquo": "‹",
		"lscr": "𝓁",
		"Lscr": "ℒ",
		"lsh": "↰",
		"Lsh": "↰",
		"lsim": "≲",
		"lsime": "⪍",
		"lsimg": "⪏",
		"lsqb": "[",
		"lsquo": "‘",
		"lsquor": "‚",
		"Lstrok": "Ł",
		"lstrok": "ł",
		"ltcc": "⪦",
		"ltcir": "⩹",
		"lt": "<",
		"LT": "<",
		"Lt": "≪",
		"ltdot": "⋖",
		"lthree": "⋋",
		"ltimes": "⋉",
		"ltlarr": "⥶",
		"ltquest": "⩻",
		"ltri": "◃",
		"ltrie": "⊴",
		"ltrif": "◂",
		"ltrPar": "⦖",
		"lurdshar": "⥊",
		"luruhar": "⥦",
		"lvertneqq": "≨︀",
		"lvnE": "≨︀",
		"macr": "¯",
		"male": "♂",
		"malt": "✠",
		"maltese": "✠",
		"Map": "⤅",
		"map": "↦",
		"mapsto": "↦",
		"mapstodown": "↧",
		"mapstoleft": "↤",
		"mapstoup": "↥",
		"marker": "▮",
		"mcomma": "⨩",
		"Mcy": "М",
		"mcy": "м",
		"mdash": "—",
		"mDDot": "∺",
		"measuredangle": "∡",
		"MediumSpace": " ",
		"Mellintrf": "ℳ",
		"Mfr": "𝔐",
		"mfr": "𝔪",
		"mho": "℧",
		"micro": "µ",
		"midast": "*",
		"midcir": "⫰",
		"mid": "∣",
		"middot": "·",
		"minusb": "⊟",
		"minus": "−",
		"minusd": "∸",
		"minusdu": "⨪",
		"MinusPlus": "∓",
		"mlcp": "⫛",
		"mldr": "…",
		"mnplus": "∓",
		"models": "⊧",
		"Mopf": "𝕄",
		"mopf": "𝕞",
		"mp": "∓",
		"mscr": "𝓂",
		"Mscr": "ℳ",
		"mstpos": "∾",
		"Mu": "Μ",
		"mu": "μ",
		"multimap": "⊸",
		"mumap": "⊸",
		"nabla": "∇",
		"Nacute": "Ń",
		"nacute": "ń",
		"nang": "∠⃒",
		"nap": "≉",
		"napE": "⩰̸",
		"napid": "≋̸",
		"napos": "ŉ",
		"napprox": "≉",
		"natural": "♮",
		"naturals": "ℕ",
		"natur": "♮",
		"nbsp": " ",
		"nbump": "≎̸",
		"nbumpe": "≏̸",
		"ncap": "⩃",
		"Ncaron": "Ň",
		"ncaron": "ň",
		"Ncedil": "Ņ",
		"ncedil": "ņ",
		"ncong": "≇",
		"ncongdot": "⩭̸",
		"ncup": "⩂",
		"Ncy": "Н",
		"ncy": "н",
		"ndash": "–",
		"nearhk": "⤤",
		"nearr": "↗",
		"neArr": "⇗",
		"nearrow": "↗",
		"ne": "≠",
		"nedot": "≐̸",
		"NegativeMediumSpace": "​",
		"NegativeThickSpace": "​",
		"NegativeThinSpace": "​",
		"NegativeVeryThinSpace": "​",
		"nequiv": "≢",
		"nesear": "⤨",
		"nesim": "≂̸",
		"NestedGreaterGreater": "≫",
		"NestedLessLess": "≪",
		"NewLine": "\n",
		"nexist": "∄",
		"nexists": "∄",
		"Nfr": "𝔑",
		"nfr": "𝔫",
		"ngE": "≧̸",
		"nge": "≱",
		"ngeq": "≱",
		"ngeqq": "≧̸",
		"ngeqslant": "⩾̸",
		"nges": "⩾̸",
		"nGg": "⋙̸",
		"ngsim": "≵",
		"nGt": "≫⃒",
		"ngt": "≯",
		"ngtr": "≯",
		"nGtv": "≫̸",
		"nharr": "↮",
		"nhArr": "⇎",
		"nhpar": "⫲",
		"ni": "∋",
		"nis": "⋼",
		"nisd": "⋺",
		"niv": "∋",
		"NJcy": "Њ",
		"njcy": "њ",
		"nlarr": "↚",
		"nlArr": "⇍",
		"nldr": "‥",
		"nlE": "≦̸",
		"nle": "≰",
		"nleftarrow": "↚",
		"nLeftarrow": "⇍",
		"nleftrightarrow": "↮",
		"nLeftrightarrow": "⇎",
		"nleq": "≰",
		"nleqq": "≦̸",
		"nleqslant": "⩽̸",
		"nles": "⩽̸",
		"nless": "≮",
		"nLl": "⋘̸",
		"nlsim": "≴",
		"nLt": "≪⃒",
		"nlt": "≮",
		"nltri": "⋪",
		"nltrie": "⋬",
		"nLtv": "≪̸",
		"nmid": "∤",
		"NoBreak": "⁠",
		"NonBreakingSpace": " ",
		"nopf": "𝕟",
		"Nopf": "ℕ",
		"Not": "⫬",
		"not": "¬",
		"NotCongruent": "≢",
		"NotCupCap": "≭",
		"NotDoubleVerticalBar": "∦",
		"NotElement": "∉",
		"NotEqual": "≠",
		"NotEqualTilde": "≂̸",
		"NotExists": "∄",
		"NotGreater": "≯",
		"NotGreaterEqual": "≱",
		"NotGreaterFullEqual": "≧̸",
		"NotGreaterGreater": "≫̸",
		"NotGreaterLess": "≹",
		"NotGreaterSlantEqual": "⩾̸",
		"NotGreaterTilde": "≵",
		"NotHumpDownHump": "≎̸",
		"NotHumpEqual": "≏̸",
		"notin": "∉",
		"notindot": "⋵̸",
		"notinE": "⋹̸",
		"notinva": "∉",
		"notinvb": "⋷",
		"notinvc": "⋶",
		"NotLeftTriangleBar": "⧏̸",
		"NotLeftTriangle": "⋪",
		"NotLeftTriangleEqual": "⋬",
		"NotLess": "≮",
		"NotLessEqual": "≰",
		"NotLessGreater": "≸",
		"NotLessLess": "≪̸",
		"NotLessSlantEqual": "⩽̸",
		"NotLessTilde": "≴",
		"NotNestedGreaterGreater": "⪢̸",
		"NotNestedLessLess": "⪡̸",
		"notni": "∌",
		"notniva": "∌",
		"notnivb": "⋾",
		"notnivc": "⋽",
		"NotPrecedes": "⊀",
		"NotPrecedesEqual": "⪯̸",
		"NotPrecedesSlantEqual": "⋠",
		"NotReverseElement": "∌",
		"NotRightTriangleBar": "⧐̸",
		"NotRightTriangle": "⋫",
		"NotRightTriangleEqual": "⋭",
		"NotSquareSubset": "⊏̸",
		"NotSquareSubsetEqual": "⋢",
		"NotSquareSuperset": "⊐̸",
		"NotSquareSupersetEqual": "⋣",
		"NotSubset": "⊂⃒",
		"NotSubsetEqual": "⊈",
		"NotSucceeds": "⊁",
		"NotSucceedsEqual": "⪰̸",
		"NotSucceedsSlantEqual": "⋡",
		"NotSucceedsTilde": "≿̸",
		"NotSuperset": "⊃⃒",
		"NotSupersetEqual": "⊉",
		"NotTilde": "≁",
		"NotTildeEqual": "≄",
		"NotTildeFullEqual": "≇",
		"NotTildeTilde": "≉",
		"NotVerticalBar": "∤",
		"nparallel": "∦",
		"npar": "∦",
		"nparsl": "⫽⃥",
		"npart": "∂̸",
		"npolint": "⨔",
		"npr": "⊀",
		"nprcue": "⋠",
		"nprec": "⊀",
		"npreceq": "⪯̸",
		"npre": "⪯̸",
		"nrarrc": "⤳̸",
		"nrarr": "↛",
		"nrArr": "⇏",
		"nrarrw": "↝̸",
		"nrightarrow": "↛",
		"nRightarrow": "⇏",
		"nrtri": "⋫",
		"nrtrie": "⋭",
		"nsc": "⊁",
		"nsccue": "⋡",
		"nsce": "⪰̸",
		"Nscr": "𝒩",
		"nscr": "𝓃",
		"nshortmid": "∤",
		"nshortparallel": "∦",
		"nsim": "≁",
		"nsime": "≄",
		"nsimeq": "≄",
		"nsmid": "∤",
		"nspar": "∦",
		"nsqsube": "⋢",
		"nsqsupe": "⋣",
		"nsub": "⊄",
		"nsubE": "⫅̸",
		"nsube": "⊈",
		"nsubset": "⊂⃒",
		"nsubseteq": "⊈",
		"nsubseteqq": "⫅̸",
		"nsucc": "⊁",
		"nsucceq": "⪰̸",
		"nsup": "⊅",
		"nsupE": "⫆̸",
		"nsupe": "⊉",
		"nsupset": "⊃⃒",
		"nsupseteq": "⊉",
		"nsupseteqq": "⫆̸",
		"ntgl": "≹",
		"Ntilde": "Ñ",
		"ntilde": "ñ",
		"ntlg": "≸",
		"ntriangleleft": "⋪",
		"ntrianglelefteq": "⋬",
		"ntriangleright": "⋫",
		"ntrianglerighteq": "⋭",
		"Nu": "Ν",
		"nu": "ν",
		"num": "#",
		"numero": "№",
		"numsp": " ",
		"nvap": "≍⃒",
		"nvdash": "⊬",
		"nvDash": "⊭",
		"nVdash": "⊮",
		"nVDash": "⊯",
		"nvge": "≥⃒",
		"nvgt": ">⃒",
		"nvHarr": "⤄",
		"nvinfin": "⧞",
		"nvlArr": "⤂",
		"nvle": "≤⃒",
		"nvlt": "<⃒",
		"nvltrie": "⊴⃒",
		"nvrArr": "⤃",
		"nvrtrie": "⊵⃒",
		"nvsim": "∼⃒",
		"nwarhk": "⤣",
		"nwarr": "↖",
		"nwArr": "⇖",
		"nwarrow": "↖",
		"nwnear": "⤧",
		"Oacute": "Ó",
		"oacute": "ó",
		"oast": "⊛",
		"Ocirc": "Ô",
		"ocirc": "ô",
		"ocir": "⊚",
		"Ocy": "О",
		"ocy": "о",
		"odash": "⊝",
		"Odblac": "Ő",
		"odblac": "ő",
		"odiv": "⨸",
		"odot": "⊙",
		"odsold": "⦼",
		"OElig": "Œ",
		"oelig": "œ",
		"ofcir": "⦿",
		"Ofr": "𝔒",
		"ofr": "𝔬",
		"ogon": "˛",
		"Ograve": "Ò",
		"ograve": "ò",
		"ogt": "⧁",
		"ohbar": "⦵",
		"ohm": "Ω",
		"oint": "∮",
		"olarr": "↺",
		"olcir": "⦾",
		"olcross": "⦻",
		"oline": "‾",
		"olt": "⧀",
		"Omacr": "Ō",
		"omacr": "ō",
		"Omega": "Ω",
		"omega": "ω",
		"Omicron": "Ο",
		"omicron": "ο",
		"omid": "⦶",
		"ominus": "⊖",
		"Oopf": "𝕆",
		"oopf": "𝕠",
		"opar": "⦷",
		"OpenCurlyDoubleQuote": "“",
		"OpenCurlyQuote": "‘",
		"operp": "⦹",
		"oplus": "⊕",
		"orarr": "↻",
		"Or": "⩔",
		"or": "∨",
		"ord": "⩝",
		"order": "ℴ",
		"orderof": "ℴ",
		"ordf": "ª",
		"ordm": "º",
		"origof": "⊶",
		"oror": "⩖",
		"orslope": "⩗",
		"orv": "⩛",
		"oS": "Ⓢ",
		"Oscr": "𝒪",
		"oscr": "ℴ",
		"Oslash": "Ø",
		"oslash": "ø",
		"osol": "⊘",
		"Otilde": "Õ",
		"otilde": "õ",
		"otimesas": "⨶",
		"Otimes": "⨷",
		"otimes": "⊗",
		"Ouml": "Ö",
		"ouml": "ö",
		"ovbar": "⌽",
		"OverBar": "‾",
		"OverBrace": "⏞",
		"OverBracket": "⎴",
		"OverParenthesis": "⏜",
		"para": "¶",
		"parallel": "∥",
		"par": "∥",
		"parsim": "⫳",
		"parsl": "⫽",
		"part": "∂",
		"PartialD": "∂",
		"Pcy": "П",
		"pcy": "п",
		"percnt": "%",
		"period": ".",
		"permil": "‰",
		"perp": "⊥",
		"pertenk": "‱",
		"Pfr": "𝔓",
		"pfr": "𝔭",
		"Phi": "Φ",
		"phi": "φ",
		"phiv": "ϕ",
		"phmmat": "ℳ",
		"phone": "☎",
		"Pi": "Π",
		"pi": "π",
		"pitchfork": "⋔",
		"piv": "ϖ",
		"planck": "ℏ",
		"planckh": "ℎ",
		"plankv": "ℏ",
		"plusacir": "⨣",
		"plusb": "⊞",
		"pluscir": "⨢",
		"plus": "+",
		"plusdo": "∔",
		"plusdu": "⨥",
		"pluse": "⩲",
		"PlusMinus": "±",
		"plusmn": "±",
		"plussim": "⨦",
		"plustwo": "⨧",
		"pm": "±",
		"Poincareplane": "ℌ",
		"pointint": "⨕",
		"popf": "𝕡",
		"Popf": "ℙ",
		"pound": "£",
		"prap": "⪷",
		"Pr": "⪻",
		"pr": "≺",
		"prcue": "≼",
		"precapprox": "⪷",
		"prec": "≺",
		"preccurlyeq": "≼",
		"Precedes": "≺",
		"PrecedesEqual": "⪯",
		"PrecedesSlantEqual": "≼",
		"PrecedesTilde": "≾",
		"preceq": "⪯",
		"precnapprox": "⪹",
		"precneqq": "⪵",
		"precnsim": "⋨",
		"pre": "⪯",
		"prE": "⪳",
		"precsim": "≾",
		"prime": "′",
		"Prime": "″",
		"primes": "ℙ",
		"prnap": "⪹",
		"prnE": "⪵",
		"prnsim": "⋨",
		"prod": "∏",
		"Product": "∏",
		"profalar": "⌮",
		"profline": "⌒",
		"profsurf": "⌓",
		"prop": "∝",
		"Proportional": "∝",
		"Proportion": "∷",
		"propto": "∝",
		"prsim": "≾",
		"prurel": "⊰",
		"Pscr": "𝒫",
		"pscr": "𝓅",
		"Psi": "Ψ",
		"psi": "ψ",
		"puncsp": " ",
		"Qfr": "𝔔",
		"qfr": "𝔮",
		"qint": "⨌",
		"qopf": "𝕢",
		"Qopf": "ℚ",
		"qprime": "⁗",
		"Qscr": "𝒬",
		"qscr": "𝓆",
		"quaternions": "ℍ",
		"quatint": "⨖",
		"quest": "?",
		"questeq": "≟",
		"quot": "\"",
		"QUOT": "\"",
		"rAarr": "⇛",
		"race": "∽̱",
		"Racute": "Ŕ",
		"racute": "ŕ",
		"radic": "√",
		"raemptyv": "⦳",
		"rang": "⟩",
		"Rang": "⟫",
		"rangd": "⦒",
		"range": "⦥",
		"rangle": "⟩",
		"raquo": "»",
		"rarrap": "⥵",
		"rarrb": "⇥",
		"rarrbfs": "⤠",
		"rarrc": "⤳",
		"rarr": "→",
		"Rarr": "↠",
		"rArr": "⇒",
		"rarrfs": "⤞",
		"rarrhk": "↪",
		"rarrlp": "↬",
		"rarrpl": "⥅",
		"rarrsim": "⥴",
		"Rarrtl": "⤖",
		"rarrtl": "↣",
		"rarrw": "↝",
		"ratail": "⤚",
		"rAtail": "⤜",
		"ratio": "∶",
		"rationals": "ℚ",
		"rbarr": "⤍",
		"rBarr": "⤏",
		"RBarr": "⤐",
		"rbbrk": "❳",
		"rbrace": "}",
		"rbrack": "]",
		"rbrke": "⦌",
		"rbrksld": "⦎",
		"rbrkslu": "⦐",
		"Rcaron": "Ř",
		"rcaron": "ř",
		"Rcedil": "Ŗ",
		"rcedil": "ŗ",
		"rceil": "⌉",
		"rcub": "}",
		"Rcy": "Р",
		"rcy": "р",
		"rdca": "⤷",
		"rdldhar": "⥩",
		"rdquo": "”",
		"rdquor": "”",
		"rdsh": "↳",
		"real": "ℜ",
		"realine": "ℛ",
		"realpart": "ℜ",
		"reals": "ℝ",
		"Re": "ℜ",
		"rect": "▭",
		"reg": "®",
		"REG": "®",
		"ReverseElement": "∋",
		"ReverseEquilibrium": "⇋",
		"ReverseUpEquilibrium": "⥯",
		"rfisht": "⥽",
		"rfloor": "⌋",
		"rfr": "𝔯",
		"Rfr": "ℜ",
		"rHar": "⥤",
		"rhard": "⇁",
		"rharu": "⇀",
		"rharul": "⥬",
		"Rho": "Ρ",
		"rho": "ρ",
		"rhov": "ϱ",
		"RightAngleBracket": "⟩",
		"RightArrowBar": "⇥",
		"rightarrow": "→",
		"RightArrow": "→",
		"Rightarrow": "⇒",
		"RightArrowLeftArrow": "⇄",
		"rightarrowtail": "↣",
		"RightCeiling": "⌉",
		"RightDoubleBracket": "⟧",
		"RightDownTeeVector": "⥝",
		"RightDownVectorBar": "⥕",
		"RightDownVector": "⇂",
		"RightFloor": "⌋",
		"rightharpoondown": "⇁",
		"rightharpoonup": "⇀",
		"rightleftarrows": "⇄",
		"rightleftharpoons": "⇌",
		"rightrightarrows": "⇉",
		"rightsquigarrow": "↝",
		"RightTeeArrow": "↦",
		"RightTee": "⊢",
		"RightTeeVector": "⥛",
		"rightthreetimes": "⋌",
		"RightTriangleBar": "⧐",
		"RightTriangle": "⊳",
		"RightTriangleEqual": "⊵",
		"RightUpDownVector": "⥏",
		"RightUpTeeVector": "⥜",
		"RightUpVectorBar": "⥔",
		"RightUpVector": "↾",
		"RightVectorBar": "⥓",
		"RightVector": "⇀",
		"ring": "˚",
		"risingdotseq": "≓",
		"rlarr": "⇄",
		"rlhar": "⇌",
		"rlm": "‏",
		"rmoustache": "⎱",
		"rmoust": "⎱",
		"rnmid": "⫮",
		"roang": "⟭",
		"roarr": "⇾",
		"robrk": "⟧",
		"ropar": "⦆",
		"ropf": "𝕣",
		"Ropf": "ℝ",
		"roplus": "⨮",
		"rotimes": "⨵",
		"RoundImplies": "⥰",
		"rpar": ")",
		"rpargt": "⦔",
		"rppolint": "⨒",
		"rrarr": "⇉",
		"Rrightarrow": "⇛",
		"rsaquo": "›",
		"rscr": "𝓇",
		"Rscr": "ℛ",
		"rsh": "↱",
		"Rsh": "↱",
		"rsqb": "]",
		"rsquo": "’",
		"rsquor": "’",
		"rthree": "⋌",
		"rtimes": "⋊",
		"rtri": "▹",
		"rtrie": "⊵",
		"rtrif": "▸",
		"rtriltri": "⧎",
		"RuleDelayed": "⧴",
		"ruluhar": "⥨",
		"rx": "℞",
		"Sacute": "Ś",
		"sacute": "ś",
		"sbquo": "‚",
		"scap": "⪸",
		"Scaron": "Š",
		"scaron": "š",
		"Sc": "⪼",
		"sc": "≻",
		"sccue": "≽",
		"sce": "⪰",
		"scE": "⪴",
		"Scedil": "Ş",
		"scedil": "ş",
		"Scirc": "Ŝ",
		"scirc": "ŝ",
		"scnap": "⪺",
		"scnE": "⪶",
		"scnsim": "⋩",
		"scpolint": "⨓",
		"scsim": "≿",
		"Scy": "С",
		"scy": "с",
		"sdotb": "⊡",
		"sdot": "⋅",
		"sdote": "⩦",
		"searhk": "⤥",
		"searr": "↘",
		"seArr": "⇘",
		"searrow": "↘",
		"sect": "§",
		"semi": ";",
		"seswar": "⤩",
		"setminus": "∖",
		"setmn": "∖",
		"sext": "✶",
		"Sfr": "𝔖",
		"sfr": "𝔰",
		"sfrown": "⌢",
		"sharp": "♯",
		"SHCHcy": "Щ",
		"shchcy": "щ",
		"SHcy": "Ш",
		"shcy": "ш",
		"ShortDownArrow": "↓",
		"ShortLeftArrow": "←",
		"shortmid": "∣",
		"shortparallel": "∥",
		"ShortRightArrow": "→",
		"ShortUpArrow": "↑",
		"shy": "­",
		"Sigma": "Σ",
		"sigma": "σ",
		"sigmaf": "ς",
		"sigmav": "ς",
		"sim": "∼",
		"simdot": "⩪",
		"sime": "≃",
		"simeq": "≃",
		"simg": "⪞",
		"simgE": "⪠",
		"siml": "⪝",
		"simlE": "⪟",
		"simne": "≆",
		"simplus": "⨤",
		"simrarr": "⥲",
		"slarr": "←",
		"SmallCircle": "∘",
		"smallsetminus": "∖",
		"smashp": "⨳",
		"smeparsl": "⧤",
		"smid": "∣",
		"smile": "⌣",
		"smt": "⪪",
		"smte": "⪬",
		"smtes": "⪬︀",
		"SOFTcy": "Ь",
		"softcy": "ь",
		"solbar": "⌿",
		"solb": "⧄",
		"sol": "/",
		"Sopf": "𝕊",
		"sopf": "𝕤",
		"spades": "♠",
		"spadesuit": "♠",
		"spar": "∥",
		"sqcap": "⊓",
		"sqcaps": "⊓︀",
		"sqcup": "⊔",
		"sqcups": "⊔︀",
		"Sqrt": "√",
		"sqsub": "⊏",
		"sqsube": "⊑",
		"sqsubset": "⊏",
		"sqsubseteq": "⊑",
		"sqsup": "⊐",
		"sqsupe": "⊒",
		"sqsupset": "⊐",
		"sqsupseteq": "⊒",
		"square": "□",
		"Square": "□",
		"SquareIntersection": "⊓",
		"SquareSubset": "⊏",
		"SquareSubsetEqual": "⊑",
		"SquareSuperset": "⊐",
		"SquareSupersetEqual": "⊒",
		"SquareUnion": "⊔",
		"squarf": "▪",
		"squ": "□",
		"squf": "▪",
		"srarr": "→",
		"Sscr": "𝒮",
		"sscr": "𝓈",
		"ssetmn": "∖",
		"ssmile": "⌣",
		"sstarf": "⋆",
		"Star": "⋆",
		"star": "☆",
		"starf": "★",
		"straightepsilon": "ϵ",
		"straightphi": "ϕ",
		"strns": "¯",
		"sub": "⊂",
		"Sub": "⋐",
		"subdot": "⪽",
		"subE": "⫅",
		"sube": "⊆",
		"subedot": "⫃",
		"submult": "⫁",
		"subnE": "⫋",
		"subne": "⊊",
		"subplus": "⪿",
		"subrarr": "⥹",
		"subset": "⊂",
		"Subset": "⋐",
		"subseteq": "⊆",
		"subseteqq": "⫅",
		"SubsetEqual": "⊆",
		"subsetneq": "⊊",
		"subsetneqq": "⫋",
		"subsim": "⫇",
		"subsub": "⫕",
		"subsup": "⫓",
		"succapprox": "⪸",
		"succ": "≻",
		"succcurlyeq": "≽",
		"Succeeds": "≻",
		"SucceedsEqual": "⪰",
		"SucceedsSlantEqual": "≽",
		"SucceedsTilde": "≿",
		"succeq": "⪰",
		"succnapprox": "⪺",
		"succneqq": "⪶",
		"succnsim": "⋩",
		"succsim": "≿",
		"SuchThat": "∋",
		"sum": "∑",
		"Sum": "∑",
		"sung": "♪",
		"sup1": "¹",
		"sup2": "²",
		"sup3": "³",
		"sup": "⊃",
		"Sup": "⋑",
		"supdot": "⪾",
		"supdsub": "⫘",
		"supE": "⫆",
		"supe": "⊇",
		"supedot": "⫄",
		"Superset": "⊃",
		"SupersetEqual": "⊇",
		"suphsol": "⟉",
		"suphsub": "⫗",
		"suplarr": "⥻",
		"supmult": "⫂",
		"supnE": "⫌",
		"supne": "⊋",
		"supplus": "⫀",
		"supset": "⊃",
		"Supset": "⋑",
		"supseteq": "⊇",
		"supseteqq": "⫆",
		"supsetneq": "⊋",
		"supsetneqq": "⫌",
		"supsim": "⫈",
		"supsub": "⫔",
		"supsup": "⫖",
		"swarhk": "⤦",
		"swarr": "↙",
		"swArr": "⇙",
		"swarrow": "↙",
		"swnwar": "⤪",
		"szlig": "ß",
		"Tab": "\t",
		"target": "⌖",
		"Tau": "Τ",
		"tau": "τ",
		"tbrk": "⎴",
		"Tcaron": "Ť",
		"tcaron": "ť",
		"Tcedil": "Ţ",
		"tcedil": "ţ",
		"Tcy": "Т",
		"tcy": "т",
		"tdot": "⃛",
		"telrec": "⌕",
		"Tfr": "𝔗",
		"tfr": "𝔱",
		"there4": "∴",
		"therefore": "∴",
		"Therefore": "∴",
		"Theta": "Θ",
		"theta": "θ",
		"thetasym": "ϑ",
		"thetav": "ϑ",
		"thickapprox": "≈",
		"thicksim": "∼",
		"ThickSpace": "  ",
		"ThinSpace": " ",
		"thinsp": " ",
		"thkap": "≈",
		"thksim": "∼",
		"THORN": "Þ",
		"thorn": "þ",
		"tilde": "˜",
		"Tilde": "∼",
		"TildeEqual": "≃",
		"TildeFullEqual": "≅",
		"TildeTilde": "≈",
		"timesbar": "⨱",
		"timesb": "⊠",
		"times": "×",
		"timesd": "⨰",
		"tint": "∭",
		"toea": "⤨",
		"topbot": "⌶",
		"topcir": "⫱",
		"top": "⊤",
		"Topf": "𝕋",
		"topf": "𝕥",
		"topfork": "⫚",
		"tosa": "⤩",
		"tprime": "‴",
		"trade": "™",
		"TRADE": "™",
		"triangle": "▵",
		"triangledown": "▿",
		"triangleleft": "◃",
		"trianglelefteq": "⊴",
		"triangleq": "≜",
		"triangleright": "▹",
		"trianglerighteq": "⊵",
		"tridot": "◬",
		"trie": "≜",
		"triminus": "⨺",
		"TripleDot": "⃛",
		"triplus": "⨹",
		"trisb": "⧍",
		"tritime": "⨻",
		"trpezium": "⏢",
		"Tscr": "𝒯",
		"tscr": "𝓉",
		"TScy": "Ц",
		"tscy": "ц",
		"TSHcy": "Ћ",
		"tshcy": "ћ",
		"Tstrok": "Ŧ",
		"tstrok": "ŧ",
		"twixt": "≬",
		"twoheadleftarrow": "↞",
		"twoheadrightarrow": "↠",
		"Uacute": "Ú",
		"uacute": "ú",
		"uarr": "↑",
		"Uarr": "↟",
		"uArr": "⇑",
		"Uarrocir": "⥉",
		"Ubrcy": "Ў",
		"ubrcy": "ў",
		"Ubreve": "Ŭ",
		"ubreve": "ŭ",
		"Ucirc": "Û",
		"ucirc": "û",
		"Ucy": "У",
		"ucy": "у",
		"udarr": "⇅",
		"Udblac": "Ű",
		"udblac": "ű",
		"udhar": "⥮",
		"ufisht": "⥾",
		"Ufr": "𝔘",
		"ufr": "𝔲",
		"Ugrave": "Ù",
		"ugrave": "ù",
		"uHar": "⥣",
		"uharl": "↿",
		"uharr": "↾",
		"uhblk": "▀",
		"ulcorn": "⌜",
		"ulcorner": "⌜",
		"ulcrop": "⌏",
		"ultri": "◸",
		"Umacr": "Ū",
		"umacr": "ū",
		"uml": "¨",
		"UnderBar": "_",
		"UnderBrace": "⏟",
		"UnderBracket": "⎵",
		"UnderParenthesis": "⏝",
		"Union": "⋃",
		"UnionPlus": "⊎",
		"Uogon": "Ų",
		"uogon": "ų",
		"Uopf": "𝕌",
		"uopf": "𝕦",
		"UpArrowBar": "⤒",
		"uparrow": "↑",
		"UpArrow": "↑",
		"Uparrow": "⇑",
		"UpArrowDownArrow": "⇅",
		"updownarrow": "↕",
		"UpDownArrow": "↕",
		"Updownarrow": "⇕",
		"UpEquilibrium": "⥮",
		"upharpoonleft": "↿",
		"upharpoonright": "↾",
		"uplus": "⊎",
		"UpperLeftArrow": "↖",
		"UpperRightArrow": "↗",
		"upsi": "υ",
		"Upsi": "ϒ",
		"upsih": "ϒ",
		"Upsilon": "Υ",
		"upsilon": "υ",
		"UpTeeArrow": "↥",
		"UpTee": "⊥",
		"upuparrows": "⇈",
		"urcorn": "⌝",
		"urcorner": "⌝",
		"urcrop": "⌎",
		"Uring": "Ů",
		"uring": "ů",
		"urtri": "◹",
		"Uscr": "𝒰",
		"uscr": "𝓊",
		"utdot": "⋰",
		"Utilde": "Ũ",
		"utilde": "ũ",
		"utri": "▵",
		"utrif": "▴",
		"uuarr": "⇈",
		"Uuml": "Ü",
		"uuml": "ü",
		"uwangle": "⦧",
		"vangrt": "⦜",
		"varepsilon": "ϵ",
		"varkappa": "ϰ",
		"varnothing": "∅",
		"varphi": "ϕ",
		"varpi": "ϖ",
		"varpropto": "∝",
		"varr": "↕",
		"vArr": "⇕",
		"varrho": "ϱ",
		"varsigma": "ς",
		"varsubsetneq": "⊊︀",
		"varsubsetneqq": "⫋︀",
		"varsupsetneq": "⊋︀",
		"varsupsetneqq": "⫌︀",
		"vartheta": "ϑ",
		"vartriangleleft": "⊲",
		"vartriangleright": "⊳",
		"vBar": "⫨",
		"Vbar": "⫫",
		"vBarv": "⫩",
		"Vcy": "В",
		"vcy": "в",
		"vdash": "⊢",
		"vDash": "⊨",
		"Vdash": "⊩",
		"VDash": "⊫",
		"Vdashl": "⫦",
		"veebar": "⊻",
		"vee": "∨",
		"Vee": "⋁",
		"veeeq": "≚",
		"vellip": "⋮",
		"verbar": "|",
		"Verbar": "‖",
		"vert": "|",
		"Vert": "‖",
		"VerticalBar": "∣",
		"VerticalLine": "|",
		"VerticalSeparator": "❘",
		"VerticalTilde": "≀",
		"VeryThinSpace": " ",
		"Vfr": "𝔙",
		"vfr": "𝔳",
		"vltri": "⊲",
		"vnsub": "⊂⃒",
		"vnsup": "⊃⃒",
		"Vopf": "𝕍",
		"vopf": "𝕧",
		"vprop": "∝",
		"vrtri": "⊳",
		"Vscr": "𝒱",
		"vscr": "𝓋",
		"vsubnE": "⫋︀",
		"vsubne": "⊊︀",
		"vsupnE": "⫌︀",
		"vsupne": "⊋︀",
		"Vvdash": "⊪",
		"vzigzag": "⦚",
		"Wcirc": "Ŵ",
		"wcirc": "ŵ",
		"wedbar": "⩟",
		"wedge": "∧",
		"Wedge": "⋀",
		"wedgeq": "≙",
		"weierp": "℘",
		"Wfr": "𝔚",
		"wfr": "𝔴",
		"Wopf": "𝕎",
		"wopf": "𝕨",
		"wp": "℘",
		"wr": "≀",
		"wreath": "≀",
		"Wscr": "𝒲",
		"wscr": "𝓌",
		"xcap": "⋂",
		"xcirc": "◯",
		"xcup": "⋃",
		"xdtri": "▽",
		"Xfr": "𝔛",
		"xfr": "𝔵",
		"xharr": "⟷",
		"xhArr": "⟺",
		"Xi": "Ξ",
		"xi": "ξ",
		"xlarr": "⟵",
		"xlArr": "⟸",
		"xmap": "⟼",
		"xnis": "⋻",
		"xodot": "⨀",
		"Xopf": "𝕏",
		"xopf": "𝕩",
		"xoplus": "⨁",
		"xotime": "⨂",
		"xrarr": "⟶",
		"xrArr": "⟹",
		"Xscr": "𝒳",
		"xscr": "𝓍",
		"xsqcup": "⨆",
		"xuplus": "⨄",
		"xutri": "△",
		"xvee": "⋁",
		"xwedge": "⋀",
		"Yacute": "Ý",
		"yacute": "ý",
		"YAcy": "Я",
		"yacy": "я",
		"Ycirc": "Ŷ",
		"ycirc": "ŷ",
		"Ycy": "Ы",
		"ycy": "ы",
		"yen": "¥",
		"Yfr": "𝔜",
		"yfr": "𝔶",
		"YIcy": "Ї",
		"yicy": "ї",
		"Yopf": "𝕐",
		"yopf": "𝕪",
		"Yscr": "𝒴",
		"yscr": "𝓎",
		"YUcy": "Ю",
		"yucy": "ю",
		"yuml": "ÿ",
		"Yuml": "Ÿ",
		"Zacute": "Ź",
		"zacute": "ź",
		"Zcaron": "Ž",
		"zcaron": "ž",
		"Zcy": "З",
		"zcy": "з",
		"Zdot": "Ż",
		"zdot": "ż",
		"zeetrf": "ℨ",
		"ZeroWidthSpace": "​",
		"Zeta": "Ζ",
		"zeta": "ζ",
		"zfr": "𝔷",
		"Zfr": "ℨ",
		"ZHcy": "Ж",
		"zhcy": "ж",
		"zigrarr": "⇝",
		"zopf": "𝕫",
		"Zopf": "ℤ",
		"Zscr": "𝒵",
		"zscr": "𝓏",
		"zwj": "‍",
		"zwnj": "‌"
	};
})
/** END DEFINE BLOCK for entities@1.1.1/maps/entities.json **/


/** START DEFINE BLOCK for entities@1.1.1/maps/legacy.json **/
jupyter.define('entities@1.1.1/maps/legacy.json', function (module, exports, __jupyter_require__) {
	module.exports = {
		"Aacute": "Á",
		"aacute": "á",
		"Acirc": "Â",
		"acirc": "â",
		"acute": "´",
		"AElig": "Æ",
		"aelig": "æ",
		"Agrave": "À",
		"agrave": "à",
		"amp": "&",
		"AMP": "&",
		"Aring": "Å",
		"aring": "å",
		"Atilde": "Ã",
		"atilde": "ã",
		"Auml": "Ä",
		"auml": "ä",
		"brvbar": "¦",
		"Ccedil": "Ç",
		"ccedil": "ç",
		"cedil": "¸",
		"cent": "¢",
		"copy": "©",
		"COPY": "©",
		"curren": "¤",
		"deg": "°",
		"divide": "÷",
		"Eacute": "É",
		"eacute": "é",
		"Ecirc": "Ê",
		"ecirc": "ê",
		"Egrave": "È",
		"egrave": "è",
		"ETH": "Ð",
		"eth": "ð",
		"Euml": "Ë",
		"euml": "ë",
		"frac12": "½",
		"frac14": "¼",
		"frac34": "¾",
		"gt": ">",
		"GT": ">",
		"Iacute": "Í",
		"iacute": "í",
		"Icirc": "Î",
		"icirc": "î",
		"iexcl": "¡",
		"Igrave": "Ì",
		"igrave": "ì",
		"iquest": "¿",
		"Iuml": "Ï",
		"iuml": "ï",
		"laquo": "«",
		"lt": "<",
		"LT": "<",
		"macr": "¯",
		"micro": "µ",
		"middot": "·",
		"nbsp": " ",
		"not": "¬",
		"Ntilde": "Ñ",
		"ntilde": "ñ",
		"Oacute": "Ó",
		"oacute": "ó",
		"Ocirc": "Ô",
		"ocirc": "ô",
		"Ograve": "Ò",
		"ograve": "ò",
		"ordf": "ª",
		"ordm": "º",
		"Oslash": "Ø",
		"oslash": "ø",
		"Otilde": "Õ",
		"otilde": "õ",
		"Ouml": "Ö",
		"ouml": "ö",
		"para": "¶",
		"plusmn": "±",
		"pound": "£",
		"quot": "\"",
		"QUOT": "\"",
		"raquo": "»",
		"reg": "®",
		"REG": "®",
		"sect": "§",
		"shy": "­",
		"sup1": "¹",
		"sup2": "²",
		"sup3": "³",
		"szlig": "ß",
		"THORN": "Þ",
		"thorn": "þ",
		"times": "×",
		"Uacute": "Ú",
		"uacute": "ú",
		"Ucirc": "Û",
		"ucirc": "û",
		"Ugrave": "Ù",
		"ugrave": "ù",
		"uml": "¨",
		"Uuml": "Ü",
		"uuml": "ü",
		"Yacute": "Ý",
		"yacute": "ý",
		"yen": "¥",
		"yuml": "ÿ"
	};
})
/** END DEFINE BLOCK for entities@1.1.1/maps/legacy.json **/


/** START DEFINE BLOCK for entities@1.1.1/maps/xml.json **/
jupyter.define('entities@1.1.1/maps/xml.json', function (module, exports, __jupyter_require__) {
	module.exports = {
		"amp": "&",
		"apos": "'",
		"gt": ">",
		"lt": "<",
		"quot": "\""
	};
})
/** END DEFINE BLOCK for entities@1.1.1/maps/xml.json **/


/** START DEFINE BLOCK for inherits@2.0.3/inherits_browser.js **/
jupyter.define('inherits@2.0.3/inherits_browser.js', function (module, exports, __jupyter_require__) {
	if (typeof Object.create === 'function') {
	  // implementation from standard node.js 'util' module
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    ctor.prototype = Object.create(superCtor.prototype, {
	      constructor: {
	        value: ctor,
	        enumerable: false,
	        writable: true,
	        configurable: true
	      }
	    });
	  };
	} else {
	  // old school shim for old browsers
	  module.exports = function inherits(ctor, superCtor) {
	    ctor.super_ = superCtor
	    var TempCtor = function () {}
	    TempCtor.prototype = superCtor.prototype
	    ctor.prototype = new TempCtor()
	    ctor.prototype.constructor = ctor
	  }
	}
	
})
/** END DEFINE BLOCK for inherits@2.0.3/inherits_browser.js **/


/** START DEFINE BLOCK for events@1.1.1/events.js **/
jupyter.define('events@1.1.1/events.js', function (module, exports, __jupyter_require__) {
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	function EventEmitter() {
	  this._events = this._events || {};
	  this._maxListeners = this._maxListeners || undefined;
	}
	module.exports = EventEmitter;
	
	// Backwards-compat with node 0.10.x
	EventEmitter.EventEmitter = EventEmitter;
	
	EventEmitter.prototype._events = undefined;
	EventEmitter.prototype._maxListeners = undefined;
	
	// By default EventEmitters will print a warning if more than 10 listeners are
	// added to it. This is a useful default which helps finding memory leaks.
	EventEmitter.defaultMaxListeners = 10;
	
	// Obviously not all Emitters should be limited to 10. This function allows
	// that to be increased. Set to zero for unlimited.
	EventEmitter.prototype.setMaxListeners = function(n) {
	  if (!isNumber(n) || n < 0 || isNaN(n))
	    throw TypeError('n must be a positive number');
	  this._maxListeners = n;
	  return this;
	};
	
	EventEmitter.prototype.emit = function(type) {
	  var er, handler, len, args, i, listeners;
	
	  if (!this._events)
	    this._events = {};
	
	  // If there is no 'error' event listener then throw.
	  if (type === 'error') {
	    if (!this._events.error ||
	        (isObject(this._events.error) && !this._events.error.length)) {
	      er = arguments[1];
	      if (er instanceof Error) {
	        throw er; // Unhandled 'error' event
	      } else {
	        // At least give some kind of context to the user
	        var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
	        err.context = er;
	        throw err;
	      }
	    }
	  }
	
	  handler = this._events[type];
	
	  if (isUndefined(handler))
	    return false;
	
	  if (isFunction(handler)) {
	    switch (arguments.length) {
	      // fast cases
	      case 1:
	        handler.call(this);
	        break;
	      case 2:
	        handler.call(this, arguments[1]);
	        break;
	      case 3:
	        handler.call(this, arguments[1], arguments[2]);
	        break;
	      // slower
	      default:
	        args = Array.prototype.slice.call(arguments, 1);
	        handler.apply(this, args);
	    }
	  } else if (isObject(handler)) {
	    args = Array.prototype.slice.call(arguments, 1);
	    listeners = handler.slice();
	    len = listeners.length;
	    for (i = 0; i < len; i++)
	      listeners[i].apply(this, args);
	  }
	
	  return true;
	};
	
	EventEmitter.prototype.addListener = function(type, listener) {
	  var m;
	
	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');
	
	  if (!this._events)
	    this._events = {};
	
	  // To avoid recursion in the case that type === "newListener"! Before
	  // adding it to the listeners, first emit "newListener".
	  if (this._events.newListener)
	    this.emit('newListener', type,
	              isFunction(listener.listener) ?
	              listener.listener : listener);
	
	  if (!this._events[type])
	    // Optimize the case of one listener. Don't need the extra array object.
	    this._events[type] = listener;
	  else if (isObject(this._events[type]))
	    // If we've already got an array, just append.
	    this._events[type].push(listener);
	  else
	    // Adding the second element, need to change to array.
	    this._events[type] = [this._events[type], listener];
	
	  // Check for listener leak
	  if (isObject(this._events[type]) && !this._events[type].warned) {
	    if (!isUndefined(this._maxListeners)) {
	      m = this._maxListeners;
	    } else {
	      m = EventEmitter.defaultMaxListeners;
	    }
	
	    if (m && m > 0 && this._events[type].length > m) {
	      this._events[type].warned = true;
	      console.error('(node) warning: possible EventEmitter memory ' +
	                    'leak detected. %d listeners added. ' +
	                    'Use emitter.setMaxListeners() to increase limit.',
	                    this._events[type].length);
	      if (typeof console.trace === 'function') {
	        // not supported in IE 10
	        console.trace();
	      }
	    }
	  }
	
	  return this;
	};
	
	EventEmitter.prototype.on = EventEmitter.prototype.addListener;
	
	EventEmitter.prototype.once = function(type, listener) {
	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');
	
	  var fired = false;
	
	  function g() {
	    this.removeListener(type, g);
	
	    if (!fired) {
	      fired = true;
	      listener.apply(this, arguments);
	    }
	  }
	
	  g.listener = listener;
	  this.on(type, g);
	
	  return this;
	};
	
	// emits a 'removeListener' event iff the listener was removed
	EventEmitter.prototype.removeListener = function(type, listener) {
	  var list, position, length, i;
	
	  if (!isFunction(listener))
	    throw TypeError('listener must be a function');
	
	  if (!this._events || !this._events[type])
	    return this;
	
	  list = this._events[type];
	  length = list.length;
	  position = -1;
	
	  if (list === listener ||
	      (isFunction(list.listener) && list.listener === listener)) {
	    delete this._events[type];
	    if (this._events.removeListener)
	      this.emit('removeListener', type, listener);
	
	  } else if (isObject(list)) {
	    for (i = length; i-- > 0;) {
	      if (list[i] === listener ||
	          (list[i].listener && list[i].listener === listener)) {
	        position = i;
	        break;
	      }
	    }
	
	    if (position < 0)
	      return this;
	
	    if (list.length === 1) {
	      list.length = 0;
	      delete this._events[type];
	    } else {
	      list.splice(position, 1);
	    }
	
	    if (this._events.removeListener)
	      this.emit('removeListener', type, listener);
	  }
	
	  return this;
	};
	
	EventEmitter.prototype.removeAllListeners = function(type) {
	  var key, listeners;
	
	  if (!this._events)
	    return this;
	
	  // not listening for removeListener, no need to emit
	  if (!this._events.removeListener) {
	    if (arguments.length === 0)
	      this._events = {};
	    else if (this._events[type])
	      delete this._events[type];
	    return this;
	  }
	
	  // emit removeListener for all listeners on all events
	  if (arguments.length === 0) {
	    for (key in this._events) {
	      if (key === 'removeListener') continue;
	      this.removeAllListeners(key);
	    }
	    this.removeAllListeners('removeListener');
	    this._events = {};
	    return this;
	  }
	
	  listeners = this._events[type];
	
	  if (isFunction(listeners)) {
	    this.removeListener(type, listeners);
	  } else if (listeners) {
	    // LIFO order
	    while (listeners.length)
	      this.removeListener(type, listeners[listeners.length - 1]);
	  }
	  delete this._events[type];
	
	  return this;
	};
	
	EventEmitter.prototype.listeners = function(type) {
	  var ret;
	  if (!this._events || !this._events[type])
	    ret = [];
	  else if (isFunction(this._events[type]))
	    ret = [this._events[type]];
	  else
	    ret = this._events[type].slice();
	  return ret;
	};
	
	EventEmitter.prototype.listenerCount = function(type) {
	  if (this._events) {
	    var evlistener = this._events[type];
	
	    if (isFunction(evlistener))
	      return 1;
	    else if (evlistener)
	      return evlistener.length;
	  }
	  return 0;
	};
	
	EventEmitter.listenerCount = function(emitter, type) {
	  return emitter.listenerCount(type);
	};
	
	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	
	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	
	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	
	function isUndefined(arg) {
	  return arg === void 0;
	}
	
})
/** END DEFINE BLOCK for events@1.1.1/events.js **/


/** START DEFINE BLOCK for domhandler@2.4.1/index.js **/
jupyter.define('domhandler@2.4.1/index.js', function (module, exports, __jupyter_require__) {
	var ElementType = __jupyter_require__('domelementtype@1/index.js');
	
	var re_whitespace = /\s+/g;
	var NodePrototype = __jupyter_require__('domhandler@2.4.1/lib/node.js');
	var ElementPrototype = __jupyter_require__('domhandler@2.4.1/lib/element.js');
	
	function DomHandler(callback, options, elementCB){
		if(typeof callback === "object"){
			elementCB = options;
			options = callback;
			callback = null;
		} else if(typeof options === "function"){
			elementCB = options;
			options = defaultOpts;
		}
		this._callback = callback;
		this._options = options || defaultOpts;
		this._elementCB = elementCB;
		this.dom = [];
		this._done = false;
		this._tagStack = [];
		this._parser = this._parser || null;
	}
	
	//default options
	var defaultOpts = {
		normalizeWhitespace: false, //Replace all whitespace with single spaces
		withStartIndices: false, //Add startIndex properties to nodes
		withEndIndices: false, //Add endIndex properties to nodes
	};
	
	DomHandler.prototype.onparserinit = function(parser){
		this._parser = parser;
	};
	
	//Resets the handler back to starting state
	DomHandler.prototype.onreset = function(){
		DomHandler.call(this, this._callback, this._options, this._elementCB);
	};
	
	//Signals the handler that parsing is done
	DomHandler.prototype.onend = function(){
		if(this._done) return;
		this._done = true;
		this._parser = null;
		this._handleCallback(null);
	};
	
	DomHandler.prototype._handleCallback =
	DomHandler.prototype.onerror = function(error){
		if(typeof this._callback === "function"){
			this._callback(error, this.dom);
		} else {
			if(error) throw error;
		}
	};
	
	DomHandler.prototype.onclosetag = function(){
		//if(this._tagStack.pop().name !== name) this._handleCallback(Error("Tagname didn't match!"));
		
		var elem = this._tagStack.pop();
	
		if(this._options.withEndIndices){
			elem.endIndex = this._parser.endIndex;
		}
	
		if(this._elementCB) this._elementCB(elem);
	};
	
	DomHandler.prototype._createDomElement = function(properties){
		if (!this._options.withDomLvl1) return properties;
	
		var element;
		if (properties.type === "tag") {
			element = Object.create(ElementPrototype);
		} else {
			element = Object.create(NodePrototype);
		}
	
		for (var key in properties) {
			if (properties.hasOwnProperty(key)) {
				element[key] = properties[key];
			}
		}
	
		return element;
	};
	
	DomHandler.prototype._addDomElement = function(element){
		var parent = this._tagStack[this._tagStack.length - 1];
		var siblings = parent ? parent.children : this.dom;
		var previousSibling = siblings[siblings.length - 1];
	
		element.next = null;
	
		if(this._options.withStartIndices){
			element.startIndex = this._parser.startIndex;
		}
		if(this._options.withEndIndices){
			element.endIndex = this._parser.endIndex;
		}
	
		if(previousSibling){
			element.prev = previousSibling;
			previousSibling.next = element;
		} else {
			element.prev = null;
		}
	
		siblings.push(element);
		element.parent = parent || null;
	};
	
	DomHandler.prototype.onopentag = function(name, attribs){
		var properties = {
			type: name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag,
			name: name,
			attribs: attribs,
			children: []
		};
	
		var element = this._createDomElement(properties);
	
		this._addDomElement(element);
	
		this._tagStack.push(element);
	};
	
	DomHandler.prototype.ontext = function(data){
		//the ignoreWhitespace is officially dropped, but for now,
		//it's an alias for normalizeWhitespace
		var normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace;
	
		var lastTag;
	
		if(!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length-1]).type === ElementType.Text){
			if(normalize){
				lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
			} else {
				lastTag.data += data;
			}
		} else {
			if(
				this._tagStack.length &&
				(lastTag = this._tagStack[this._tagStack.length - 1]) &&
				(lastTag = lastTag.children[lastTag.children.length - 1]) &&
				lastTag.type === ElementType.Text
			){
				if(normalize){
					lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
				} else {
					lastTag.data += data;
				}
			} else {
				if(normalize){
					data = data.replace(re_whitespace, " ");
				}
	
				var element = this._createDomElement({
					data: data,
					type: ElementType.Text
				});
	
				this._addDomElement(element);
			}
		}
	};
	
	DomHandler.prototype.oncomment = function(data){
		var lastTag = this._tagStack[this._tagStack.length - 1];
	
		if(lastTag && lastTag.type === ElementType.Comment){
			lastTag.data += data;
			return;
		}
	
		var properties = {
			data: data,
			type: ElementType.Comment
		};
	
		var element = this._createDomElement(properties);
	
		this._addDomElement(element);
		this._tagStack.push(element);
	};
	
	DomHandler.prototype.oncdatastart = function(){
		var properties = {
			children: [{
				data: "",
				type: ElementType.Text
			}],
			type: ElementType.CDATA
		};
	
		var element = this._createDomElement(properties);
	
		this._addDomElement(element);
		this._tagStack.push(element);
	};
	
	DomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function(){
		this._tagStack.pop();
	};
	
	DomHandler.prototype.onprocessinginstruction = function(name, data){
		var element = this._createDomElement({
			name: name,
			data: data,
			type: ElementType.Directive
		});
	
		this._addDomElement(element);
	};
	
	module.exports = DomHandler;
	
})
/** END DEFINE BLOCK for domhandler@2.4.1/index.js **/


/** START DEFINE BLOCK for domelementtype@1.3.0/index.js **/
jupyter.define('domelementtype@1.3.0/index.js', function (module, exports, __jupyter_require__) {
	//Types of elements found in the DOM
	module.exports = {
		Text: "text", //Text
		Directive: "directive", //<? ... ?>
		Comment: "comment", //<!-- ... -->
		Script: "script", //<script> tags
		Style: "style", //<style> tags
		Tag: "tag", //Any tag
		CDATA: "cdata", //<![CDATA[ ... ]]>
		Doctype: "doctype",
	
		isTag: function(elem){
			return elem.type === "tag" || elem.type === "script" || elem.type === "style";
		}
	};
	
})
/** END DEFINE BLOCK for domelementtype@1.3.0/index.js **/


/** START DEFINE BLOCK for domhandler@2.4.1/lib/node.js **/
jupyter.define('domhandler@2.4.1/lib/node.js', function (module, exports, __jupyter_require__) {
	// This object will be used as the prototype for Nodes when creating a
	// DOM-Level-1-compliant structure.
	var NodePrototype = module.exports = {
		get firstChild() {
			var children = this.children;
			return children && children[0] || null;
		},
		get lastChild() {
			var children = this.children;
			return children && children[children.length - 1] || null;
		},
		get nodeType() {
			return nodeTypes[this.type] || nodeTypes.element;
		}
	};
	
	var domLvl1 = {
		tagName: "name",
		childNodes: "children",
		parentNode: "parent",
		previousSibling: "prev",
		nextSibling: "next",
		nodeValue: "data"
	};
	
	var nodeTypes = {
		element: 1,
		text: 3,
		cdata: 4,
		comment: 8
	};
	
	Object.keys(domLvl1).forEach(function(key) {
		var shorthand = domLvl1[key];
		Object.defineProperty(NodePrototype, key, {
			get: function() {
				return this[shorthand] || null;
			},
			set: function(val) {
				this[shorthand] = val;
				return val;
			}
		});
	});
	
})
/** END DEFINE BLOCK for domhandler@2.4.1/lib/node.js **/


/** START DEFINE BLOCK for domhandler@2.4.1/lib/element.js **/
jupyter.define('domhandler@2.4.1/lib/element.js', function (module, exports, __jupyter_require__) {
	// DOM-Level-1-compliant structure
	var NodePrototype = __jupyter_require__('domhandler@2.4.1/lib/node.js');
	var ElementPrototype = module.exports = Object.create(NodePrototype);
	
	var domLvl1 = {
		tagName: "name"
	};
	
	Object.keys(domLvl1).forEach(function(key) {
		var shorthand = domLvl1[key];
		Object.defineProperty(ElementPrototype, key, {
			get: function() {
				return this[shorthand] || null;
			},
			set: function(val) {
				this[shorthand] = val;
				return val;
			}
		});
	});
	
})
/** END DEFINE BLOCK for domhandler@2.4.1/lib/element.js **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/FeedHandler.js **/
jupyter.define('htmlparser2@3.9.2/lib/FeedHandler.js', function (module, exports, __jupyter_require__) {
	var index = __jupyter_require__('htmlparser2@3.9.2/lib/index.js'),
	    DomHandler = index.DomHandler,
	    DomUtils = index.DomUtils;
	
	//TODO: make this a streamable handler
	function FeedHandler(callback, options){
		this.init(callback, options);
	}
	
	__jupyter_require__('inherits@^2.0.1/inherits_browser.js')(FeedHandler, DomHandler);
	
	FeedHandler.prototype.init = DomHandler;
	
	function getElements(what, where){
		return DomUtils.getElementsByTagName(what, where, true);
	}
	function getOneElement(what, where){
		return DomUtils.getElementsByTagName(what, where, true, 1)[0];
	}
	function fetch(what, where, recurse){
		return DomUtils.getText(
			DomUtils.getElementsByTagName(what, where, recurse, 1)
		).trim();
	}
	
	function addConditionally(obj, prop, what, where, recurse){
		var tmp = fetch(what, where, recurse);
		if(tmp) obj[prop] = tmp;
	}
	
	var isValidFeed = function(value){
		return value === "rss" || value === "feed" || value === "rdf:RDF";
	};
	
	FeedHandler.prototype.onend = function(){
		var feed = {},
		    feedRoot = getOneElement(isValidFeed, this.dom),
		    tmp, childs;
	
		if(feedRoot){
			if(feedRoot.name === "feed"){
				childs = feedRoot.children;
	
				feed.type = "atom";
				addConditionally(feed, "id", "id", childs);
				addConditionally(feed, "title", "title", childs);
				if((tmp = getOneElement("link", childs)) && (tmp = tmp.attribs) && (tmp = tmp.href)) feed.link = tmp;
				addConditionally(feed, "description", "subtitle", childs);
				if((tmp = fetch("updated", childs))) feed.updated = new Date(tmp);
				addConditionally(feed, "author", "email", childs, true);
	
				feed.items = getElements("entry", childs).map(function(item){
					var entry = {}, tmp;
	
					item = item.children;
	
					addConditionally(entry, "id", "id", item);
					addConditionally(entry, "title", "title", item);
					if((tmp = getOneElement("link", item)) && (tmp = tmp.attribs) && (tmp = tmp.href)) entry.link = tmp;
					if((tmp = fetch("summary", item) || fetch("content", item))) entry.description = tmp;
					if((tmp = fetch("updated", item))) entry.pubDate = new Date(tmp);
					return entry;
				});
			} else {
				childs = getOneElement("channel", feedRoot.children).children;
	
				feed.type = feedRoot.name.substr(0, 3);
				feed.id = "";
				addConditionally(feed, "title", "title", childs);
				addConditionally(feed, "link", "link", childs);
				addConditionally(feed, "description", "description", childs);
				if((tmp = fetch("lastBuildDate", childs))) feed.updated = new Date(tmp);
				addConditionally(feed, "author", "managingEditor", childs, true);
	
				feed.items = getElements("item", feedRoot.children).map(function(item){
					var entry = {}, tmp;
	
					item = item.children;
	
					addConditionally(entry, "id", "guid", item);
					addConditionally(entry, "title", "title", item);
					addConditionally(entry, "link", "link", item);
					addConditionally(entry, "description", "description", item);
					if((tmp = fetch("pubDate", item))) entry.pubDate = new Date(tmp);
					return entry;
				});
			}
		}
		this.dom = feed;
		DomHandler.prototype._handleCallback.call(
			this, feedRoot ? null : Error("couldn't find root of feed")
		);
	};
	
	module.exports = FeedHandler;
	
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/FeedHandler.js **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/Stream.js **/
jupyter.define('htmlparser2@3.9.2/lib/Stream.js', function (module, exports, __jupyter_require__) {
	module.exports = Stream;
	
	var Parser = __jupyter_require__('htmlparser2@3.9.2/lib/WritableStream.js');
	
	function Stream(options){
		Parser.call(this, new Cbs(this), options);
	}
	
	__jupyter_require__('inherits@^2.0.1/inherits_browser.js')(Stream, Parser);
	
	Stream.prototype.readable = true;
	
	function Cbs(scope){
		this.scope = scope;
	}
	
	var EVENTS = __jupyter_require__('htmlparser2@3.9.2/lib/index.js').EVENTS;
	
	Object.keys(EVENTS).forEach(function(name){
		if(EVENTS[name] === 0){
			Cbs.prototype["on" + name] = function(){
				this.scope.emit(name);
			};
		} else if(EVENTS[name] === 1){
			Cbs.prototype["on" + name] = function(a){
				this.scope.emit(name, a);
			};
		} else if(EVENTS[name] === 2){
			Cbs.prototype["on" + name] = function(a, b){
				this.scope.emit(name, a, b);
			};
		} else {
			throw Error("wrong number of arguments!");
		}
	});
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/Stream.js **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/WritableStream.js **/
jupyter.define('htmlparser2@3.9.2/lib/WritableStream.js', function (module, exports, __jupyter_require__) {
	module.exports = Stream;
	
	var Parser = __jupyter_require__('htmlparser2@3.9.2/lib/Parser.js'),
	    WritableStream = __jupyter_require__('stream-browserify@2.0.1/index.js').Writable || __jupyter_require__('__ignored__').Writable,
	    StringDecoder = __jupyter_require__('string_decoder@1.0.3/lib/string_decoder.js').StringDecoder,
	    Buffer = __jupyter_require__('buffer@4.9.1/index.js').Buffer;
	
	function Stream(cbs, options){
		var parser = this._parser = new Parser(cbs, options);
		var decoder = this._decoder = new StringDecoder();
	
		WritableStream.call(this, {decodeStrings: false});
	
		this.once("finish", function(){
			parser.end(decoder.end());
		});
	}
	
	__jupyter_require__('inherits@^2.0.1/inherits_browser.js')(Stream, WritableStream);
	
	WritableStream.prototype._write = function(chunk, encoding, cb){
		if(chunk instanceof Buffer) chunk = this._decoder.write(chunk);
		this._parser.write(chunk);
		cb();
	};
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/WritableStream.js **/


/** START DEFINE BLOCK for stream-browserify@2.0.1/index.js **/
jupyter.define('stream-browserify@2.0.1/index.js', function (module, exports, __jupyter_require__) {
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	module.exports = Stream;
	
	var EE = __jupyter_require__('events@1.1.1/events.js').EventEmitter;
	var inherits = __jupyter_require__('inherits@~2.0.1/inherits_browser.js');
	
	inherits(Stream, EE);
	Stream.Readable = __jupyter_require__('readable-stream@^2.0.2/readable-browser.js');
	Stream.Writable = __jupyter_require__('readable-stream@^2.0.2/writable-browser.js');
	Stream.Duplex = __jupyter_require__('readable-stream@^2.0.2/duplex-browser.js');
	Stream.Transform = __jupyter_require__('readable-stream@^2.0.2/transform.js');
	Stream.PassThrough = __jupyter_require__('readable-stream@^2.0.2/passthrough.js');
	
	// Backwards-compat with node 0.4.x
	Stream.Stream = Stream;
	
	
	
	// old-style streams.  Note that the pipe method (the only relevant
	// part of this class) is overridden in the Readable class.
	
	function Stream() {
	  EE.call(this);
	}
	
	Stream.prototype.pipe = function(dest, options) {
	  var source = this;
	
	  function ondata(chunk) {
	    if (dest.writable) {
	      if (false === dest.write(chunk) && source.pause) {
	        source.pause();
	      }
	    }
	  }
	
	  source.on('data', ondata);
	
	  function ondrain() {
	    if (source.readable && source.resume) {
	      source.resume();
	    }
	  }
	
	  dest.on('drain', ondrain);
	
	  // If the 'end' option is not supplied, dest.end() will be called when
	  // source gets the 'end' or 'close' events.  Only dest.end() once.
	  if (!dest._isStdio && (!options || options.end !== false)) {
	    source.on('end', onend);
	    source.on('close', onclose);
	  }
	
	  var didOnEnd = false;
	  function onend() {
	    if (didOnEnd) return;
	    didOnEnd = true;
	
	    dest.end();
	  }
	
	
	  function onclose() {
	    if (didOnEnd) return;
	    didOnEnd = true;
	
	    if (typeof dest.destroy === 'function') dest.destroy();
	  }
	
	  // don't leave dangling pipes when there are errors.
	  function onerror(er) {
	    cleanup();
	    if (EE.listenerCount(this, 'error') === 0) {
	      throw er; // Unhandled stream error in pipe.
	    }
	  }
	
	  source.on('error', onerror);
	  dest.on('error', onerror);
	
	  // remove all the event listeners that were added.
	  function cleanup() {
	    source.removeListener('data', ondata);
	    dest.removeListener('drain', ondrain);
	
	    source.removeListener('end', onend);
	    source.removeListener('close', onclose);
	
	    source.removeListener('error', onerror);
	    dest.removeListener('error', onerror);
	
	    source.removeListener('end', cleanup);
	    source.removeListener('close', cleanup);
	
	    dest.removeListener('close', cleanup);
	  }
	
	  source.on('end', cleanup);
	  source.on('close', cleanup);
	
	  dest.on('close', cleanup);
	
	  dest.emit('pipe', source);
	
	  // Allow for unix-like usage: A.pipe(B).pipe(C)
	  return dest;
	};
	
})
/** END DEFINE BLOCK for stream-browserify@2.0.1/index.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/readable-browser.js **/
jupyter.define('readable-stream@2.3.2/readable-browser.js', function (module, exports, __jupyter_require__) {
	exports = module.exports = __jupyter_require__('readable-stream@2.3.2/lib/_stream_readable.js');
	exports.Stream = exports;
	exports.Readable = exports;
	exports.Writable = __jupyter_require__('readable-stream@2.3.2/lib/_stream_writable.js');
	exports.Duplex = __jupyter_require__('readable-stream@2.3.2/lib/_stream_duplex.js');
	exports.Transform = __jupyter_require__('readable-stream@2.3.2/lib/_stream_transform.js');
	exports.PassThrough = __jupyter_require__('readable-stream@2.3.2/lib/_stream_passthrough.js');
	
})
/** END DEFINE BLOCK for readable-stream@2.3.2/readable-browser.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_readable.js **/
jupyter.define('readable-stream@2.3.2/lib/_stream_readable.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __jupyter_require__('process-nextick-args@~1.0.6/index.js');
	/*</replacement>*/
	
	module.exports = Readable;
	
	/*<replacement>*/
	var isArray = __jupyter_require__('isarray@~1.0.0/index.js');
	/*</replacement>*/
	
	/*<replacement>*/
	var Duplex;
	/*</replacement>*/
	
	Readable.ReadableState = ReadableState;
	
	/*<replacement>*/
	var EE = __jupyter_require__('events@1.1.1/events.js').EventEmitter;
	
	var EElistenerCount = function (emitter, type) {
	  return emitter.listeners(type).length;
	};
	/*</replacement>*/
	
	/*<replacement>*/
	var Stream = __jupyter_require__('readable-stream@2.3.2/lib/internal/streams/stream-browser.js');
	/*</replacement>*/
	
	// TODO(bmeurer): Change this back to const once hole checks are
	// properly optimized away early in Ignition+TurboFan.
	/*<replacement>*/
	var Buffer = __jupyter_require__('safe-buffer@~5.1.0/index.js').Buffer;
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj);
	}
	/*</replacement>*/
	
	/*<replacement>*/
	var util = __jupyter_require__('core-util-is@~1.0.0/lib/util.js');
	util.inherits = __jupyter_require__('inherits@~2.0.3/inherits_browser.js');
	/*</replacement>*/
	
	/*<replacement>*/
	var debugUtil = __jupyter_require__('__ignored__');
	var debug = void 0;
	if (debugUtil && debugUtil.debuglog) {
	  debug = debugUtil.debuglog('stream');
	} else {
	  debug = function () {};
	}
	/*</replacement>*/
	
	var BufferList = __jupyter_require__('readable-stream@2.3.2/lib/internal/streams/BufferList.js');
	var destroyImpl = __jupyter_require__('readable-stream@2.3.2/lib/internal/streams/destroy.js');
	var StringDecoder;
	
	util.inherits(Readable, Stream);
	
	var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
	
	function prependListener(emitter, event, fn) {
	  // Sadly this is not cacheable as some libraries bundle their own
	  // event emitter implementation with them.
	  if (typeof emitter.prependListener === 'function') {
	    return emitter.prependListener(event, fn);
	  } else {
	    // This is a hack to make sure that our error handler is attached before any
	    // userland ones.  NEVER DO THIS. This is here only because this code needs
	    // to continue to work with older versions of Node.js that do not include
	    // the prependListener() method. The goal is to eventually remove this hack.
	    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
	  }
	}
	
	function ReadableState(options, stream) {
	  Duplex = Duplex || __jupyter_require__('readable-stream@2.3.2/lib/_stream_duplex.js');
	
	  options = options || {};
	
	  // object stream flag. Used to make read(n) ignore n and to
	  // make all the buffer merging and length checks go away
	  this.objectMode = !!options.objectMode;
	
	  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
	
	  // the point at which it stops calling _read() to fill the buffer
	  // Note: 0 is a valid value, means "don't call _read preemptively ever"
	  var hwm = options.highWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
	
	  // cast to ints.
	  this.highWaterMark = Math.floor(this.highWaterMark);
	
	  // A linked list is used to store data chunks instead of an array because the
	  // linked list can remove elements from the beginning faster than
	  // array.shift()
	  this.buffer = new BufferList();
	  this.length = 0;
	  this.pipes = null;
	  this.pipesCount = 0;
	  this.flowing = null;
	  this.ended = false;
	  this.endEmitted = false;
	  this.reading = false;
	
	  // a flag to be able to tell if the event 'readable'/'data' is emitted
	  // immediately, or on a later tick.  We set this to true at first, because
	  // any actions that shouldn't happen until "later" should generally also
	  // not happen before the first read call.
	  this.sync = true;
	
	  // whenever we return null, then we set a flag to say
	  // that we're awaiting a 'readable' event emission.
	  this.needReadable = false;
	  this.emittedReadable = false;
	  this.readableListening = false;
	  this.resumeScheduled = false;
	
	  // has it been destroyed
	  this.destroyed = false;
	
	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';
	
	  // the number of writers that are awaiting a drain event in .pipe()s
	  this.awaitDrain = 0;
	
	  // if true, a maybeReadMore has been scheduled
	  this.readingMore = false;
	
	  this.decoder = null;
	  this.encoding = null;
	  if (options.encoding) {
	    if (!StringDecoder) StringDecoder = __jupyter_require__('string_decoder@~1.0.0/lib/string_decoder.js').StringDecoder;
	    this.decoder = new StringDecoder(options.encoding);
	    this.encoding = options.encoding;
	  }
	}
	
	function Readable(options) {
	  Duplex = Duplex || __jupyter_require__('readable-stream@2.3.2/lib/_stream_duplex.js');
	
	  if (!(this instanceof Readable)) return new Readable(options);
	
	  this._readableState = new ReadableState(options, this);
	
	  // legacy
	  this.readable = true;
	
	  if (options) {
	    if (typeof options.read === 'function') this._read = options.read;
	
	    if (typeof options.destroy === 'function') this._destroy = options.destroy;
	  }
	
	  Stream.call(this);
	}
	
	Object.defineProperty(Readable.prototype, 'destroyed', {
	  get: function () {
	    if (this._readableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._readableState) {
	      return;
	    }
	
	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	  }
	});
	
	Readable.prototype.destroy = destroyImpl.destroy;
	Readable.prototype._undestroy = destroyImpl.undestroy;
	Readable.prototype._destroy = function (err, cb) {
	  this.push(null);
	  cb(err);
	};
	
	// Manually shove something into the read() buffer.
	// This returns true if the highWaterMark has not been hit yet,
	// similar to how Writable.write() returns true if you should
	// write() some more.
	Readable.prototype.push = function (chunk, encoding) {
	  var state = this._readableState;
	  var skipChunkCheck;
	
	  if (!state.objectMode) {
	    if (typeof chunk === 'string') {
	      encoding = encoding || state.defaultEncoding;
	      if (encoding !== state.encoding) {
	        chunk = Buffer.from(chunk, encoding);
	        encoding = '';
	      }
	      skipChunkCheck = true;
	    }
	  } else {
	    skipChunkCheck = true;
	  }
	
	  return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
	};
	
	// Unshift should *always* be something directly out of read()
	Readable.prototype.unshift = function (chunk) {
	  return readableAddChunk(this, chunk, null, true, false);
	};
	
	function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
	  var state = stream._readableState;
	  if (chunk === null) {
	    state.reading = false;
	    onEofChunk(stream, state);
	  } else {
	    var er;
	    if (!skipChunkCheck) er = chunkInvalid(state, chunk);
	    if (er) {
	      stream.emit('error', er);
	    } else if (state.objectMode || chunk && chunk.length > 0) {
	      if (typeof chunk !== 'string' && Object.getPrototypeOf(chunk) !== Buffer.prototype && !state.objectMode) {
	        chunk = _uint8ArrayToBuffer(chunk);
	      }
	
	      if (addToFront) {
	        if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true);
	      } else if (state.ended) {
	        stream.emit('error', new Error('stream.push() after EOF'));
	      } else {
	        state.reading = false;
	        if (state.decoder && !encoding) {
	          chunk = state.decoder.write(chunk);
	          if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
	        } else {
	          addChunk(stream, state, chunk, false);
	        }
	      }
	    } else if (!addToFront) {
	      state.reading = false;
	    }
	  }
	
	  return needMoreData(state);
	}
	
	function addChunk(stream, state, chunk, addToFront) {
	  if (state.flowing && state.length === 0 && !state.sync) {
	    stream.emit('data', chunk);
	    stream.read(0);
	  } else {
	    // update the buffer info.
	    state.length += state.objectMode ? 1 : chunk.length;
	    if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
	
	    if (state.needReadable) emitReadable(stream);
	  }
	  maybeReadMore(stream, state);
	}
	
	function chunkInvalid(state, chunk) {
	  var er;
	  if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  return er;
	}
	
	// if it's past the high water mark, we can push in some more.
	// Also, if we have no data yet, we can stand some
	// more bytes.  This is to work around cases where hwm=0,
	// such as the repl.  Also, if the push() triggered a
	// readable event, and the user called read(largeNumber) such that
	// needReadable was set, then we ought to push more, so that another
	// 'readable' event will be triggered.
	function needMoreData(state) {
	  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
	}
	
	Readable.prototype.isPaused = function () {
	  return this._readableState.flowing === false;
	};
	
	// backwards compatibility.
	Readable.prototype.setEncoding = function (enc) {
	  if (!StringDecoder) StringDecoder = __jupyter_require__('string_decoder@~1.0.0/lib/string_decoder.js').StringDecoder;
	  this._readableState.decoder = new StringDecoder(enc);
	  this._readableState.encoding = enc;
	  return this;
	};
	
	// Don't raise the hwm > 8MB
	var MAX_HWM = 0x800000;
	function computeNewHighWaterMark(n) {
	  if (n >= MAX_HWM) {
	    n = MAX_HWM;
	  } else {
	    // Get the next highest power of 2 to prevent increasing hwm excessively in
	    // tiny amounts
	    n--;
	    n |= n >>> 1;
	    n |= n >>> 2;
	    n |= n >>> 4;
	    n |= n >>> 8;
	    n |= n >>> 16;
	    n++;
	  }
	  return n;
	}
	
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function howMuchToRead(n, state) {
	  if (n <= 0 || state.length === 0 && state.ended) return 0;
	  if (state.objectMode) return 1;
	  if (n !== n) {
	    // Only flow one buffer at a time
	    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
	  }
	  // If we're asking for more than the current hwm, then raise the hwm.
	  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
	  if (n <= state.length) return n;
	  // Don't have enough
	  if (!state.ended) {
	    state.needReadable = true;
	    return 0;
	  }
	  return state.length;
	}
	
	// you can override either this method, or the async _read(n) below.
	Readable.prototype.read = function (n) {
	  debug('read', n);
	  n = parseInt(n, 10);
	  var state = this._readableState;
	  var nOrig = n;
	
	  if (n !== 0) state.emittedReadable = false;
	
	  // if we're doing read(0) to trigger a readable event, but we
	  // already have a bunch of data in the buffer, then just trigger
	  // the 'readable' event and move on.
	  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
	    debug('read: emitReadable', state.length, state.ended);
	    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
	    return null;
	  }
	
	  n = howMuchToRead(n, state);
	
	  // if we've ended, and we're now clear, then finish it up.
	  if (n === 0 && state.ended) {
	    if (state.length === 0) endReadable(this);
	    return null;
	  }
	
	  // All the actual chunk generation logic needs to be
	  // *below* the call to _read.  The reason is that in certain
	  // synthetic stream cases, such as passthrough streams, _read
	  // may be a completely synchronous operation which may change
	  // the state of the read buffer, providing enough data when
	  // before there was *not* enough.
	  //
	  // So, the steps are:
	  // 1. Figure out what the state of things will be after we do
	  // a read from the buffer.
	  //
	  // 2. If that resulting state will trigger a _read, then call _read.
	  // Note that this may be asynchronous, or synchronous.  Yes, it is
	  // deeply ugly to write APIs this way, but that still doesn't mean
	  // that the Readable class should behave improperly, as streams are
	  // designed to be sync/async agnostic.
	  // Take note if the _read call is sync or async (ie, if the read call
	  // has returned yet), so that we know whether or not it's safe to emit
	  // 'readable' etc.
	  //
	  // 3. Actually pull the requested chunks out of the buffer and return.
	
	  // if we need a readable event, then we need to do some reading.
	  var doRead = state.needReadable;
	  debug('need readable', doRead);
	
	  // if we currently have less than the highWaterMark, then also read some
	  if (state.length === 0 || state.length - n < state.highWaterMark) {
	    doRead = true;
	    debug('length less than watermark', doRead);
	  }
	
	  // however, if we've ended, then there's no point, and if we're already
	  // reading, then it's unnecessary.
	  if (state.ended || state.reading) {
	    doRead = false;
	    debug('reading or ended', doRead);
	  } else if (doRead) {
	    debug('do read');
	    state.reading = true;
	    state.sync = true;
	    // if the length is currently zero, then we *need* a readable event.
	    if (state.length === 0) state.needReadable = true;
	    // call internal read method
	    this._read(state.highWaterMark);
	    state.sync = false;
	    // If _read pushed data synchronously, then `reading` will be false,
	    // and we need to re-evaluate how much data we can return to the user.
	    if (!state.reading) n = howMuchToRead(nOrig, state);
	  }
	
	  var ret;
	  if (n > 0) ret = fromList(n, state);else ret = null;
	
	  if (ret === null) {
	    state.needReadable = true;
	    n = 0;
	  } else {
	    state.length -= n;
	  }
	
	  if (state.length === 0) {
	    // If we have nothing in the buffer, then we want to know
	    // as soon as we *do* get something into the buffer.
	    if (!state.ended) state.needReadable = true;
	
	    // If we tried to read() past the EOF, then emit end on the next tick.
	    if (nOrig !== n && state.ended) endReadable(this);
	  }
	
	  if (ret !== null) this.emit('data', ret);
	
	  return ret;
	};
	
	function onEofChunk(stream, state) {
	  if (state.ended) return;
	  if (state.decoder) {
	    var chunk = state.decoder.end();
	    if (chunk && chunk.length) {
	      state.buffer.push(chunk);
	      state.length += state.objectMode ? 1 : chunk.length;
	    }
	  }
	  state.ended = true;
	
	  // emit 'readable' now to make sure it gets picked up.
	  emitReadable(stream);
	}
	
	// Don't emit readable right away in sync mode, because this can trigger
	// another read() call => stack overflow.  This way, it might trigger
	// a nextTick recursion warning, but that's not so bad.
	function emitReadable(stream) {
	  var state = stream._readableState;
	  state.needReadable = false;
	  if (!state.emittedReadable) {
	    debug('emitReadable', state.flowing);
	    state.emittedReadable = true;
	    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
	  }
	}
	
	function emitReadable_(stream) {
	  debug('emit readable');
	  stream.emit('readable');
	  flow(stream);
	}
	
	// at this point, the user has presumably seen the 'readable' event,
	// and called read() to consume some data.  that may have triggered
	// in turn another _read(n) call, in which case reading = true if
	// it's in progress.
	// However, if we're not ended, or reading, and the length < hwm,
	// then go ahead and try to read some more preemptively.
	function maybeReadMore(stream, state) {
	  if (!state.readingMore) {
	    state.readingMore = true;
	    processNextTick(maybeReadMore_, stream, state);
	  }
	}
	
	function maybeReadMore_(stream, state) {
	  var len = state.length;
	  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
	    debug('maybeReadMore read 0');
	    stream.read(0);
	    if (len === state.length)
	      // didn't get any data, stop spinning.
	      break;else len = state.length;
	  }
	  state.readingMore = false;
	}
	
	// abstract method.  to be overridden in specific implementation classes.
	// call cb(er, data) where data is <= n in length.
	// for virtual (non-string, non-buffer) streams, "length" is somewhat
	// arbitrary, and perhaps not very meaningful.
	Readable.prototype._read = function (n) {
	  this.emit('error', new Error('_read() is not implemented'));
	};
	
	Readable.prototype.pipe = function (dest, pipeOpts) {
	  var src = this;
	  var state = this._readableState;
	
	  switch (state.pipesCount) {
	    case 0:
	      state.pipes = dest;
	      break;
	    case 1:
	      state.pipes = [state.pipes, dest];
	      break;
	    default:
	      state.pipes.push(dest);
	      break;
	  }
	  state.pipesCount += 1;
	  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
	
	  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
	
	  var endFn = doEnd ? onend : unpipe;
	  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
	
	  dest.on('unpipe', onunpipe);
	  function onunpipe(readable, unpipeInfo) {
	    debug('onunpipe');
	    if (readable === src) {
	      if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
	        unpipeInfo.hasUnpiped = true;
	        cleanup();
	      }
	    }
	  }
	
	  function onend() {
	    debug('onend');
	    dest.end();
	  }
	
	  // when the dest drains, it reduces the awaitDrain counter
	  // on the source.  This would be more elegant with a .once()
	  // handler in flow(), but adding and removing repeatedly is
	  // too slow.
	  var ondrain = pipeOnDrain(src);
	  dest.on('drain', ondrain);
	
	  var cleanedUp = false;
	  function cleanup() {
	    debug('cleanup');
	    // cleanup event handlers once the pipe is broken
	    dest.removeListener('close', onclose);
	    dest.removeListener('finish', onfinish);
	    dest.removeListener('drain', ondrain);
	    dest.removeListener('error', onerror);
	    dest.removeListener('unpipe', onunpipe);
	    src.removeListener('end', onend);
	    src.removeListener('end', unpipe);
	    src.removeListener('data', ondata);
	
	    cleanedUp = true;
	
	    // if the reader is waiting for a drain event from this
	    // specific writer, then it would cause it to never start
	    // flowing again.
	    // So, if this is awaiting a drain, then we just call it now.
	    // If we don't know, then assume that we are waiting for one.
	    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
	  }
	
	  // If the user pushes more data while we're writing to dest then we'll end up
	  // in ondata again. However, we only want to increase awaitDrain once because
	  // dest will only emit one 'drain' event for the multiple writes.
	  // => Introduce a guard on increasing awaitDrain.
	  var increasedAwaitDrain = false;
	  src.on('data', ondata);
	  function ondata(chunk) {
	    debug('ondata');
	    increasedAwaitDrain = false;
	    var ret = dest.write(chunk);
	    if (false === ret && !increasedAwaitDrain) {
	      // If the user unpiped during `dest.write()`, it is possible
	      // to get stuck in a permanently paused state if that write
	      // also returned false.
	      // => Check whether `dest` is still a piping destination.
	      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
	        debug('false write response, pause', src._readableState.awaitDrain);
	        src._readableState.awaitDrain++;
	        increasedAwaitDrain = true;
	      }
	      src.pause();
	    }
	  }
	
	  // if the dest has an error, then stop piping into it.
	  // however, don't suppress the throwing behavior for this.
	  function onerror(er) {
	    debug('onerror', er);
	    unpipe();
	    dest.removeListener('error', onerror);
	    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
	  }
	
	  // Make sure our error handler is attached before userland ones.
	  prependListener(dest, 'error', onerror);
	
	  // Both close and finish should trigger unpipe, but only once.
	  function onclose() {
	    dest.removeListener('finish', onfinish);
	    unpipe();
	  }
	  dest.once('close', onclose);
	  function onfinish() {
	    debug('onfinish');
	    dest.removeListener('close', onclose);
	    unpipe();
	  }
	  dest.once('finish', onfinish);
	
	  function unpipe() {
	    debug('unpipe');
	    src.unpipe(dest);
	  }
	
	  // tell the dest that it's being piped to
	  dest.emit('pipe', src);
	
	  // start the flow if it hasn't been started already.
	  if (!state.flowing) {
	    debug('pipe resume');
	    src.resume();
	  }
	
	  return dest;
	};
	
	function pipeOnDrain(src) {
	  return function () {
	    var state = src._readableState;
	    debug('pipeOnDrain', state.awaitDrain);
	    if (state.awaitDrain) state.awaitDrain--;
	    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
	      state.flowing = true;
	      flow(src);
	    }
	  };
	}
	
	Readable.prototype.unpipe = function (dest) {
	  var state = this._readableState;
	  var unpipeInfo = { hasUnpiped: false };
	
	  // if we're not piping anywhere, then do nothing.
	  if (state.pipesCount === 0) return this;
	
	  // just one destination.  most common case.
	  if (state.pipesCount === 1) {
	    // passed in one, but it's not the right one.
	    if (dest && dest !== state.pipes) return this;
	
	    if (!dest) dest = state.pipes;
	
	    // got a match.
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	    if (dest) dest.emit('unpipe', this, unpipeInfo);
	    return this;
	  }
	
	  // slow case. multiple pipe destinations.
	
	  if (!dest) {
	    // remove all.
	    var dests = state.pipes;
	    var len = state.pipesCount;
	    state.pipes = null;
	    state.pipesCount = 0;
	    state.flowing = false;
	
	    for (var i = 0; i < len; i++) {
	      dests[i].emit('unpipe', this, unpipeInfo);
	    }return this;
	  }
	
	  // try to find the right one.
	  var index = indexOf(state.pipes, dest);
	  if (index === -1) return this;
	
	  state.pipes.splice(index, 1);
	  state.pipesCount -= 1;
	  if (state.pipesCount === 1) state.pipes = state.pipes[0];
	
	  dest.emit('unpipe', this, unpipeInfo);
	
	  return this;
	};
	
	// set up data events if they are asked for
	// Ensure readable listeners eventually get something
	Readable.prototype.on = function (ev, fn) {
	  var res = Stream.prototype.on.call(this, ev, fn);
	
	  if (ev === 'data') {
	    // Start flowing on next tick if stream isn't explicitly paused
	    if (this._readableState.flowing !== false) this.resume();
	  } else if (ev === 'readable') {
	    var state = this._readableState;
	    if (!state.endEmitted && !state.readableListening) {
	      state.readableListening = state.needReadable = true;
	      state.emittedReadable = false;
	      if (!state.reading) {
	        processNextTick(nReadingNextTick, this);
	      } else if (state.length) {
	        emitReadable(this);
	      }
	    }
	  }
	
	  return res;
	};
	Readable.prototype.addListener = Readable.prototype.on;
	
	function nReadingNextTick(self) {
	  debug('readable nexttick read 0');
	  self.read(0);
	}
	
	// pause() and resume() are remnants of the legacy readable stream API
	// If the user uses them, then switch into old mode.
	Readable.prototype.resume = function () {
	  var state = this._readableState;
	  if (!state.flowing) {
	    debug('resume');
	    state.flowing = true;
	    resume(this, state);
	  }
	  return this;
	};
	
	function resume(stream, state) {
	  if (!state.resumeScheduled) {
	    state.resumeScheduled = true;
	    processNextTick(resume_, stream, state);
	  }
	}
	
	function resume_(stream, state) {
	  if (!state.reading) {
	    debug('resume read 0');
	    stream.read(0);
	  }
	
	  state.resumeScheduled = false;
	  state.awaitDrain = 0;
	  stream.emit('resume');
	  flow(stream);
	  if (state.flowing && !state.reading) stream.read(0);
	}
	
	Readable.prototype.pause = function () {
	  debug('call pause flowing=%j', this._readableState.flowing);
	  if (false !== this._readableState.flowing) {
	    debug('pause');
	    this._readableState.flowing = false;
	    this.emit('pause');
	  }
	  return this;
	};
	
	function flow(stream) {
	  var state = stream._readableState;
	  debug('flow', state.flowing);
	  while (state.flowing && stream.read() !== null) {}
	}
	
	// wrap an old-style stream as the async data source.
	// This is *not* part of the readable stream interface.
	// It is an ugly unfortunate mess of history.
	Readable.prototype.wrap = function (stream) {
	  var state = this._readableState;
	  var paused = false;
	
	  var self = this;
	  stream.on('end', function () {
	    debug('wrapped end');
	    if (state.decoder && !state.ended) {
	      var chunk = state.decoder.end();
	      if (chunk && chunk.length) self.push(chunk);
	    }
	
	    self.push(null);
	  });
	
	  stream.on('data', function (chunk) {
	    debug('wrapped data');
	    if (state.decoder) chunk = state.decoder.write(chunk);
	
	    // don't skip over falsy values in objectMode
	    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
	
	    var ret = self.push(chunk);
	    if (!ret) {
	      paused = true;
	      stream.pause();
	    }
	  });
	
	  // proxy all the other methods.
	  // important when wrapping filters and duplexes.
	  for (var i in stream) {
	    if (this[i] === undefined && typeof stream[i] === 'function') {
	      this[i] = function (method) {
	        return function () {
	          return stream[method].apply(stream, arguments);
	        };
	      }(i);
	    }
	  }
	
	  // proxy certain important events.
	  for (var n = 0; n < kProxyEvents.length; n++) {
	    stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n]));
	  }
	
	  // when we try to consume some more bytes, simply unpause the
	  // underlying stream.
	  self._read = function (n) {
	    debug('wrapped _read', n);
	    if (paused) {
	      paused = false;
	      stream.resume();
	    }
	  };
	
	  return self;
	};
	
	// exposed for testing purposes only.
	Readable._fromList = fromList;
	
	// Pluck off n bytes from an array of buffers.
	// Length is the combined lengths of all the buffers in the list.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function fromList(n, state) {
	  // nothing buffered
	  if (state.length === 0) return null;
	
	  var ret;
	  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
	    // read it all, truncate the list
	    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
	    state.buffer.clear();
	  } else {
	    // read part of list
	    ret = fromListPartial(n, state.buffer, state.decoder);
	  }
	
	  return ret;
	}
	
	// Extracts only enough buffered data to satisfy the amount requested.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function fromListPartial(n, list, hasStrings) {
	  var ret;
	  if (n < list.head.data.length) {
	    // slice is the same for buffers and strings
	    ret = list.head.data.slice(0, n);
	    list.head.data = list.head.data.slice(n);
	  } else if (n === list.head.data.length) {
	    // first chunk is a perfect match
	    ret = list.shift();
	  } else {
	    // result spans more than one buffer
	    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
	  }
	  return ret;
	}
	
	// Copies a specified amount of characters from the list of buffered data
	// chunks.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function copyFromBufferString(n, list) {
	  var p = list.head;
	  var c = 1;
	  var ret = p.data;
	  n -= ret.length;
	  while (p = p.next) {
	    var str = p.data;
	    var nb = n > str.length ? str.length : n;
	    if (nb === str.length) ret += str;else ret += str.slice(0, n);
	    n -= nb;
	    if (n === 0) {
	      if (nb === str.length) {
	        ++c;
	        if (p.next) list.head = p.next;else list.head = list.tail = null;
	      } else {
	        list.head = p;
	        p.data = str.slice(nb);
	      }
	      break;
	    }
	    ++c;
	  }
	  list.length -= c;
	  return ret;
	}
	
	// Copies a specified amount of bytes from the list of buffered data chunks.
	// This function is designed to be inlinable, so please take care when making
	// changes to the function body.
	function copyFromBuffer(n, list) {
	  var ret = Buffer.allocUnsafe(n);
	  var p = list.head;
	  var c = 1;
	  p.data.copy(ret);
	  n -= p.data.length;
	  while (p = p.next) {
	    var buf = p.data;
	    var nb = n > buf.length ? buf.length : n;
	    buf.copy(ret, ret.length - n, 0, nb);
	    n -= nb;
	    if (n === 0) {
	      if (nb === buf.length) {
	        ++c;
	        if (p.next) list.head = p.next;else list.head = list.tail = null;
	      } else {
	        list.head = p;
	        p.data = buf.slice(nb);
	      }
	      break;
	    }
	    ++c;
	  }
	  list.length -= c;
	  return ret;
	}
	
	function endReadable(stream) {
	  var state = stream._readableState;
	
	  // If we get here before consuming all the bytes, then that is a
	  // bug in node.  Should never happen.
	  if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');
	
	  if (!state.endEmitted) {
	    state.ended = true;
	    processNextTick(endReadableNT, state, stream);
	  }
	}
	
	function endReadableNT(state, stream) {
	  // Check that we didn't get one last unshift.
	  if (!state.endEmitted && state.length === 0) {
	    state.endEmitted = true;
	    stream.readable = false;
	    stream.emit('end');
	  }
	}
	
	function forEach(xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}
	
	function indexOf(xs, x) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    if (xs[i] === x) return i;
	  }
	  return -1;
	}
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('process@0.11.10/browser.js')))
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_readable.js **/


/** START DEFINE BLOCK for process-nextick-args@1.0.7/index.js **/
jupyter.define('process-nextick-args@1.0.7/index.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(process) {'use strict';
	
	if (!process.version ||
	    process.version.indexOf('v0.') === 0 ||
	    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
	  module.exports = nextTick;
	} else {
	  module.exports = process.nextTick;
	}
	
	function nextTick(fn, arg1, arg2, arg3) {
	  if (typeof fn !== 'function') {
	    throw new TypeError('"callback" argument must be a function');
	  }
	  var len = arguments.length;
	  var args, i;
	  switch (len) {
	  case 0:
	  case 1:
	    return process.nextTick(fn);
	  case 2:
	    return process.nextTick(function afterTickOne() {
	      fn.call(null, arg1);
	    });
	  case 3:
	    return process.nextTick(function afterTickTwo() {
	      fn.call(null, arg1, arg2);
	    });
	  case 4:
	    return process.nextTick(function afterTickThree() {
	      fn.call(null, arg1, arg2, arg3);
	    });
	  default:
	    args = new Array(len - 1);
	    i = 0;
	    while (i < args.length) {
	      args[i++] = arguments[i];
	    }
	    return process.nextTick(function afterTick() {
	      fn.apply(null, args);
	    });
	  }
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('process@0.11.10/browser.js')))
})
/** END DEFINE BLOCK for process-nextick-args@1.0.7/index.js **/


/** START DEFINE BLOCK for isarray@1.0.0/index.js **/
jupyter.define('isarray@1.0.0/index.js', function (module, exports, __jupyter_require__) {
	var toString = {}.toString;
	
	module.exports = Array.isArray || function (arr) {
	  return toString.call(arr) == '[object Array]';
	};
	
})
/** END DEFINE BLOCK for isarray@1.0.0/index.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/internal/streams/stream-browser.js **/
jupyter.define('readable-stream@2.3.2/lib/internal/streams/stream-browser.js', function (module, exports, __jupyter_require__) {
	module.exports = __jupyter_require__('events@1.1.1/events.js').EventEmitter;
	
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/internal/streams/stream-browser.js **/


/** START DEFINE BLOCK for safe-buffer@5.1.1/index.js **/
jupyter.define('safe-buffer@5.1.1/index.js', function (module, exports, __jupyter_require__) {
	/* eslint-disable node/no-deprecated-api */
	var buffer = __jupyter_require__('buffer@4.9.1/index.js')
	var Buffer = buffer.Buffer
	
	// alternative to using Object.keys for old browsers
	function copyProps (src, dst) {
	  for (var key in src) {
	    dst[key] = src[key]
	  }
	}
	if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
	  module.exports = buffer
	} else {
	  // Copy properties from require('buffer')
	  copyProps(buffer, exports)
	  exports.Buffer = SafeBuffer
	}
	
	function SafeBuffer (arg, encodingOrOffset, length) {
	  return Buffer(arg, encodingOrOffset, length)
	}
	
	// Copy static methods from Buffer
	copyProps(Buffer, SafeBuffer)
	
	SafeBuffer.from = function (arg, encodingOrOffset, length) {
	  if (typeof arg === 'number') {
	    throw new TypeError('Argument must not be a number')
	  }
	  return Buffer(arg, encodingOrOffset, length)
	}
	
	SafeBuffer.alloc = function (size, fill, encoding) {
	  if (typeof size !== 'number') {
	    throw new TypeError('Argument must be a number')
	  }
	  var buf = Buffer(size)
	  if (fill !== undefined) {
	    if (typeof encoding === 'string') {
	      buf.fill(fill, encoding)
	    } else {
	      buf.fill(fill)
	    }
	  } else {
	    buf.fill(0)
	  }
	  return buf
	}
	
	SafeBuffer.allocUnsafe = function (size) {
	  if (typeof size !== 'number') {
	    throw new TypeError('Argument must be a number')
	  }
	  return Buffer(size)
	}
	
	SafeBuffer.allocUnsafeSlow = function (size) {
	  if (typeof size !== 'number') {
	    throw new TypeError('Argument must be a number')
	  }
	  return buffer.SlowBuffer(size)
	}
	
})
/** END DEFINE BLOCK for safe-buffer@5.1.1/index.js **/


/** START DEFINE BLOCK for buffer@4.9.1/index.js **/
jupyter.define('buffer@4.9.1/index.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(global) {/*!
	 * The buffer module from node.js, for the browser.
	 *
	 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
	 * @license  MIT
	 */
	/* eslint-disable no-proto */
	
	'use strict'
	
	var base64 = __jupyter_require__('base64-js@^1.0.2/index.js')
	var ieee754 = __jupyter_require__('ieee754@^1.1.4/index.js')
	var isArray = __jupyter_require__('isarray@^1.0.0/index.js')
	
	exports.Buffer = Buffer
	exports.SlowBuffer = SlowBuffer
	exports.INSPECT_MAX_BYTES = 50
	
	/**
	 * If `Buffer.TYPED_ARRAY_SUPPORT`:
	 *   === true    Use Uint8Array implementation (fastest)
	 *   === false   Use Object implementation (most compatible, even IE6)
	 *
	 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
	 * Opera 11.6+, iOS 4.2+.
	 *
	 * Due to various browser bugs, sometimes the Object implementation will be used even
	 * when the browser supports typed arrays.
	 *
	 * Note:
	 *
	 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
	 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
	 *
	 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
	 *
	 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
	 *     incorrect length in some situations.
	
	 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
	 * get the Object implementation, which is slower but behaves correctly.
	 */
	Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
	  ? global.TYPED_ARRAY_SUPPORT
	  : typedArraySupport()
	
	/*
	 * Export kMaxLength after typed array support is determined.
	 */
	exports.kMaxLength = kMaxLength()
	
	function typedArraySupport () {
	  try {
	    var arr = new Uint8Array(1)
	    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
	    return arr.foo() === 42 && // typed array instances can be augmented
	        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
	        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
	  } catch (e) {
	    return false
	  }
	}
	
	function kMaxLength () {
	  return Buffer.TYPED_ARRAY_SUPPORT
	    ? 0x7fffffff
	    : 0x3fffffff
	}
	
	function createBuffer (that, length) {
	  if (kMaxLength() < length) {
	    throw new RangeError('Invalid typed array length')
	  }
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    // Return an augmented `Uint8Array` instance, for best performance
	    that = new Uint8Array(length)
	    that.__proto__ = Buffer.prototype
	  } else {
	    // Fallback: Return an object instance of the Buffer class
	    if (that === null) {
	      that = new Buffer(length)
	    }
	    that.length = length
	  }
	
	  return that
	}
	
	/**
	 * The Buffer constructor returns instances of `Uint8Array` that have their
	 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
	 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
	 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
	 * returns a single octet.
	 *
	 * The `Uint8Array` prototype remains unmodified.
	 */
	
	function Buffer (arg, encodingOrOffset, length) {
	  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
	    return new Buffer(arg, encodingOrOffset, length)
	  }
	
	  // Common case.
	  if (typeof arg === 'number') {
	    if (typeof encodingOrOffset === 'string') {
	      throw new Error(
	        'If encoding is specified then the first argument must be a string'
	      )
	    }
	    return allocUnsafe(this, arg)
	  }
	  return from(this, arg, encodingOrOffset, length)
	}
	
	Buffer.poolSize = 8192 // not used by this implementation
	
	// TODO: Legacy, not needed anymore. Remove in next major version.
	Buffer._augment = function (arr) {
	  arr.__proto__ = Buffer.prototype
	  return arr
	}
	
	function from (that, value, encodingOrOffset, length) {
	  if (typeof value === 'number') {
	    throw new TypeError('"value" argument must not be a number')
	  }
	
	  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
	    return fromArrayBuffer(that, value, encodingOrOffset, length)
	  }
	
	  if (typeof value === 'string') {
	    return fromString(that, value, encodingOrOffset)
	  }
	
	  return fromObject(that, value)
	}
	
	/**
	 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
	 * if value is a number.
	 * Buffer.from(str[, encoding])
	 * Buffer.from(array)
	 * Buffer.from(buffer)
	 * Buffer.from(arrayBuffer[, byteOffset[, length]])
	 **/
	Buffer.from = function (value, encodingOrOffset, length) {
	  return from(null, value, encodingOrOffset, length)
	}
	
	if (Buffer.TYPED_ARRAY_SUPPORT) {
	  Buffer.prototype.__proto__ = Uint8Array.prototype
	  Buffer.__proto__ = Uint8Array
	  if (typeof Symbol !== 'undefined' && Symbol.species &&
	      Buffer[Symbol.species] === Buffer) {
	    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
	    Object.defineProperty(Buffer, Symbol.species, {
	      value: null,
	      configurable: true
	    })
	  }
	}
	
	function assertSize (size) {
	  if (typeof size !== 'number') {
	    throw new TypeError('"size" argument must be a number')
	  } else if (size < 0) {
	    throw new RangeError('"size" argument must not be negative')
	  }
	}
	
	function alloc (that, size, fill, encoding) {
	  assertSize(size)
	  if (size <= 0) {
	    return createBuffer(that, size)
	  }
	  if (fill !== undefined) {
	    // Only pay attention to encoding if it's a string. This
	    // prevents accidentally sending in a number that would
	    // be interpretted as a start offset.
	    return typeof encoding === 'string'
	      ? createBuffer(that, size).fill(fill, encoding)
	      : createBuffer(that, size).fill(fill)
	  }
	  return createBuffer(that, size)
	}
	
	/**
	 * Creates a new filled Buffer instance.
	 * alloc(size[, fill[, encoding]])
	 **/
	Buffer.alloc = function (size, fill, encoding) {
	  return alloc(null, size, fill, encoding)
	}
	
	function allocUnsafe (that, size) {
	  assertSize(size)
	  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) {
	    for (var i = 0; i < size; ++i) {
	      that[i] = 0
	    }
	  }
	  return that
	}
	
	/**
	 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
	 * */
	Buffer.allocUnsafe = function (size) {
	  return allocUnsafe(null, size)
	}
	/**
	 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
	 */
	Buffer.allocUnsafeSlow = function (size) {
	  return allocUnsafe(null, size)
	}
	
	function fromString (that, string, encoding) {
	  if (typeof encoding !== 'string' || encoding === '') {
	    encoding = 'utf8'
	  }
	
	  if (!Buffer.isEncoding(encoding)) {
	    throw new TypeError('"encoding" must be a valid string encoding')
	  }
	
	  var length = byteLength(string, encoding) | 0
	  that = createBuffer(that, length)
	
	  var actual = that.write(string, encoding)
	
	  if (actual !== length) {
	    // Writing a hex string, for example, that contains invalid characters will
	    // cause everything after the first invalid character to be ignored. (e.g.
	    // 'abxxcd' will be treated as 'ab')
	    that = that.slice(0, actual)
	  }
	
	  return that
	}
	
	function fromArrayLike (that, array) {
	  var length = array.length < 0 ? 0 : checked(array.length) | 0
	  that = createBuffer(that, length)
	  for (var i = 0; i < length; i += 1) {
	    that[i] = array[i] & 255
	  }
	  return that
	}
	
	function fromArrayBuffer (that, array, byteOffset, length) {
	  array.byteLength // this throws if `array` is not a valid ArrayBuffer
	
	  if (byteOffset < 0 || array.byteLength < byteOffset) {
	    throw new RangeError('\'offset\' is out of bounds')
	  }
	
	  if (array.byteLength < byteOffset + (length || 0)) {
	    throw new RangeError('\'length\' is out of bounds')
	  }
	
	  if (byteOffset === undefined && length === undefined) {
	    array = new Uint8Array(array)
	  } else if (length === undefined) {
	    array = new Uint8Array(array, byteOffset)
	  } else {
	    array = new Uint8Array(array, byteOffset, length)
	  }
	
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    // Return an augmented `Uint8Array` instance, for best performance
	    that = array
	    that.__proto__ = Buffer.prototype
	  } else {
	    // Fallback: Return an object instance of the Buffer class
	    that = fromArrayLike(that, array)
	  }
	  return that
	}
	
	function fromObject (that, obj) {
	  if (Buffer.isBuffer(obj)) {
	    var len = checked(obj.length) | 0
	    that = createBuffer(that, len)
	
	    if (that.length === 0) {
	      return that
	    }
	
	    obj.copy(that, 0, 0, len)
	    return that
	  }
	
	  if (obj) {
	    if ((typeof ArrayBuffer !== 'undefined' &&
	        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
	      if (typeof obj.length !== 'number' || isnan(obj.length)) {
	        return createBuffer(that, 0)
	      }
	      return fromArrayLike(that, obj)
	    }
	
	    if (obj.type === 'Buffer' && isArray(obj.data)) {
	      return fromArrayLike(that, obj.data)
	    }
	  }
	
	  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
	}
	
	function checked (length) {
	  // Note: cannot use `length < kMaxLength()` here because that fails when
	  // length is NaN (which is otherwise coerced to zero.)
	  if (length >= kMaxLength()) {
	    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
	                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
	  }
	  return length | 0
	}
	
	function SlowBuffer (length) {
	  if (+length != length) { // eslint-disable-line eqeqeq
	    length = 0
	  }
	  return Buffer.alloc(+length)
	}
	
	Buffer.isBuffer = function isBuffer (b) {
	  return !!(b != null && b._isBuffer)
	}
	
	Buffer.compare = function compare (a, b) {
	  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
	    throw new TypeError('Arguments must be Buffers')
	  }
	
	  if (a === b) return 0
	
	  var x = a.length
	  var y = b.length
	
	  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
	    if (a[i] !== b[i]) {
	      x = a[i]
	      y = b[i]
	      break
	    }
	  }
	
	  if (x < y) return -1
	  if (y < x) return 1
	  return 0
	}
	
	Buffer.isEncoding = function isEncoding (encoding) {
	  switch (String(encoding).toLowerCase()) {
	    case 'hex':
	    case 'utf8':
	    case 'utf-8':
	    case 'ascii':
	    case 'latin1':
	    case 'binary':
	    case 'base64':
	    case 'ucs2':
	    case 'ucs-2':
	    case 'utf16le':
	    case 'utf-16le':
	      return true
	    default:
	      return false
	  }
	}
	
	Buffer.concat = function concat (list, length) {
	  if (!isArray(list)) {
	    throw new TypeError('"list" argument must be an Array of Buffers')
	  }
	
	  if (list.length === 0) {
	    return Buffer.alloc(0)
	  }
	
	  var i
	  if (length === undefined) {
	    length = 0
	    for (i = 0; i < list.length; ++i) {
	      length += list[i].length
	    }
	  }
	
	  var buffer = Buffer.allocUnsafe(length)
	  var pos = 0
	  for (i = 0; i < list.length; ++i) {
	    var buf = list[i]
	    if (!Buffer.isBuffer(buf)) {
	      throw new TypeError('"list" argument must be an Array of Buffers')
	    }
	    buf.copy(buffer, pos)
	    pos += buf.length
	  }
	  return buffer
	}
	
	function byteLength (string, encoding) {
	  if (Buffer.isBuffer(string)) {
	    return string.length
	  }
	  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
	      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
	    return string.byteLength
	  }
	  if (typeof string !== 'string') {
	    string = '' + string
	  }
	
	  var len = string.length
	  if (len === 0) return 0
	
	  // Use a for loop to avoid recursion
	  var loweredCase = false
	  for (;;) {
	    switch (encoding) {
	      case 'ascii':
	      case 'latin1':
	      case 'binary':
	        return len
	      case 'utf8':
	      case 'utf-8':
	      case undefined:
	        return utf8ToBytes(string).length
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return len * 2
	      case 'hex':
	        return len >>> 1
	      case 'base64':
	        return base64ToBytes(string).length
	      default:
	        if (loweredCase) return utf8ToBytes(string).length // assume utf8
	        encoding = ('' + encoding).toLowerCase()
	        loweredCase = true
	    }
	  }
	}
	Buffer.byteLength = byteLength
	
	function slowToString (encoding, start, end) {
	  var loweredCase = false
	
	  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
	  // property of a typed array.
	
	  // This behaves neither like String nor Uint8Array in that we set start/end
	  // to their upper/lower bounds if the value passed is out of range.
	  // undefined is handled specially as per ECMA-262 6th Edition,
	  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
	  if (start === undefined || start < 0) {
	    start = 0
	  }
	  // Return early if start > this.length. Done here to prevent potential uint32
	  // coercion fail below.
	  if (start > this.length) {
	    return ''
	  }
	
	  if (end === undefined || end > this.length) {
	    end = this.length
	  }
	
	  if (end <= 0) {
	    return ''
	  }
	
	  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
	  end >>>= 0
	  start >>>= 0
	
	  if (end <= start) {
	    return ''
	  }
	
	  if (!encoding) encoding = 'utf8'
	
	  while (true) {
	    switch (encoding) {
	      case 'hex':
	        return hexSlice(this, start, end)
	
	      case 'utf8':
	      case 'utf-8':
	        return utf8Slice(this, start, end)
	
	      case 'ascii':
	        return asciiSlice(this, start, end)
	
	      case 'latin1':
	      case 'binary':
	        return latin1Slice(this, start, end)
	
	      case 'base64':
	        return base64Slice(this, start, end)
	
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return utf16leSlice(this, start, end)
	
	      default:
	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
	        encoding = (encoding + '').toLowerCase()
	        loweredCase = true
	    }
	  }
	}
	
	// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
	// Buffer instances.
	Buffer.prototype._isBuffer = true
	
	function swap (b, n, m) {
	  var i = b[n]
	  b[n] = b[m]
	  b[m] = i
	}
	
	Buffer.prototype.swap16 = function swap16 () {
	  var len = this.length
	  if (len % 2 !== 0) {
	    throw new RangeError('Buffer size must be a multiple of 16-bits')
	  }
	  for (var i = 0; i < len; i += 2) {
	    swap(this, i, i + 1)
	  }
	  return this
	}
	
	Buffer.prototype.swap32 = function swap32 () {
	  var len = this.length
	  if (len % 4 !== 0) {
	    throw new RangeError('Buffer size must be a multiple of 32-bits')
	  }
	  for (var i = 0; i < len; i += 4) {
	    swap(this, i, i + 3)
	    swap(this, i + 1, i + 2)
	  }
	  return this
	}
	
	Buffer.prototype.swap64 = function swap64 () {
	  var len = this.length
	  if (len % 8 !== 0) {
	    throw new RangeError('Buffer size must be a multiple of 64-bits')
	  }
	  for (var i = 0; i < len; i += 8) {
	    swap(this, i, i + 7)
	    swap(this, i + 1, i + 6)
	    swap(this, i + 2, i + 5)
	    swap(this, i + 3, i + 4)
	  }
	  return this
	}
	
	Buffer.prototype.toString = function toString () {
	  var length = this.length | 0
	  if (length === 0) return ''
	  if (arguments.length === 0) return utf8Slice(this, 0, length)
	  return slowToString.apply(this, arguments)
	}
	
	Buffer.prototype.equals = function equals (b) {
	  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
	  if (this === b) return true
	  return Buffer.compare(this, b) === 0
	}
	
	Buffer.prototype.inspect = function inspect () {
	  var str = ''
	  var max = exports.INSPECT_MAX_BYTES
	  if (this.length > 0) {
	    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
	    if (this.length > max) str += ' ... '
	  }
	  return '<Buffer ' + str + '>'
	}
	
	Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
	  if (!Buffer.isBuffer(target)) {
	    throw new TypeError('Argument must be a Buffer')
	  }
	
	  if (start === undefined) {
	    start = 0
	  }
	  if (end === undefined) {
	    end = target ? target.length : 0
	  }
	  if (thisStart === undefined) {
	    thisStart = 0
	  }
	  if (thisEnd === undefined) {
	    thisEnd = this.length
	  }
	
	  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
	    throw new RangeError('out of range index')
	  }
	
	  if (thisStart >= thisEnd && start >= end) {
	    return 0
	  }
	  if (thisStart >= thisEnd) {
	    return -1
	  }
	  if (start >= end) {
	    return 1
	  }
	
	  start >>>= 0
	  end >>>= 0
	  thisStart >>>= 0
	  thisEnd >>>= 0
	
	  if (this === target) return 0
	
	  var x = thisEnd - thisStart
	  var y = end - start
	  var len = Math.min(x, y)
	
	  var thisCopy = this.slice(thisStart, thisEnd)
	  var targetCopy = target.slice(start, end)
	
	  for (var i = 0; i < len; ++i) {
	    if (thisCopy[i] !== targetCopy[i]) {
	      x = thisCopy[i]
	      y = targetCopy[i]
	      break
	    }
	  }
	
	  if (x < y) return -1
	  if (y < x) return 1
	  return 0
	}
	
	// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
	// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
	//
	// Arguments:
	// - buffer - a Buffer to search
	// - val - a string, Buffer, or number
	// - byteOffset - an index into `buffer`; will be clamped to an int32
	// - encoding - an optional encoding, relevant is val is a string
	// - dir - true for indexOf, false for lastIndexOf
	function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
	  // Empty buffer means no match
	  if (buffer.length === 0) return -1
	
	  // Normalize byteOffset
	  if (typeof byteOffset === 'string') {
	    encoding = byteOffset
	    byteOffset = 0
	  } else if (byteOffset > 0x7fffffff) {
	    byteOffset = 0x7fffffff
	  } else if (byteOffset < -0x80000000) {
	    byteOffset = -0x80000000
	  }
	  byteOffset = +byteOffset  // Coerce to Number.
	  if (isNaN(byteOffset)) {
	    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
	    byteOffset = dir ? 0 : (buffer.length - 1)
	  }
	
	  // Normalize byteOffset: negative offsets start from the end of the buffer
	  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
	  if (byteOffset >= buffer.length) {
	    if (dir) return -1
	    else byteOffset = buffer.length - 1
	  } else if (byteOffset < 0) {
	    if (dir) byteOffset = 0
	    else return -1
	  }
	
	  // Normalize val
	  if (typeof val === 'string') {
	    val = Buffer.from(val, encoding)
	  }
	
	  // Finally, search either indexOf (if dir is true) or lastIndexOf
	  if (Buffer.isBuffer(val)) {
	    // Special case: looking for empty string/buffer always fails
	    if (val.length === 0) {
	      return -1
	    }
	    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
	  } else if (typeof val === 'number') {
	    val = val & 0xFF // Search for a byte value [0-255]
	    if (Buffer.TYPED_ARRAY_SUPPORT &&
	        typeof Uint8Array.prototype.indexOf === 'function') {
	      if (dir) {
	        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
	      } else {
	        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
	      }
	    }
	    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
	  }
	
	  throw new TypeError('val must be string, number or Buffer')
	}
	
	function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
	  var indexSize = 1
	  var arrLength = arr.length
	  var valLength = val.length
	
	  if (encoding !== undefined) {
	    encoding = String(encoding).toLowerCase()
	    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
	        encoding === 'utf16le' || encoding === 'utf-16le') {
	      if (arr.length < 2 || val.length < 2) {
	        return -1
	      }
	      indexSize = 2
	      arrLength /= 2
	      valLength /= 2
	      byteOffset /= 2
	    }
	  }
	
	  function read (buf, i) {
	    if (indexSize === 1) {
	      return buf[i]
	    } else {
	      return buf.readUInt16BE(i * indexSize)
	    }
	  }
	
	  var i
	  if (dir) {
	    var foundIndex = -1
	    for (i = byteOffset; i < arrLength; i++) {
	      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
	        if (foundIndex === -1) foundIndex = i
	        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
	      } else {
	        if (foundIndex !== -1) i -= i - foundIndex
	        foundIndex = -1
	      }
	    }
	  } else {
	    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
	    for (i = byteOffset; i >= 0; i--) {
	      var found = true
	      for (var j = 0; j < valLength; j++) {
	        if (read(arr, i + j) !== read(val, j)) {
	          found = false
	          break
	        }
	      }
	      if (found) return i
	    }
	  }
	
	  return -1
	}
	
	Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
	  return this.indexOf(val, byteOffset, encoding) !== -1
	}
	
	Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
	  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
	}
	
	Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
	  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
	}
	
	function hexWrite (buf, string, offset, length) {
	  offset = Number(offset) || 0
	  var remaining = buf.length - offset
	  if (!length) {
	    length = remaining
	  } else {
	    length = Number(length)
	    if (length > remaining) {
	      length = remaining
	    }
	  }
	
	  // must be an even number of digits
	  var strLen = string.length
	  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
	
	  if (length > strLen / 2) {
	    length = strLen / 2
	  }
	  for (var i = 0; i < length; ++i) {
	    var parsed = parseInt(string.substr(i * 2, 2), 16)
	    if (isNaN(parsed)) return i
	    buf[offset + i] = parsed
	  }
	  return i
	}
	
	function utf8Write (buf, string, offset, length) {
	  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
	}
	
	function asciiWrite (buf, string, offset, length) {
	  return blitBuffer(asciiToBytes(string), buf, offset, length)
	}
	
	function latin1Write (buf, string, offset, length) {
	  return asciiWrite(buf, string, offset, length)
	}
	
	function base64Write (buf, string, offset, length) {
	  return blitBuffer(base64ToBytes(string), buf, offset, length)
	}
	
	function ucs2Write (buf, string, offset, length) {
	  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
	}
	
	Buffer.prototype.write = function write (string, offset, length, encoding) {
	  // Buffer#write(string)
	  if (offset === undefined) {
	    encoding = 'utf8'
	    length = this.length
	    offset = 0
	  // Buffer#write(string, encoding)
	  } else if (length === undefined && typeof offset === 'string') {
	    encoding = offset
	    length = this.length
	    offset = 0
	  // Buffer#write(string, offset[, length][, encoding])
	  } else if (isFinite(offset)) {
	    offset = offset | 0
	    if (isFinite(length)) {
	      length = length | 0
	      if (encoding === undefined) encoding = 'utf8'
	    } else {
	      encoding = length
	      length = undefined
	    }
	  // legacy write(string, encoding, offset, length) - remove in v0.13
	  } else {
	    throw new Error(
	      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
	    )
	  }
	
	  var remaining = this.length - offset
	  if (length === undefined || length > remaining) length = remaining
	
	  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
	    throw new RangeError('Attempt to write outside buffer bounds')
	  }
	
	  if (!encoding) encoding = 'utf8'
	
	  var loweredCase = false
	  for (;;) {
	    switch (encoding) {
	      case 'hex':
	        return hexWrite(this, string, offset, length)
	
	      case 'utf8':
	      case 'utf-8':
	        return utf8Write(this, string, offset, length)
	
	      case 'ascii':
	        return asciiWrite(this, string, offset, length)
	
	      case 'latin1':
	      case 'binary':
	        return latin1Write(this, string, offset, length)
	
	      case 'base64':
	        // Warning: maxLength not taken into account in base64Write
	        return base64Write(this, string, offset, length)
	
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return ucs2Write(this, string, offset, length)
	
	      default:
	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
	        encoding = ('' + encoding).toLowerCase()
	        loweredCase = true
	    }
	  }
	}
	
	Buffer.prototype.toJSON = function toJSON () {
	  return {
	    type: 'Buffer',
	    data: Array.prototype.slice.call(this._arr || this, 0)
	  }
	}
	
	function base64Slice (buf, start, end) {
	  if (start === 0 && end === buf.length) {
	    return base64.fromByteArray(buf)
	  } else {
	    return base64.fromByteArray(buf.slice(start, end))
	  }
	}
	
	function utf8Slice (buf, start, end) {
	  end = Math.min(buf.length, end)
	  var res = []
	
	  var i = start
	  while (i < end) {
	    var firstByte = buf[i]
	    var codePoint = null
	    var bytesPerSequence = (firstByte > 0xEF) ? 4
	      : (firstByte > 0xDF) ? 3
	      : (firstByte > 0xBF) ? 2
	      : 1
	
	    if (i + bytesPerSequence <= end) {
	      var secondByte, thirdByte, fourthByte, tempCodePoint
	
	      switch (bytesPerSequence) {
	        case 1:
	          if (firstByte < 0x80) {
	            codePoint = firstByte
	          }
	          break
	        case 2:
	          secondByte = buf[i + 1]
	          if ((secondByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
	            if (tempCodePoint > 0x7F) {
	              codePoint = tempCodePoint
	            }
	          }
	          break
	        case 3:
	          secondByte = buf[i + 1]
	          thirdByte = buf[i + 2]
	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
	            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
	              codePoint = tempCodePoint
	            }
	          }
	          break
	        case 4:
	          secondByte = buf[i + 1]
	          thirdByte = buf[i + 2]
	          fourthByte = buf[i + 3]
	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
	            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
	            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
	              codePoint = tempCodePoint
	            }
	          }
	      }
	    }
	
	    if (codePoint === null) {
	      // we did not generate a valid codePoint so insert a
	      // replacement char (U+FFFD) and advance only 1 byte
	      codePoint = 0xFFFD
	      bytesPerSequence = 1
	    } else if (codePoint > 0xFFFF) {
	      // encode to utf16 (surrogate pair dance)
	      codePoint -= 0x10000
	      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
	      codePoint = 0xDC00 | codePoint & 0x3FF
	    }
	
	    res.push(codePoint)
	    i += bytesPerSequence
	  }
	
	  return decodeCodePointsArray(res)
	}
	
	// Based on http://stackoverflow.com/a/22747272/680742, the browser with
	// the lowest limit is Chrome, with 0x10000 args.
	// We go 1 magnitude less, for safety
	var MAX_ARGUMENTS_LENGTH = 0x1000
	
	function decodeCodePointsArray (codePoints) {
	  var len = codePoints.length
	  if (len <= MAX_ARGUMENTS_LENGTH) {
	    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
	  }
	
	  // Decode in chunks to avoid "call stack size exceeded".
	  var res = ''
	  var i = 0
	  while (i < len) {
	    res += String.fromCharCode.apply(
	      String,
	      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
	    )
	  }
	  return res
	}
	
	function asciiSlice (buf, start, end) {
	  var ret = ''
	  end = Math.min(buf.length, end)
	
	  for (var i = start; i < end; ++i) {
	    ret += String.fromCharCode(buf[i] & 0x7F)
	  }
	  return ret
	}
	
	function latin1Slice (buf, start, end) {
	  var ret = ''
	  end = Math.min(buf.length, end)
	
	  for (var i = start; i < end; ++i) {
	    ret += String.fromCharCode(buf[i])
	  }
	  return ret
	}
	
	function hexSlice (buf, start, end) {
	  var len = buf.length
	
	  if (!start || start < 0) start = 0
	  if (!end || end < 0 || end > len) end = len
	
	  var out = ''
	  for (var i = start; i < end; ++i) {
	    out += toHex(buf[i])
	  }
	  return out
	}
	
	function utf16leSlice (buf, start, end) {
	  var bytes = buf.slice(start, end)
	  var res = ''
	  for (var i = 0; i < bytes.length; i += 2) {
	    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
	  }
	  return res
	}
	
	Buffer.prototype.slice = function slice (start, end) {
	  var len = this.length
	  start = ~~start
	  end = end === undefined ? len : ~~end
	
	  if (start < 0) {
	    start += len
	    if (start < 0) start = 0
	  } else if (start > len) {
	    start = len
	  }
	
	  if (end < 0) {
	    end += len
	    if (end < 0) end = 0
	  } else if (end > len) {
	    end = len
	  }
	
	  if (end < start) end = start
	
	  var newBuf
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    newBuf = this.subarray(start, end)
	    newBuf.__proto__ = Buffer.prototype
	  } else {
	    var sliceLen = end - start
	    newBuf = new Buffer(sliceLen, undefined)
	    for (var i = 0; i < sliceLen; ++i) {
	      newBuf[i] = this[i + start]
	    }
	  }
	
	  return newBuf
	}
	
	/*
	 * Need to make sure that buffer isn't trying to write out of bounds.
	 */
	function checkOffset (offset, ext, length) {
	  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
	  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
	}
	
	Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)
	
	  var val = this[offset]
	  var mul = 1
	  var i = 0
	  while (++i < byteLength && (mul *= 0x100)) {
	    val += this[offset + i] * mul
	  }
	
	  return val
	}
	
	Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) {
	    checkOffset(offset, byteLength, this.length)
	  }
	
	  var val = this[offset + --byteLength]
	  var mul = 1
	  while (byteLength > 0 && (mul *= 0x100)) {
	    val += this[offset + --byteLength] * mul
	  }
	
	  return val
	}
	
	Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 1, this.length)
	  return this[offset]
	}
	
	Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  return this[offset] | (this[offset + 1] << 8)
	}
	
	Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  return (this[offset] << 8) | this[offset + 1]
	}
	
	Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return ((this[offset]) |
	      (this[offset + 1] << 8) |
	      (this[offset + 2] << 16)) +
	      (this[offset + 3] * 0x1000000)
	}
	
	Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return (this[offset] * 0x1000000) +
	    ((this[offset + 1] << 16) |
	    (this[offset + 2] << 8) |
	    this[offset + 3])
	}
	
	Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)
	
	  var val = this[offset]
	  var mul = 1
	  var i = 0
	  while (++i < byteLength && (mul *= 0x100)) {
	    val += this[offset + i] * mul
	  }
	  mul *= 0x80
	
	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
	
	  return val
	}
	
	Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) checkOffset(offset, byteLength, this.length)
	
	  var i = byteLength
	  var mul = 1
	  var val = this[offset + --i]
	  while (i > 0 && (mul *= 0x100)) {
	    val += this[offset + --i] * mul
	  }
	  mul *= 0x80
	
	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
	
	  return val
	}
	
	Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 1, this.length)
	  if (!(this[offset] & 0x80)) return (this[offset])
	  return ((0xff - this[offset] + 1) * -1)
	}
	
	Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  var val = this[offset] | (this[offset + 1] << 8)
	  return (val & 0x8000) ? val | 0xFFFF0000 : val
	}
	
	Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 2, this.length)
	  var val = this[offset + 1] | (this[offset] << 8)
	  return (val & 0x8000) ? val | 0xFFFF0000 : val
	}
	
	Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return (this[offset]) |
	    (this[offset + 1] << 8) |
	    (this[offset + 2] << 16) |
	    (this[offset + 3] << 24)
	}
	
	Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	
	  return (this[offset] << 24) |
	    (this[offset + 1] << 16) |
	    (this[offset + 2] << 8) |
	    (this[offset + 3])
	}
	
	Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	  return ieee754.read(this, offset, true, 23, 4)
	}
	
	Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 4, this.length)
	  return ieee754.read(this, offset, false, 23, 4)
	}
	
	Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 8, this.length)
	  return ieee754.read(this, offset, true, 52, 8)
	}
	
	Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
	  if (!noAssert) checkOffset(offset, 8, this.length)
	  return ieee754.read(this, offset, false, 52, 8)
	}
	
	function checkInt (buf, value, offset, ext, max, min) {
	  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
	  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
	  if (offset + ext > buf.length) throw new RangeError('Index out of range')
	}
	
	Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) {
	    var maxBytes = Math.pow(2, 8 * byteLength) - 1
	    checkInt(this, value, offset, byteLength, maxBytes, 0)
	  }
	
	  var mul = 1
	  var i = 0
	  this[offset] = value & 0xFF
	  while (++i < byteLength && (mul *= 0x100)) {
	    this[offset + i] = (value / mul) & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  byteLength = byteLength | 0
	  if (!noAssert) {
	    var maxBytes = Math.pow(2, 8 * byteLength) - 1
	    checkInt(this, value, offset, byteLength, maxBytes, 0)
	  }
	
	  var i = byteLength - 1
	  var mul = 1
	  this[offset + i] = value & 0xFF
	  while (--i >= 0 && (mul *= 0x100)) {
	    this[offset + i] = (value / mul) & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
	  this[offset] = (value & 0xff)
	  return offset + 1
	}
	
	function objectWriteUInt16 (buf, value, offset, littleEndian) {
	  if (value < 0) value = 0xffff + value + 1
	  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
	    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
	      (littleEndian ? i : 1 - i) * 8
	  }
	}
	
	Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	  } else {
	    objectWriteUInt16(this, value, offset, true)
	  }
	  return offset + 2
	}
	
	Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 8)
	    this[offset + 1] = (value & 0xff)
	  } else {
	    objectWriteUInt16(this, value, offset, false)
	  }
	  return offset + 2
	}
	
	function objectWriteUInt32 (buf, value, offset, littleEndian) {
	  if (value < 0) value = 0xffffffff + value + 1
	  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
	    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
	  }
	}
	
	Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset + 3] = (value >>> 24)
	    this[offset + 2] = (value >>> 16)
	    this[offset + 1] = (value >>> 8)
	    this[offset] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, true)
	  }
	  return offset + 4
	}
	
	Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 24)
	    this[offset + 1] = (value >>> 16)
	    this[offset + 2] = (value >>> 8)
	    this[offset + 3] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, false)
	  }
	  return offset + 4
	}
	
	Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) {
	    var limit = Math.pow(2, 8 * byteLength - 1)
	
	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
	  }
	
	  var i = 0
	  var mul = 1
	  var sub = 0
	  this[offset] = value & 0xFF
	  while (++i < byteLength && (mul *= 0x100)) {
	    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
	      sub = 1
	    }
	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) {
	    var limit = Math.pow(2, 8 * byteLength - 1)
	
	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
	  }
	
	  var i = byteLength - 1
	  var mul = 1
	  var sub = 0
	  this[offset + i] = value & 0xFF
	  while (--i >= 0 && (mul *= 0x100)) {
	    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
	      sub = 1
	    }
	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
	  }
	
	  return offset + byteLength
	}
	
	Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
	  if (value < 0) value = 0xff + value + 1
	  this[offset] = (value & 0xff)
	  return offset + 1
	}
	
	Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	  } else {
	    objectWriteUInt16(this, value, offset, true)
	  }
	  return offset + 2
	}
	
	Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 8)
	    this[offset + 1] = (value & 0xff)
	  } else {
	    objectWriteUInt16(this, value, offset, false)
	  }
	  return offset + 2
	}
	
	Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value & 0xff)
	    this[offset + 1] = (value >>> 8)
	    this[offset + 2] = (value >>> 16)
	    this[offset + 3] = (value >>> 24)
	  } else {
	    objectWriteUInt32(this, value, offset, true)
	  }
	  return offset + 4
	}
	
	Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
	  value = +value
	  offset = offset | 0
	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
	  if (value < 0) value = 0xffffffff + value + 1
	  if (Buffer.TYPED_ARRAY_SUPPORT) {
	    this[offset] = (value >>> 24)
	    this[offset + 1] = (value >>> 16)
	    this[offset + 2] = (value >>> 8)
	    this[offset + 3] = (value & 0xff)
	  } else {
	    objectWriteUInt32(this, value, offset, false)
	  }
	  return offset + 4
	}
	
	function checkIEEE754 (buf, value, offset, ext, max, min) {
	  if (offset + ext > buf.length) throw new RangeError('Index out of range')
	  if (offset < 0) throw new RangeError('Index out of range')
	}
	
	function writeFloat (buf, value, offset, littleEndian, noAssert) {
	  if (!noAssert) {
	    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
	  }
	  ieee754.write(buf, value, offset, littleEndian, 23, 4)
	  return offset + 4
	}
	
	Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
	  return writeFloat(this, value, offset, true, noAssert)
	}
	
	Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
	  return writeFloat(this, value, offset, false, noAssert)
	}
	
	function writeDouble (buf, value, offset, littleEndian, noAssert) {
	  if (!noAssert) {
	    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
	  }
	  ieee754.write(buf, value, offset, littleEndian, 52, 8)
	  return offset + 8
	}
	
	Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
	  return writeDouble(this, value, offset, true, noAssert)
	}
	
	Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
	  return writeDouble(this, value, offset, false, noAssert)
	}
	
	// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
	Buffer.prototype.copy = function copy (target, targetStart, start, end) {
	  if (!start) start = 0
	  if (!end && end !== 0) end = this.length
	  if (targetStart >= target.length) targetStart = target.length
	  if (!targetStart) targetStart = 0
	  if (end > 0 && end < start) end = start
	
	  // Copy 0 bytes; we're done
	  if (end === start) return 0
	  if (target.length === 0 || this.length === 0) return 0
	
	  // Fatal error conditions
	  if (targetStart < 0) {
	    throw new RangeError('targetStart out of bounds')
	  }
	  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
	  if (end < 0) throw new RangeError('sourceEnd out of bounds')
	
	  // Are we oob?
	  if (end > this.length) end = this.length
	  if (target.length - targetStart < end - start) {
	    end = target.length - targetStart + start
	  }
	
	  var len = end - start
	  var i
	
	  if (this === target && start < targetStart && targetStart < end) {
	    // descending copy from end
	    for (i = len - 1; i >= 0; --i) {
	      target[i + targetStart] = this[i + start]
	    }
	  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
	    // ascending copy from start
	    for (i = 0; i < len; ++i) {
	      target[i + targetStart] = this[i + start]
	    }
	  } else {
	    Uint8Array.prototype.set.call(
	      target,
	      this.subarray(start, start + len),
	      targetStart
	    )
	  }
	
	  return len
	}
	
	// Usage:
	//    buffer.fill(number[, offset[, end]])
	//    buffer.fill(buffer[, offset[, end]])
	//    buffer.fill(string[, offset[, end]][, encoding])
	Buffer.prototype.fill = function fill (val, start, end, encoding) {
	  // Handle string cases:
	  if (typeof val === 'string') {
	    if (typeof start === 'string') {
	      encoding = start
	      start = 0
	      end = this.length
	    } else if (typeof end === 'string') {
	      encoding = end
	      end = this.length
	    }
	    if (val.length === 1) {
	      var code = val.charCodeAt(0)
	      if (code < 256) {
	        val = code
	      }
	    }
	    if (encoding !== undefined && typeof encoding !== 'string') {
	      throw new TypeError('encoding must be a string')
	    }
	    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
	      throw new TypeError('Unknown encoding: ' + encoding)
	    }
	  } else if (typeof val === 'number') {
	    val = val & 255
	  }
	
	  // Invalid ranges are not set to a default, so can range check early.
	  if (start < 0 || this.length < start || this.length < end) {
	    throw new RangeError('Out of range index')
	  }
	
	  if (end <= start) {
	    return this
	  }
	
	  start = start >>> 0
	  end = end === undefined ? this.length : end >>> 0
	
	  if (!val) val = 0
	
	  var i
	  if (typeof val === 'number') {
	    for (i = start; i < end; ++i) {
	      this[i] = val
	    }
	  } else {
	    var bytes = Buffer.isBuffer(val)
	      ? val
	      : utf8ToBytes(new Buffer(val, encoding).toString())
	    var len = bytes.length
	    for (i = 0; i < end - start; ++i) {
	      this[i + start] = bytes[i % len]
	    }
	  }
	
	  return this
	}
	
	// HELPER FUNCTIONS
	// ================
	
	var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
	
	function base64clean (str) {
	  // Node strips out invalid characters like \n and \t from the string, base64-js does not
	  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
	  // Node converts strings with length < 2 to ''
	  if (str.length < 2) return ''
	  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
	  while (str.length % 4 !== 0) {
	    str = str + '='
	  }
	  return str
	}
	
	function stringtrim (str) {
	  if (str.trim) return str.trim()
	  return str.replace(/^\s+|\s+$/g, '')
	}
	
	function toHex (n) {
	  if (n < 16) return '0' + n.toString(16)
	  return n.toString(16)
	}
	
	function utf8ToBytes (string, units) {
	  units = units || Infinity
	  var codePoint
	  var length = string.length
	  var leadSurrogate = null
	  var bytes = []
	
	  for (var i = 0; i < length; ++i) {
	    codePoint = string.charCodeAt(i)
	
	    // is surrogate component
	    if (codePoint > 0xD7FF && codePoint < 0xE000) {
	      // last char was a lead
	      if (!leadSurrogate) {
	        // no lead yet
	        if (codePoint > 0xDBFF) {
	          // unexpected trail
	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	          continue
	        } else if (i + 1 === length) {
	          // unpaired lead
	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	          continue
	        }
	
	        // valid lead
	        leadSurrogate = codePoint
	
	        continue
	      }
	
	      // 2 leads in a row
	      if (codePoint < 0xDC00) {
	        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	        leadSurrogate = codePoint
	        continue
	      }
	
	      // valid surrogate pair
	      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
	    } else if (leadSurrogate) {
	      // valid bmp char, but last char was a lead
	      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
	    }
	
	    leadSurrogate = null
	
	    // encode utf8
	    if (codePoint < 0x80) {
	      if ((units -= 1) < 0) break
	      bytes.push(codePoint)
	    } else if (codePoint < 0x800) {
	      if ((units -= 2) < 0) break
	      bytes.push(
	        codePoint >> 0x6 | 0xC0,
	        codePoint & 0x3F | 0x80
	      )
	    } else if (codePoint < 0x10000) {
	      if ((units -= 3) < 0) break
	      bytes.push(
	        codePoint >> 0xC | 0xE0,
	        codePoint >> 0x6 & 0x3F | 0x80,
	        codePoint & 0x3F | 0x80
	      )
	    } else if (codePoint < 0x110000) {
	      if ((units -= 4) < 0) break
	      bytes.push(
	        codePoint >> 0x12 | 0xF0,
	        codePoint >> 0xC & 0x3F | 0x80,
	        codePoint >> 0x6 & 0x3F | 0x80,
	        codePoint & 0x3F | 0x80
	      )
	    } else {
	      throw new Error('Invalid code point')
	    }
	  }
	
	  return bytes
	}
	
	function asciiToBytes (str) {
	  var byteArray = []
	  for (var i = 0; i < str.length; ++i) {
	    // Node's code seems to be doing this and not & 0x7F..
	    byteArray.push(str.charCodeAt(i) & 0xFF)
	  }
	  return byteArray
	}
	
	function utf16leToBytes (str, units) {
	  var c, hi, lo
	  var byteArray = []
	  for (var i = 0; i < str.length; ++i) {
	    if ((units -= 2) < 0) break
	
	    c = str.charCodeAt(i)
	    hi = c >> 8
	    lo = c % 256
	    byteArray.push(lo)
	    byteArray.push(hi)
	  }
	
	  return byteArray
	}
	
	function base64ToBytes (str) {
	  return base64.toByteArray(base64clean(str))
	}
	
	function blitBuffer (src, dst, offset, length) {
	  for (var i = 0; i < length; ++i) {
	    if ((i + offset >= dst.length) || (i >= src.length)) break
	    dst[i + offset] = src[i]
	  }
	  return i
	}
	
	function isnan (val) {
	  return val !== val // eslint-disable-line no-self-compare
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
})
/** END DEFINE BLOCK for buffer@4.9.1/index.js **/


/** START DEFINE BLOCK for ieee754@1.1.8/index.js **/
jupyter.define('ieee754@1.1.8/index.js', function (module, exports, __jupyter_require__) {
	exports.read = function (buffer, offset, isLE, mLen, nBytes) {
	  var e, m
	  var eLen = nBytes * 8 - mLen - 1
	  var eMax = (1 << eLen) - 1
	  var eBias = eMax >> 1
	  var nBits = -7
	  var i = isLE ? (nBytes - 1) : 0
	  var d = isLE ? -1 : 1
	  var s = buffer[offset + i]
	
	  i += d
	
	  e = s & ((1 << (-nBits)) - 1)
	  s >>= (-nBits)
	  nBits += eLen
	  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
	
	  m = e & ((1 << (-nBits)) - 1)
	  e >>= (-nBits)
	  nBits += mLen
	  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
	
	  if (e === 0) {
	    e = 1 - eBias
	  } else if (e === eMax) {
	    return m ? NaN : ((s ? -1 : 1) * Infinity)
	  } else {
	    m = m + Math.pow(2, mLen)
	    e = e - eBias
	  }
	  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
	}
	
	exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
	  var e, m, c
	  var eLen = nBytes * 8 - mLen - 1
	  var eMax = (1 << eLen) - 1
	  var eBias = eMax >> 1
	  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
	  var i = isLE ? 0 : (nBytes - 1)
	  var d = isLE ? 1 : -1
	  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
	
	  value = Math.abs(value)
	
	  if (isNaN(value) || value === Infinity) {
	    m = isNaN(value) ? 1 : 0
	    e = eMax
	  } else {
	    e = Math.floor(Math.log(value) / Math.LN2)
	    if (value * (c = Math.pow(2, -e)) < 1) {
	      e--
	      c *= 2
	    }
	    if (e + eBias >= 1) {
	      value += rt / c
	    } else {
	      value += rt * Math.pow(2, 1 - eBias)
	    }
	    if (value * c >= 2) {
	      e++
	      c /= 2
	    }
	
	    if (e + eBias >= eMax) {
	      m = 0
	      e = eMax
	    } else if (e + eBias >= 1) {
	      m = (value * c - 1) * Math.pow(2, mLen)
	      e = e + eBias
	    } else {
	      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
	      e = 0
	    }
	  }
	
	  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
	
	  e = (e << mLen) | m
	  eLen += mLen
	  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
	
	  buffer[offset + i - d] |= s * 128
	}
	
})
/** END DEFINE BLOCK for ieee754@1.1.8/index.js **/


/** START DEFINE BLOCK for core-util-is@1.0.2/lib/util.js **/
jupyter.define('core-util-is@1.0.2/lib/util.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// NOTE: These type checking functions intentionally don't use `instanceof`
	// because it is fragile and can be easily faked with `Object.create()`.
	
	function isArray(arg) {
	  if (Array.isArray) {
	    return Array.isArray(arg);
	  }
	  return objectToString(arg) === '[object Array]';
	}
	exports.isArray = isArray;
	
	function isBoolean(arg) {
	  return typeof arg === 'boolean';
	}
	exports.isBoolean = isBoolean;
	
	function isNull(arg) {
	  return arg === null;
	}
	exports.isNull = isNull;
	
	function isNullOrUndefined(arg) {
	  return arg == null;
	}
	exports.isNullOrUndefined = isNullOrUndefined;
	
	function isNumber(arg) {
	  return typeof arg === 'number';
	}
	exports.isNumber = isNumber;
	
	function isString(arg) {
	  return typeof arg === 'string';
	}
	exports.isString = isString;
	
	function isSymbol(arg) {
	  return typeof arg === 'symbol';
	}
	exports.isSymbol = isSymbol;
	
	function isUndefined(arg) {
	  return arg === void 0;
	}
	exports.isUndefined = isUndefined;
	
	function isRegExp(re) {
	  return objectToString(re) === '[object RegExp]';
	}
	exports.isRegExp = isRegExp;
	
	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	exports.isObject = isObject;
	
	function isDate(d) {
	  return objectToString(d) === '[object Date]';
	}
	exports.isDate = isDate;
	
	function isError(e) {
	  return (objectToString(e) === '[object Error]' || e instanceof Error);
	}
	exports.isError = isError;
	
	function isFunction(arg) {
	  return typeof arg === 'function';
	}
	exports.isFunction = isFunction;
	
	function isPrimitive(arg) {
	  return arg === null ||
	         typeof arg === 'boolean' ||
	         typeof arg === 'number' ||
	         typeof arg === 'string' ||
	         typeof arg === 'symbol' ||  // ES6 symbol
	         typeof arg === 'undefined';
	}
	exports.isPrimitive = isPrimitive;
	
	exports.isBuffer = Buffer.isBuffer;
	
	function objectToString(o) {
	  return Object.prototype.toString.call(o);
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('buffer@4.9.1/index.js').Buffer))
})
/** END DEFINE BLOCK for core-util-is@1.0.2/lib/util.js **/


/** START DEFINE BLOCK for __ignored__ **/
jupyter.define('__ignored__', function (module, exports, __jupyter_require__) {
	/* (ignored) */
})
/** END DEFINE BLOCK for __ignored__ **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/internal/streams/BufferList.js **/
jupyter.define('readable-stream@2.3.2/lib/internal/streams/BufferList.js', function (module, exports, __jupyter_require__) {
	'use strict';
	
	/*<replacement>*/
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
	
	var Buffer = __jupyter_require__('safe-buffer@~5.1.0/index.js').Buffer;
	/*</replacement>*/
	
	function copyBuffer(src, target, offset) {
	  src.copy(target, offset);
	}
	
	module.exports = function () {
	  function BufferList() {
	    _classCallCheck(this, BufferList);
	
	    this.head = null;
	    this.tail = null;
	    this.length = 0;
	  }
	
	  BufferList.prototype.push = function push(v) {
	    var entry = { data: v, next: null };
	    if (this.length > 0) this.tail.next = entry;else this.head = entry;
	    this.tail = entry;
	    ++this.length;
	  };
	
	  BufferList.prototype.unshift = function unshift(v) {
	    var entry = { data: v, next: this.head };
	    if (this.length === 0) this.tail = entry;
	    this.head = entry;
	    ++this.length;
	  };
	
	  BufferList.prototype.shift = function shift() {
	    if (this.length === 0) return;
	    var ret = this.head.data;
	    if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
	    --this.length;
	    return ret;
	  };
	
	  BufferList.prototype.clear = function clear() {
	    this.head = this.tail = null;
	    this.length = 0;
	  };
	
	  BufferList.prototype.join = function join(s) {
	    if (this.length === 0) return '';
	    var p = this.head;
	    var ret = '' + p.data;
	    while (p = p.next) {
	      ret += s + p.data;
	    }return ret;
	  };
	
	  BufferList.prototype.concat = function concat(n) {
	    if (this.length === 0) return Buffer.alloc(0);
	    if (this.length === 1) return this.head.data;
	    var ret = Buffer.allocUnsafe(n >>> 0);
	    var p = this.head;
	    var i = 0;
	    while (p) {
	      copyBuffer(p.data, ret, i);
	      i += p.data.length;
	      p = p.next;
	    }
	    return ret;
	  };
	
	  return BufferList;
	}();
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/internal/streams/BufferList.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/internal/streams/destroy.js **/
jupyter.define('readable-stream@2.3.2/lib/internal/streams/destroy.js', function (module, exports, __jupyter_require__) {
	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __jupyter_require__('process-nextick-args@~1.0.6/index.js');
	/*</replacement>*/
	
	// undocumented cb() API, needed for core, not for public API
	function destroy(err, cb) {
	  var _this = this;
	
	  var readableDestroyed = this._readableState && this._readableState.destroyed;
	  var writableDestroyed = this._writableState && this._writableState.destroyed;
	
	  if (readableDestroyed || writableDestroyed) {
	    if (cb) {
	      cb(err);
	    } else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
	      processNextTick(emitErrorNT, this, err);
	    }
	    return;
	  }
	
	  // we set destroyed to true before firing error callbacks in order
	  // to make it re-entrance safe in case destroy() is called within callbacks
	
	  if (this._readableState) {
	    this._readableState.destroyed = true;
	  }
	
	  // if this is a duplex stream mark the writable part as destroyed as well
	  if (this._writableState) {
	    this._writableState.destroyed = true;
	  }
	
	  this._destroy(err || null, function (err) {
	    if (!cb && err) {
	      processNextTick(emitErrorNT, _this, err);
	      if (_this._writableState) {
	        _this._writableState.errorEmitted = true;
	      }
	    } else if (cb) {
	      cb(err);
	    }
	  });
	}
	
	function undestroy() {
	  if (this._readableState) {
	    this._readableState.destroyed = false;
	    this._readableState.reading = false;
	    this._readableState.ended = false;
	    this._readableState.endEmitted = false;
	  }
	
	  if (this._writableState) {
	    this._writableState.destroyed = false;
	    this._writableState.ended = false;
	    this._writableState.ending = false;
	    this._writableState.finished = false;
	    this._writableState.errorEmitted = false;
	  }
	}
	
	function emitErrorNT(self, err) {
	  self.emit('error', err);
	}
	
	module.exports = {
	  destroy: destroy,
	  undestroy: undestroy
	};
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/internal/streams/destroy.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_duplex.js **/
jupyter.define('readable-stream@2.3.2/lib/_stream_duplex.js', function (module, exports, __jupyter_require__) {
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// a duplex stream is just a stream that is both readable and writable.
	// Since JS doesn't have multiple prototypal inheritance, this class
	// prototypally inherits from Readable, and then parasitically from
	// Writable.
	
	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __jupyter_require__('process-nextick-args@~1.0.6/index.js');
	/*</replacement>*/
	
	/*<replacement>*/
	var objectKeys = Object.keys || function (obj) {
	  var keys = [];
	  for (var key in obj) {
	    keys.push(key);
	  }return keys;
	};
	/*</replacement>*/
	
	module.exports = Duplex;
	
	/*<replacement>*/
	var util = __jupyter_require__('core-util-is@~1.0.0/lib/util.js');
	util.inherits = __jupyter_require__('inherits@~2.0.3/inherits_browser.js');
	/*</replacement>*/
	
	var Readable = __jupyter_require__('readable-stream@2.3.2/lib/_stream_readable.js');
	var Writable = __jupyter_require__('readable-stream@2.3.2/lib/_stream_writable.js');
	
	util.inherits(Duplex, Readable);
	
	var keys = objectKeys(Writable.prototype);
	for (var v = 0; v < keys.length; v++) {
	  var method = keys[v];
	  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
	}
	
	function Duplex(options) {
	  if (!(this instanceof Duplex)) return new Duplex(options);
	
	  Readable.call(this, options);
	  Writable.call(this, options);
	
	  if (options && options.readable === false) this.readable = false;
	
	  if (options && options.writable === false) this.writable = false;
	
	  this.allowHalfOpen = true;
	  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
	
	  this.once('end', onend);
	}
	
	// the no-half-open enforcer
	function onend() {
	  // if we allow half-open state, or if the writable side ended,
	  // then we're ok.
	  if (this.allowHalfOpen || this._writableState.ended) return;
	
	  // no more data can be written.
	  // But allow more writes to happen in this tick.
	  processNextTick(onEndNT, this);
	}
	
	function onEndNT(self) {
	  self.end();
	}
	
	Object.defineProperty(Duplex.prototype, 'destroyed', {
	  get: function () {
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return false;
	    }
	    return this._readableState.destroyed && this._writableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (this._readableState === undefined || this._writableState === undefined) {
	      return;
	    }
	
	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._readableState.destroyed = value;
	    this._writableState.destroyed = value;
	  }
	});
	
	Duplex.prototype._destroy = function (err, cb) {
	  this.push(null);
	  this.end();
	
	  processNextTick(cb, err);
	};
	
	function forEach(xs, f) {
	  for (var i = 0, l = xs.length; i < l; i++) {
	    f(xs[i], i);
	  }
	}
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_duplex.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_writable.js **/
jupyter.define('readable-stream@2.3.2/lib/_stream_writable.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(process, setImmediate) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// A bit simpler than readable streams.
	// Implement an async ._write(chunk, encoding, cb), and it'll handle all
	// the drain event emission and buffering.
	
	'use strict';
	
	/*<replacement>*/
	
	var processNextTick = __jupyter_require__('process-nextick-args@~1.0.6/index.js');
	/*</replacement>*/
	
	module.exports = Writable;
	
	/* <replacement> */
	function WriteReq(chunk, encoding, cb) {
	  this.chunk = chunk;
	  this.encoding = encoding;
	  this.callback = cb;
	  this.next = null;
	}
	
	// It seems a linked list but it is not
	// there will be only 2 of these for each stream
	function CorkedRequest(state) {
	  var _this = this;
	
	  this.next = null;
	  this.entry = null;
	  this.finish = function () {
	    onCorkedFinish(_this, state);
	  };
	}
	/* </replacement> */
	
	/*<replacement>*/
	var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
	/*</replacement>*/
	
	/*<replacement>*/
	var Duplex;
	/*</replacement>*/
	
	Writable.WritableState = WritableState;
	
	/*<replacement>*/
	var util = __jupyter_require__('core-util-is@~1.0.0/lib/util.js');
	util.inherits = __jupyter_require__('inherits@~2.0.3/inherits_browser.js');
	/*</replacement>*/
	
	/*<replacement>*/
	var internalUtil = {
	  deprecate: __jupyter_require__('util-deprecate@~1.0.1/browser.js')
	};
	/*</replacement>*/
	
	/*<replacement>*/
	var Stream = __jupyter_require__('readable-stream@2.3.2/lib/internal/streams/stream-browser.js');
	/*</replacement>*/
	
	/*<replacement>*/
	var Buffer = __jupyter_require__('safe-buffer@~5.1.0/index.js').Buffer;
	function _uint8ArrayToBuffer(chunk) {
	  return Buffer.from(chunk);
	}
	function _isUint8Array(obj) {
	  return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj);
	}
	/*</replacement>*/
	
	var destroyImpl = __jupyter_require__('readable-stream@2.3.2/lib/internal/streams/destroy.js');
	
	util.inherits(Writable, Stream);
	
	function nop() {}
	
	function WritableState(options, stream) {
	  Duplex = Duplex || __jupyter_require__('readable-stream@2.3.2/lib/_stream_duplex.js');
	
	  options = options || {};
	
	  // object stream flag to indicate whether or not this stream
	  // contains buffers or objects.
	  this.objectMode = !!options.objectMode;
	
	  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
	
	  // the point at which write() starts returning false
	  // Note: 0 is a valid value, means that we always return false if
	  // the entire buffer is not flushed immediately on write()
	  var hwm = options.highWaterMark;
	  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
	  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
	
	  // cast to ints.
	  this.highWaterMark = Math.floor(this.highWaterMark);
	
	  // if _final has been called
	  this.finalCalled = false;
	
	  // drain event flag.
	  this.needDrain = false;
	  // at the start of calling end()
	  this.ending = false;
	  // when end() has been called, and returned
	  this.ended = false;
	  // when 'finish' is emitted
	  this.finished = false;
	
	  // has it been destroyed
	  this.destroyed = false;
	
	  // should we decode strings into buffers before passing to _write?
	  // this is here so that some node-core streams can optimize string
	  // handling at a lower level.
	  var noDecode = options.decodeStrings === false;
	  this.decodeStrings = !noDecode;
	
	  // Crypto is kind of old and crusty.  Historically, its default string
	  // encoding is 'binary' so we have to make this configurable.
	  // Everything else in the universe uses 'utf8', though.
	  this.defaultEncoding = options.defaultEncoding || 'utf8';
	
	  // not an actual buffer we keep track of, but a measurement
	  // of how much we're waiting to get pushed to some underlying
	  // socket or file.
	  this.length = 0;
	
	  // a flag to see when we're in the middle of a write.
	  this.writing = false;
	
	  // when true all writes will be buffered until .uncork() call
	  this.corked = 0;
	
	  // a flag to be able to tell if the onwrite cb is called immediately,
	  // or on a later tick.  We set this to true at first, because any
	  // actions that shouldn't happen until "later" should generally also
	  // not happen before the first write call.
	  this.sync = true;
	
	  // a flag to know if we're processing previously buffered items, which
	  // may call the _write() callback in the same tick, so that we don't
	  // end up in an overlapped onwrite situation.
	  this.bufferProcessing = false;
	
	  // the callback that's passed to _write(chunk,cb)
	  this.onwrite = function (er) {
	    onwrite(stream, er);
	  };
	
	  // the callback that the user supplies to write(chunk,encoding,cb)
	  this.writecb = null;
	
	  // the amount that is being written when _write is called.
	  this.writelen = 0;
	
	  this.bufferedRequest = null;
	  this.lastBufferedRequest = null;
	
	  // number of pending user-supplied write callbacks
	  // this must be 0 before 'finish' can be emitted
	  this.pendingcb = 0;
	
	  // emit prefinish if the only thing we're waiting for is _write cbs
	  // This is relevant for synchronous Transform streams
	  this.prefinished = false;
	
	  // True if the error was already emitted and should not be thrown again
	  this.errorEmitted = false;
	
	  // count buffered requests
	  this.bufferedRequestCount = 0;
	
	  // allocate the first CorkedRequest, there is always
	  // one allocated and free to use, and we maintain at most two
	  this.corkedRequestsFree = new CorkedRequest(this);
	}
	
	WritableState.prototype.getBuffer = function getBuffer() {
	  var current = this.bufferedRequest;
	  var out = [];
	  while (current) {
	    out.push(current);
	    current = current.next;
	  }
	  return out;
	};
	
	(function () {
	  try {
	    Object.defineProperty(WritableState.prototype, 'buffer', {
	      get: internalUtil.deprecate(function () {
	        return this.getBuffer();
	      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
	    });
	  } catch (_) {}
	})();
	
	// Test _writableState for inheritance to account for Duplex streams,
	// whose prototype chain only points to Readable.
	var realHasInstance;
	if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
	  realHasInstance = Function.prototype[Symbol.hasInstance];
	  Object.defineProperty(Writable, Symbol.hasInstance, {
	    value: function (object) {
	      if (realHasInstance.call(this, object)) return true;
	
	      return object && object._writableState instanceof WritableState;
	    }
	  });
	} else {
	  realHasInstance = function (object) {
	    return object instanceof this;
	  };
	}
	
	function Writable(options) {
	  Duplex = Duplex || __jupyter_require__('readable-stream@2.3.2/lib/_stream_duplex.js');
	
	  // Writable ctor is applied to Duplexes, too.
	  // `realHasInstance` is necessary because using plain `instanceof`
	  // would return false, as no `_writableState` property is attached.
	
	  // Trying to use the custom `instanceof` for Writable here will also break the
	  // Node.js LazyTransform implementation, which has a non-trivial getter for
	  // `_writableState` that would lead to infinite recursion.
	  if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
	    return new Writable(options);
	  }
	
	  this._writableState = new WritableState(options, this);
	
	  // legacy.
	  this.writable = true;
	
	  if (options) {
	    if (typeof options.write === 'function') this._write = options.write;
	
	    if (typeof options.writev === 'function') this._writev = options.writev;
	
	    if (typeof options.destroy === 'function') this._destroy = options.destroy;
	
	    if (typeof options.final === 'function') this._final = options.final;
	  }
	
	  Stream.call(this);
	}
	
	// Otherwise people can pipe Writable streams, which is just wrong.
	Writable.prototype.pipe = function () {
	  this.emit('error', new Error('Cannot pipe, not readable'));
	};
	
	function writeAfterEnd(stream, cb) {
	  var er = new Error('write after end');
	  // TODO: defer error events consistently everywhere, not just the cb
	  stream.emit('error', er);
	  processNextTick(cb, er);
	}
	
	// Checks that a user-supplied chunk is valid, especially for the particular
	// mode the stream is in. Currently this means that `null` is never accepted
	// and undefined/non-string values are only allowed in object mode.
	function validChunk(stream, state, chunk, cb) {
	  var valid = true;
	  var er = false;
	
	  if (chunk === null) {
	    er = new TypeError('May not write null values to stream');
	  } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
	    er = new TypeError('Invalid non-string/buffer chunk');
	  }
	  if (er) {
	    stream.emit('error', er);
	    processNextTick(cb, er);
	    valid = false;
	  }
	  return valid;
	}
	
	Writable.prototype.write = function (chunk, encoding, cb) {
	  var state = this._writableState;
	  var ret = false;
	  var isBuf = _isUint8Array(chunk) && !state.objectMode;
	
	  if (isBuf && !Buffer.isBuffer(chunk)) {
	    chunk = _uint8ArrayToBuffer(chunk);
	  }
	
	  if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }
	
	  if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
	
	  if (typeof cb !== 'function') cb = nop;
	
	  if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
	    state.pendingcb++;
	    ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
	  }
	
	  return ret;
	};
	
	Writable.prototype.cork = function () {
	  var state = this._writableState;
	
	  state.corked++;
	};
	
	Writable.prototype.uncork = function () {
	  var state = this._writableState;
	
	  if (state.corked) {
	    state.corked--;
	
	    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
	  }
	};
	
	Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
	  // node::ParseEncoding() requires lower case.
	  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
	  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
	  this._writableState.defaultEncoding = encoding;
	  return this;
	};
	
	function decodeChunk(state, chunk, encoding) {
	  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
	    chunk = Buffer.from(chunk, encoding);
	  }
	  return chunk;
	}
	
	// if we're already writing something, then just put this
	// in the queue, and wait our turn.  Otherwise, call _write
	// If we return false, then we need a drain event, so set that flag.
	function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
	  if (!isBuf) {
	    var newChunk = decodeChunk(state, chunk, encoding);
	    if (chunk !== newChunk) {
	      isBuf = true;
	      encoding = 'buffer';
	      chunk = newChunk;
	    }
	  }
	  var len = state.objectMode ? 1 : chunk.length;
	
	  state.length += len;
	
	  var ret = state.length < state.highWaterMark;
	  // we must ensure that previous needDrain will not be reset to false.
	  if (!ret) state.needDrain = true;
	
	  if (state.writing || state.corked) {
	    var last = state.lastBufferedRequest;
	    state.lastBufferedRequest = {
	      chunk: chunk,
	      encoding: encoding,
	      isBuf: isBuf,
	      callback: cb,
	      next: null
	    };
	    if (last) {
	      last.next = state.lastBufferedRequest;
	    } else {
	      state.bufferedRequest = state.lastBufferedRequest;
	    }
	    state.bufferedRequestCount += 1;
	  } else {
	    doWrite(stream, state, false, len, chunk, encoding, cb);
	  }
	
	  return ret;
	}
	
	function doWrite(stream, state, writev, len, chunk, encoding, cb) {
	  state.writelen = len;
	  state.writecb = cb;
	  state.writing = true;
	  state.sync = true;
	  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
	  state.sync = false;
	}
	
	function onwriteError(stream, state, sync, er, cb) {
	  --state.pendingcb;
	
	  if (sync) {
	    // defer the callback if we are being called synchronously
	    // to avoid piling up things on the stack
	    processNextTick(cb, er);
	    // this can emit finish, and it will always happen
	    // after error
	    processNextTick(finishMaybe, stream, state);
	    stream._writableState.errorEmitted = true;
	    stream.emit('error', er);
	  } else {
	    // the caller expect this to happen before if
	    // it is async
	    cb(er);
	    stream._writableState.errorEmitted = true;
	    stream.emit('error', er);
	    // this can emit finish, but finish must
	    // always follow error
	    finishMaybe(stream, state);
	  }
	}
	
	function onwriteStateUpdate(state) {
	  state.writing = false;
	  state.writecb = null;
	  state.length -= state.writelen;
	  state.writelen = 0;
	}
	
	function onwrite(stream, er) {
	  var state = stream._writableState;
	  var sync = state.sync;
	  var cb = state.writecb;
	
	  onwriteStateUpdate(state);
	
	  if (er) onwriteError(stream, state, sync, er, cb);else {
	    // Check if we're actually ready to finish, but don't emit yet
	    var finished = needFinish(state);
	
	    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
	      clearBuffer(stream, state);
	    }
	
	    if (sync) {
	      /*<replacement>*/
	      asyncWrite(afterWrite, stream, state, finished, cb);
	      /*</replacement>*/
	    } else {
	      afterWrite(stream, state, finished, cb);
	    }
	  }
	}
	
	function afterWrite(stream, state, finished, cb) {
	  if (!finished) onwriteDrain(stream, state);
	  state.pendingcb--;
	  cb();
	  finishMaybe(stream, state);
	}
	
	// Must force callback to be called on nextTick, so that we don't
	// emit 'drain' before the write() consumer gets the 'false' return
	// value, and has a chance to attach a 'drain' listener.
	function onwriteDrain(stream, state) {
	  if (state.length === 0 && state.needDrain) {
	    state.needDrain = false;
	    stream.emit('drain');
	  }
	}
	
	// if there's something in the buffer waiting, then process it
	function clearBuffer(stream, state) {
	  state.bufferProcessing = true;
	  var entry = state.bufferedRequest;
	
	  if (stream._writev && entry && entry.next) {
	    // Fast case, write everything using _writev()
	    var l = state.bufferedRequestCount;
	    var buffer = new Array(l);
	    var holder = state.corkedRequestsFree;
	    holder.entry = entry;
	
	    var count = 0;
	    var allBuffers = true;
	    while (entry) {
	      buffer[count] = entry;
	      if (!entry.isBuf) allBuffers = false;
	      entry = entry.next;
	      count += 1;
	    }
	    buffer.allBuffers = allBuffers;
	
	    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
	
	    // doWrite is almost always async, defer these to save a bit of time
	    // as the hot path ends with doWrite
	    state.pendingcb++;
	    state.lastBufferedRequest = null;
	    if (holder.next) {
	      state.corkedRequestsFree = holder.next;
	      holder.next = null;
	    } else {
	      state.corkedRequestsFree = new CorkedRequest(state);
	    }
	  } else {
	    // Slow case, write chunks one-by-one
	    while (entry) {
	      var chunk = entry.chunk;
	      var encoding = entry.encoding;
	      var cb = entry.callback;
	      var len = state.objectMode ? 1 : chunk.length;
	
	      doWrite(stream, state, false, len, chunk, encoding, cb);
	      entry = entry.next;
	      // if we didn't call the onwrite immediately, then
	      // it means that we need to wait until it does.
	      // also, that means that the chunk and cb are currently
	      // being processed, so move the buffer counter past them.
	      if (state.writing) {
	        break;
	      }
	    }
	
	    if (entry === null) state.lastBufferedRequest = null;
	  }
	
	  state.bufferedRequestCount = 0;
	  state.bufferedRequest = entry;
	  state.bufferProcessing = false;
	}
	
	Writable.prototype._write = function (chunk, encoding, cb) {
	  cb(new Error('_write() is not implemented'));
	};
	
	Writable.prototype._writev = null;
	
	Writable.prototype.end = function (chunk, encoding, cb) {
	  var state = this._writableState;
	
	  if (typeof chunk === 'function') {
	    cb = chunk;
	    chunk = null;
	    encoding = null;
	  } else if (typeof encoding === 'function') {
	    cb = encoding;
	    encoding = null;
	  }
	
	  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
	
	  // .end() fully uncorks
	  if (state.corked) {
	    state.corked = 1;
	    this.uncork();
	  }
	
	  // ignore unnecessary end() calls.
	  if (!state.ending && !state.finished) endWritable(this, state, cb);
	};
	
	function needFinish(state) {
	  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
	}
	function callFinal(stream, state) {
	  stream._final(function (err) {
	    state.pendingcb--;
	    if (err) {
	      stream.emit('error', err);
	    }
	    state.prefinished = true;
	    stream.emit('prefinish');
	    finishMaybe(stream, state);
	  });
	}
	function prefinish(stream, state) {
	  if (!state.prefinished && !state.finalCalled) {
	    if (typeof stream._final === 'function') {
	      state.pendingcb++;
	      state.finalCalled = true;
	      processNextTick(callFinal, stream, state);
	    } else {
	      state.prefinished = true;
	      stream.emit('prefinish');
	    }
	  }
	}
	
	function finishMaybe(stream, state) {
	  var need = needFinish(state);
	  if (need) {
	    prefinish(stream, state);
	    if (state.pendingcb === 0) {
	      state.finished = true;
	      stream.emit('finish');
	    }
	  }
	  return need;
	}
	
	function endWritable(stream, state, cb) {
	  state.ending = true;
	  finishMaybe(stream, state);
	  if (cb) {
	    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
	  }
	  state.ended = true;
	  stream.writable = false;
	}
	
	function onCorkedFinish(corkReq, state, err) {
	  var entry = corkReq.entry;
	  corkReq.entry = null;
	  while (entry) {
	    var cb = entry.callback;
	    state.pendingcb--;
	    cb(err);
	    entry = entry.next;
	  }
	  if (state.corkedRequestsFree) {
	    state.corkedRequestsFree.next = corkReq;
	  } else {
	    state.corkedRequestsFree = corkReq;
	  }
	}
	
	Object.defineProperty(Writable.prototype, 'destroyed', {
	  get: function () {
	    if (this._writableState === undefined) {
	      return false;
	    }
	    return this._writableState.destroyed;
	  },
	  set: function (value) {
	    // we ignore the value if the stream
	    // has not been initialized yet
	    if (!this._writableState) {
	      return;
	    }
	
	    // backward compatibility, the user is explicitly
	    // managing destroyed
	    this._writableState.destroyed = value;
	  }
	});
	
	Writable.prototype.destroy = destroyImpl.destroy;
	Writable.prototype._undestroy = destroyImpl.undestroy;
	Writable.prototype._destroy = function (err, cb) {
	  this.end();
	  cb(err);
	};
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('process@0.11.10/browser.js'), __jupyter_require__('timers-browserify@2.0.2/main.js').setImmediate))
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_writable.js **/


/** START DEFINE BLOCK for util-deprecate@1.0.2/browser.js **/
jupyter.define('util-deprecate@1.0.2/browser.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(global) {
	/**
	 * Module exports.
	 */
	
	module.exports = deprecate;
	
	/**
	 * Mark that a method should not be used.
	 * Returns a modified function which warns once by default.
	 *
	 * If `localStorage.noDeprecation = true` is set, then it is a no-op.
	 *
	 * If `localStorage.throwDeprecation = true` is set, then deprecated functions
	 * will throw an Error when invoked.
	 *
	 * If `localStorage.traceDeprecation = true` is set, then deprecated functions
	 * will invoke `console.trace()` instead of `console.error()`.
	 *
	 * @param {Function} fn - the function to deprecate
	 * @param {String} msg - the string to print to the console when `fn` is invoked
	 * @returns {Function} a new "deprecated" version of `fn`
	 * @api public
	 */
	
	function deprecate (fn, msg) {
	  if (config('noDeprecation')) {
	    return fn;
	  }
	
	  var warned = false;
	  function deprecated() {
	    if (!warned) {
	      if (config('throwDeprecation')) {
	        throw new Error(msg);
	      } else if (config('traceDeprecation')) {
	        console.trace(msg);
	      } else {
	        console.warn(msg);
	      }
	      warned = true;
	    }
	    return fn.apply(this, arguments);
	  }
	
	  return deprecated;
	}
	
	/**
	 * Checks `localStorage` for boolean values for the given `name`.
	 *
	 * @param {String} name
	 * @returns {Boolean}
	 * @api private
	 */
	
	function config (name) {
	  // accessing global.localStorage can trigger a DOMException in sandboxed iframes
	  try {
	    if (!global.localStorage) return false;
	  } catch (_) {
	    return false;
	  }
	  var val = global.localStorage[name];
	  if (null == val) return false;
	  return String(val).toLowerCase() === 'true';
	}
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
})
/** END DEFINE BLOCK for util-deprecate@1.0.2/browser.js **/


/** START DEFINE BLOCK for string_decoder@1.0.3/lib/string_decoder.js **/
jupyter.define('string_decoder@1.0.3/lib/string_decoder.js', function (module, exports, __jupyter_require__) {
	'use strict';
	
	var Buffer = __jupyter_require__('safe-buffer@~5.1.0/index.js').Buffer;
	
	var isEncoding = Buffer.isEncoding || function (encoding) {
	  encoding = '' + encoding;
	  switch (encoding && encoding.toLowerCase()) {
	    case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
	      return true;
	    default:
	      return false;
	  }
	};
	
	function _normalizeEncoding(enc) {
	  if (!enc) return 'utf8';
	  var retried;
	  while (true) {
	    switch (enc) {
	      case 'utf8':
	      case 'utf-8':
	        return 'utf8';
	      case 'ucs2':
	      case 'ucs-2':
	      case 'utf16le':
	      case 'utf-16le':
	        return 'utf16le';
	      case 'latin1':
	      case 'binary':
	        return 'latin1';
	      case 'base64':
	      case 'ascii':
	      case 'hex':
	        return enc;
	      default:
	        if (retried) return; // undefined
	        enc = ('' + enc).toLowerCase();
	        retried = true;
	    }
	  }
	};
	
	// Do not cache `Buffer.isEncoding` when checking encoding names as some
	// modules monkey-patch it to support additional encodings
	function normalizeEncoding(enc) {
	  var nenc = _normalizeEncoding(enc);
	  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
	  return nenc || enc;
	}
	
	// StringDecoder provides an interface for efficiently splitting a series of
	// buffers into a series of JS strings without breaking apart multi-byte
	// characters.
	exports.StringDecoder = StringDecoder;
	function StringDecoder(encoding) {
	  this.encoding = normalizeEncoding(encoding);
	  var nb;
	  switch (this.encoding) {
	    case 'utf16le':
	      this.text = utf16Text;
	      this.end = utf16End;
	      nb = 4;
	      break;
	    case 'utf8':
	      this.fillLast = utf8FillLast;
	      nb = 4;
	      break;
	    case 'base64':
	      this.text = base64Text;
	      this.end = base64End;
	      nb = 3;
	      break;
	    default:
	      this.write = simpleWrite;
	      this.end = simpleEnd;
	      return;
	  }
	  this.lastNeed = 0;
	  this.lastTotal = 0;
	  this.lastChar = Buffer.allocUnsafe(nb);
	}
	
	StringDecoder.prototype.write = function (buf) {
	  if (buf.length === 0) return '';
	  var r;
	  var i;
	  if (this.lastNeed) {
	    r = this.fillLast(buf);
	    if (r === undefined) return '';
	    i = this.lastNeed;
	    this.lastNeed = 0;
	  } else {
	    i = 0;
	  }
	  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
	  return r || '';
	};
	
	StringDecoder.prototype.end = utf8End;
	
	// Returns only complete characters in a Buffer
	StringDecoder.prototype.text = utf8Text;
	
	// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
	StringDecoder.prototype.fillLast = function (buf) {
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
	  this.lastNeed -= buf.length;
	};
	
	// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
	// continuation byte.
	function utf8CheckByte(byte) {
	  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
	  return -1;
	}
	
	// Checks at most 3 bytes at the end of a Buffer in order to detect an
	// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
	// needed to complete the UTF-8 character (if applicable) are returned.
	function utf8CheckIncomplete(self, buf, i) {
	  var j = buf.length - 1;
	  if (j < i) return 0;
	  var nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 1;
	    return nb;
	  }
	  if (--j < i) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) self.lastNeed = nb - 2;
	    return nb;
	  }
	  if (--j < i) return 0;
	  nb = utf8CheckByte(buf[j]);
	  if (nb >= 0) {
	    if (nb > 0) {
	      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
	    }
	    return nb;
	  }
	  return 0;
	}
	
	// Validates as many continuation bytes for a multi-byte UTF-8 character as
	// needed or are available. If we see a non-continuation byte where we expect
	// one, we "replace" the validated continuation bytes we've seen so far with
	// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding
	// behavior. The continuation byte check is included three times in the case
	// where all of the continuation bytes for a character exist in the same buffer.
	// It is also done this way as a slight performance increase instead of using a
	// loop.
	function utf8CheckExtraBytes(self, buf, p) {
	  if ((buf[0] & 0xC0) !== 0x80) {
	    self.lastNeed = 0;
	    return '\ufffd'.repeat(p);
	  }
	  if (self.lastNeed > 1 && buf.length > 1) {
	    if ((buf[1] & 0xC0) !== 0x80) {
	      self.lastNeed = 1;
	      return '\ufffd'.repeat(p + 1);
	    }
	    if (self.lastNeed > 2 && buf.length > 2) {
	      if ((buf[2] & 0xC0) !== 0x80) {
	        self.lastNeed = 2;
	        return '\ufffd'.repeat(p + 2);
	      }
	    }
	  }
	}
	
	// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
	function utf8FillLast(buf) {
	  var p = this.lastTotal - this.lastNeed;
	  var r = utf8CheckExtraBytes(this, buf, p);
	  if (r !== undefined) return r;
	  if (this.lastNeed <= buf.length) {
	    buf.copy(this.lastChar, p, 0, this.lastNeed);
	    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
	  }
	  buf.copy(this.lastChar, p, 0, buf.length);
	  this.lastNeed -= buf.length;
	}
	
	// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
	// partial character, the character's bytes are buffered until the required
	// number of bytes are available.
	function utf8Text(buf, i) {
	  var total = utf8CheckIncomplete(this, buf, i);
	  if (!this.lastNeed) return buf.toString('utf8', i);
	  this.lastTotal = total;
	  var end = buf.length - (total - this.lastNeed);
	  buf.copy(this.lastChar, 0, end);
	  return buf.toString('utf8', i, end);
	}
	
	// For UTF-8, a replacement character for each buffered byte of a (partial)
	// character needs to be added to the output.
	function utf8End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed);
	  return r;
	}
	
	// UTF-16LE typically needs two bytes per character, but even if we have an even
	// number of bytes available, we need to check if we end on a leading/high
	// surrogate. In that case, we need to wait for the next two bytes in order to
	// decode the last character properly.
	function utf16Text(buf, i) {
	  if ((buf.length - i) % 2 === 0) {
	    var r = buf.toString('utf16le', i);
	    if (r) {
	      var c = r.charCodeAt(r.length - 1);
	      if (c >= 0xD800 && c <= 0xDBFF) {
	        this.lastNeed = 2;
	        this.lastTotal = 4;
	        this.lastChar[0] = buf[buf.length - 2];
	        this.lastChar[1] = buf[buf.length - 1];
	        return r.slice(0, -1);
	      }
	    }
	    return r;
	  }
	  this.lastNeed = 1;
	  this.lastTotal = 2;
	  this.lastChar[0] = buf[buf.length - 1];
	  return buf.toString('utf16le', i, buf.length - 1);
	}
	
	// For UTF-16LE we do not explicitly append special replacement characters if we
	// end on a partial character, we simply let v8 handle that.
	function utf16End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) {
	    var end = this.lastTotal - this.lastNeed;
	    return r + this.lastChar.toString('utf16le', 0, end);
	  }
	  return r;
	}
	
	function base64Text(buf, i) {
	  var n = (buf.length - i) % 3;
	  if (n === 0) return buf.toString('base64', i);
	  this.lastNeed = 3 - n;
	  this.lastTotal = 3;
	  if (n === 1) {
	    this.lastChar[0] = buf[buf.length - 1];
	  } else {
	    this.lastChar[0] = buf[buf.length - 2];
	    this.lastChar[1] = buf[buf.length - 1];
	  }
	  return buf.toString('base64', i, buf.length - n);
	}
	
	function base64End(buf) {
	  var r = buf && buf.length ? this.write(buf) : '';
	  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
	  return r;
	}
	
	// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
	function simpleWrite(buf) {
	  return buf.toString(this.encoding);
	}
	
	function simpleEnd(buf) {
	  return buf && buf.length ? this.write(buf) : '';
	}
})
/** END DEFINE BLOCK for string_decoder@1.0.3/lib/string_decoder.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_transform.js **/
jupyter.define('readable-stream@2.3.2/lib/_stream_transform.js', function (module, exports, __jupyter_require__) {
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// a transform stream is a readable/writable stream where you do
	// something with the data.  Sometimes it's called a "filter",
	// but that's not a great name for it, since that implies a thing where
	// some bits pass through, and others are simply ignored.  (That would
	// be a valid example of a transform, of course.)
	//
	// While the output is causally related to the input, it's not a
	// necessarily symmetric or synchronous transformation.  For example,
	// a zlib stream might take multiple plain-text writes(), and then
	// emit a single compressed chunk some time in the future.
	//
	// Here's how this works:
	//
	// The Transform stream has all the aspects of the readable and writable
	// stream classes.  When you write(chunk), that calls _write(chunk,cb)
	// internally, and returns false if there's a lot of pending writes
	// buffered up.  When you call read(), that calls _read(n) until
	// there's enough pending readable data buffered up.
	//
	// In a transform stream, the written data is placed in a buffer.  When
	// _read(n) is called, it transforms the queued up data, calling the
	// buffered _write cb's as it consumes chunks.  If consuming a single
	// written chunk would result in multiple output chunks, then the first
	// outputted bit calls the readcb, and subsequent chunks just go into
	// the read buffer, and will cause it to emit 'readable' if necessary.
	//
	// This way, back-pressure is actually determined by the reading side,
	// since _read has to be called to start processing a new chunk.  However,
	// a pathological inflate type of transform can cause excessive buffering
	// here.  For example, imagine a stream where every byte of input is
	// interpreted as an integer from 0-255, and then results in that many
	// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
	// 1kb of data being output.  In this case, you could write a very small
	// amount of input, and end up with a very large amount of output.  In
	// such a pathological inflating mechanism, there'd be no way to tell
	// the system to stop doing the transform.  A single 4MB write could
	// cause the system to run out of memory.
	//
	// However, even in such a pathological case, only a single written chunk
	// would be consumed, and then the rest would wait (un-transformed) until
	// the results of the previous transformed chunk were consumed.
	
	'use strict';
	
	module.exports = Transform;
	
	var Duplex = __jupyter_require__('readable-stream@2.3.2/lib/_stream_duplex.js');
	
	/*<replacement>*/
	var util = __jupyter_require__('core-util-is@~1.0.0/lib/util.js');
	util.inherits = __jupyter_require__('inherits@~2.0.3/inherits_browser.js');
	/*</replacement>*/
	
	util.inherits(Transform, Duplex);
	
	function TransformState(stream) {
	  this.afterTransform = function (er, data) {
	    return afterTransform(stream, er, data);
	  };
	
	  this.needTransform = false;
	  this.transforming = false;
	  this.writecb = null;
	  this.writechunk = null;
	  this.writeencoding = null;
	}
	
	function afterTransform(stream, er, data) {
	  var ts = stream._transformState;
	  ts.transforming = false;
	
	  var cb = ts.writecb;
	
	  if (!cb) {
	    return stream.emit('error', new Error('write callback called multiple times'));
	  }
	
	  ts.writechunk = null;
	  ts.writecb = null;
	
	  if (data !== null && data !== undefined) stream.push(data);
	
	  cb(er);
	
	  var rs = stream._readableState;
	  rs.reading = false;
	  if (rs.needReadable || rs.length < rs.highWaterMark) {
	    stream._read(rs.highWaterMark);
	  }
	}
	
	function Transform(options) {
	  if (!(this instanceof Transform)) return new Transform(options);
	
	  Duplex.call(this, options);
	
	  this._transformState = new TransformState(this);
	
	  var stream = this;
	
	  // start out asking for a readable event once data is transformed.
	  this._readableState.needReadable = true;
	
	  // we have implemented the _read method, and done the other things
	  // that Readable wants before the first _read call, so unset the
	  // sync guard flag.
	  this._readableState.sync = false;
	
	  if (options) {
	    if (typeof options.transform === 'function') this._transform = options.transform;
	
	    if (typeof options.flush === 'function') this._flush = options.flush;
	  }
	
	  // When the writable side finishes, then flush out anything remaining.
	  this.once('prefinish', function () {
	    if (typeof this._flush === 'function') this._flush(function (er, data) {
	      done(stream, er, data);
	    });else done(stream);
	  });
	}
	
	Transform.prototype.push = function (chunk, encoding) {
	  this._transformState.needTransform = false;
	  return Duplex.prototype.push.call(this, chunk, encoding);
	};
	
	// This is the part where you do stuff!
	// override this function in implementation classes.
	// 'chunk' is an input chunk.
	//
	// Call `push(newChunk)` to pass along transformed output
	// to the readable side.  You may call 'push' zero or more times.
	//
	// Call `cb(err)` when you are done with this chunk.  If you pass
	// an error, then that'll put the hurt on the whole operation.  If you
	// never call cb(), then you'll never get another chunk.
	Transform.prototype._transform = function (chunk, encoding, cb) {
	  throw new Error('_transform() is not implemented');
	};
	
	Transform.prototype._write = function (chunk, encoding, cb) {
	  var ts = this._transformState;
	  ts.writecb = cb;
	  ts.writechunk = chunk;
	  ts.writeencoding = encoding;
	  if (!ts.transforming) {
	    var rs = this._readableState;
	    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
	  }
	};
	
	// Doesn't matter what the args are here.
	// _transform does all the work.
	// That we got here means that the readable side wants more data.
	Transform.prototype._read = function (n) {
	  var ts = this._transformState;
	
	  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
	    ts.transforming = true;
	    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
	  } else {
	    // mark that we need a transform, so that any data that comes in
	    // will get processed, now that we've asked for it.
	    ts.needTransform = true;
	  }
	};
	
	Transform.prototype._destroy = function (err, cb) {
	  var _this = this;
	
	  Duplex.prototype._destroy.call(this, err, function (err2) {
	    cb(err2);
	    _this.emit('close');
	  });
	};
	
	function done(stream, er, data) {
	  if (er) return stream.emit('error', er);
	
	  if (data !== null && data !== undefined) stream.push(data);
	
	  // if there's nothing in the write buffer, then that means
	  // that nothing more will ever be provided
	  var ws = stream._writableState;
	  var ts = stream._transformState;
	
	  if (ws.length) throw new Error('Calling transform done when ws.length != 0');
	
	  if (ts.transforming) throw new Error('Calling transform done when still transforming');
	
	  return stream.push(null);
	}
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_transform.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_passthrough.js **/
jupyter.define('readable-stream@2.3.2/lib/_stream_passthrough.js', function (module, exports, __jupyter_require__) {
	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// a passthrough stream.
	// basically just the most minimal sort of Transform stream.
	// Every written chunk gets output as-is.
	
	'use strict';
	
	module.exports = PassThrough;
	
	var Transform = __jupyter_require__('readable-stream@2.3.2/lib/_stream_transform.js');
	
	/*<replacement>*/
	var util = __jupyter_require__('core-util-is@~1.0.0/lib/util.js');
	util.inherits = __jupyter_require__('inherits@~2.0.3/inherits_browser.js');
	/*</replacement>*/
	
	util.inherits(PassThrough, Transform);
	
	function PassThrough(options) {
	  if (!(this instanceof PassThrough)) return new PassThrough(options);
	
	  Transform.call(this, options);
	}
	
	PassThrough.prototype._transform = function (chunk, encoding, cb) {
	  cb(null, chunk);
	};
})
/** END DEFINE BLOCK for readable-stream@2.3.2/lib/_stream_passthrough.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/writable-browser.js **/
jupyter.define('readable-stream@2.3.2/writable-browser.js', function (module, exports, __jupyter_require__) {
	module.exports = __jupyter_require__('readable-stream@2.3.2/lib/_stream_writable.js');
	
})
/** END DEFINE BLOCK for readable-stream@2.3.2/writable-browser.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/duplex-browser.js **/
jupyter.define('readable-stream@2.3.2/duplex-browser.js', function (module, exports, __jupyter_require__) {
	module.exports = __jupyter_require__('readable-stream@2.3.2/lib/_stream_duplex.js');
	
})
/** END DEFINE BLOCK for readable-stream@2.3.2/duplex-browser.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/transform.js **/
jupyter.define('readable-stream@2.3.2/transform.js', function (module, exports, __jupyter_require__) {
	module.exports = __jupyter_require__('readable-stream@2.3.2/readable-browser.js').Transform
	
})
/** END DEFINE BLOCK for readable-stream@2.3.2/transform.js **/


/** START DEFINE BLOCK for readable-stream@2.3.2/passthrough.js **/
jupyter.define('readable-stream@2.3.2/passthrough.js', function (module, exports, __jupyter_require__) {
	module.exports = __jupyter_require__('readable-stream@2.3.2/readable-browser.js').PassThrough
	
})
/** END DEFINE BLOCK for readable-stream@2.3.2/passthrough.js **/


/** START DEFINE BLOCK for __ignored__ **/
jupyter.define('__ignored__', function (module, exports, __jupyter_require__) {
	/* (ignored) */
})
/** END DEFINE BLOCK for __ignored__ **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/ProxyHandler.js **/
jupyter.define('htmlparser2@3.9.2/lib/ProxyHandler.js', function (module, exports, __jupyter_require__) {
	module.exports = ProxyHandler;
	
	function ProxyHandler(cbs){
		this._cbs = cbs || {};
	}
	
	var EVENTS = __jupyter_require__('htmlparser2@3.9.2/lib/index.js').EVENTS;
	Object.keys(EVENTS).forEach(function(name){
		if(EVENTS[name] === 0){
			name = "on" + name;
			ProxyHandler.prototype[name] = function(){
				if(this._cbs[name]) this._cbs[name]();
			};
		} else if(EVENTS[name] === 1){
			name = "on" + name;
			ProxyHandler.prototype[name] = function(a){
				if(this._cbs[name]) this._cbs[name](a);
			};
		} else if(EVENTS[name] === 2){
			name = "on" + name;
			ProxyHandler.prototype[name] = function(a, b){
				if(this._cbs[name]) this._cbs[name](a, b);
			};
		} else {
			throw Error("wrong number of arguments");
		}
	});
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/ProxyHandler.js **/


/** START DEFINE BLOCK for domutils@1.6.2/index.js **/
jupyter.define('domutils@1.6.2/index.js', function (module, exports, __jupyter_require__) {
	var DomUtils = module.exports;
	
	[
		__jupyter_require__('domutils@1.6.2/lib/stringify.js'),
		__jupyter_require__('domutils@1.6.2/lib/traversal.js'),
		__jupyter_require__('domutils@1.6.2/lib/manipulation.js'),
		__jupyter_require__('domutils@1.6.2/lib/querying.js'),
		__jupyter_require__('domutils@1.6.2/lib/legacy.js'),
		__jupyter_require__('domutils@1.6.2/lib/helpers.js')
	].forEach(function(ext){
		Object.keys(ext).forEach(function(key){
			DomUtils[key] = ext[key].bind(DomUtils);
		});
	});
	
})
/** END DEFINE BLOCK for domutils@1.6.2/index.js **/


/** START DEFINE BLOCK for domutils@1.6.2/lib/stringify.js **/
jupyter.define('domutils@1.6.2/lib/stringify.js', function (module, exports, __jupyter_require__) {
	var ElementType = __jupyter_require__('domelementtype@1/index.js'),
	    getOuterHTML = __jupyter_require__('dom-serializer@0/index.js'),
	    isTag = ElementType.isTag;
	
	module.exports = {
		getInnerHTML: getInnerHTML,
		getOuterHTML: getOuterHTML,
		getText: getText
	};
	
	function getInnerHTML(elem, opts){
		return elem.children ? elem.children.map(function(elem){
			return getOuterHTML(elem, opts);
		}).join("") : "";
	}
	
	function getText(elem){
		if(Array.isArray(elem)) return elem.map(getText).join("");
		if(isTag(elem)) return elem.name === "br" ? "\n" : getText(elem.children);
		if(elem.type === ElementType.CDATA) return getText(elem.children);
		if(elem.type === ElementType.Text) return elem.data;
		return "";
	}
	
})
/** END DEFINE BLOCK for domutils@1.6.2/lib/stringify.js **/


/** START DEFINE BLOCK for dom-serializer@0.1.0/index.js **/
jupyter.define('dom-serializer@0.1.0/index.js', function (module, exports, __jupyter_require__) {
	/*
	  Module dependencies
	*/
	var ElementType = __jupyter_require__('domelementtype@~1.1.1/index.js');
	var entities = __jupyter_require__('entities@~1.1.1/index.js');
	
	/*
	  Boolean Attributes
	*/
	var booleanAttributes = {
	  __proto__: null,
	  allowfullscreen: true,
	  async: true,
	  autofocus: true,
	  autoplay: true,
	  checked: true,
	  controls: true,
	  default: true,
	  defer: true,
	  disabled: true,
	  hidden: true,
	  ismap: true,
	  loop: true,
	  multiple: true,
	  muted: true,
	  open: true,
	  readonly: true,
	  required: true,
	  reversed: true,
	  scoped: true,
	  seamless: true,
	  selected: true,
	  typemustmatch: true
	};
	
	var unencodedElements = {
	  __proto__: null,
	  style: true,
	  script: true,
	  xmp: true,
	  iframe: true,
	  noembed: true,
	  noframes: true,
	  plaintext: true,
	  noscript: true
	};
	
	/*
	  Format attributes
	*/
	function formatAttrs(attributes, opts) {
	  if (!attributes) return;
	
	  var output = '',
	      value;
	
	  // Loop through the attributes
	  for (var key in attributes) {
	    value = attributes[key];
	    if (output) {
	      output += ' ';
	    }
	
	    if (!value && booleanAttributes[key]) {
	      output += key;
	    } else {
	      output += key + '="' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '"';
	    }
	  }
	
	  return output;
	}
	
	/*
	  Self-enclosing tags (stolen from node-htmlparser)
	*/
	var singleTag = {
	  __proto__: null,
	  area: true,
	  base: true,
	  basefont: true,
	  br: true,
	  col: true,
	  command: true,
	  embed: true,
	  frame: true,
	  hr: true,
	  img: true,
	  input: true,
	  isindex: true,
	  keygen: true,
	  link: true,
	  meta: true,
	  param: true,
	  source: true,
	  track: true,
	  wbr: true,
	};
	
	
	var render = module.exports = function(dom, opts) {
	  if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];
	  opts = opts || {};
	
	  var output = '';
	
	  for(var i = 0; i < dom.length; i++){
	    var elem = dom[i];
	
	    if (elem.type === 'root')
	      output += render(elem.children, opts);
	    else if (ElementType.isTag(elem))
	      output += renderTag(elem, opts);
	    else if (elem.type === ElementType.Directive)
	      output += renderDirective(elem);
	    else if (elem.type === ElementType.Comment)
	      output += renderComment(elem);
	    else if (elem.type === ElementType.CDATA)
	      output += renderCdata(elem);
	    else
	      output += renderText(elem, opts);
	  }
	
	  return output;
	};
	
	function renderTag(elem, opts) {
	  // Handle SVG
	  if (elem.name === "svg") opts = {decodeEntities: opts.decodeEntities, xmlMode: true};
	
	  var tag = '<' + elem.name,
	      attribs = formatAttrs(elem.attribs, opts);
	
	  if (attribs) {
	    tag += ' ' + attribs;
	  }
	
	  if (
	    opts.xmlMode
	    && (!elem.children || elem.children.length === 0)
	  ) {
	    tag += '/>';
	  } else {
	    tag += '>';
	    if (elem.children) {
	      tag += render(elem.children, opts);
	    }
	
	    if (!singleTag[elem.name] || opts.xmlMode) {
	      tag += '</' + elem.name + '>';
	    }
	  }
	
	  return tag;
	}
	
	function renderDirective(elem) {
	  return '<' + elem.data + '>';
	}
	
	function renderText(elem, opts) {
	  var data = elem.data || '';
	
	  // if entities weren't decoded, no need to encode them back
	  if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) {
	    data = entities.encodeXML(data);
	  }
	
	  return data;
	}
	
	function renderCdata(elem) {
	  return '<![CDATA[' + elem.children[0].data + ']]>';
	}
	
	function renderComment(elem) {
	  return '<!--' + elem.data + '-->';
	}
	
})
/** END DEFINE BLOCK for dom-serializer@0.1.0/index.js **/


/** START DEFINE BLOCK for domelementtype@1.1.3/index.js **/
jupyter.define('domelementtype@1.1.3/index.js', function (module, exports, __jupyter_require__) {
	//Types of elements found in the DOM
	module.exports = {
		Text: "text", //Text
		Directive: "directive", //<? ... ?>
		Comment: "comment", //<!-- ... -->
		Script: "script", //<script> tags
		Style: "style", //<style> tags
		Tag: "tag", //Any tag
		CDATA: "cdata", //<![CDATA[ ... ]]>
	
		isTag: function(elem){
			return elem.type === "tag" || elem.type === "script" || elem.type === "style";
		}
	};
})
/** END DEFINE BLOCK for domelementtype@1.1.3/index.js **/


/** START DEFINE BLOCK for entities@1.1.1/index.js **/
jupyter.define('entities@1.1.1/index.js', function (module, exports, __jupyter_require__) {
	var encode = __jupyter_require__('entities@1.1.1/lib/encode.js'),
	    decode = __jupyter_require__('entities@1.1.1/lib/decode.js');
	
	exports.decode = function(data, level){
		return (!level || level <= 0 ? decode.XML : decode.HTML)(data);
	};
	
	exports.decodeStrict = function(data, level){
		return (!level || level <= 0 ? decode.XML : decode.HTMLStrict)(data);
	};
	
	exports.encode = function(data, level){
		return (!level || level <= 0 ? encode.XML : encode.HTML)(data);
	};
	
	exports.encodeXML = encode.XML;
	
	exports.encodeHTML4 =
	exports.encodeHTML5 =
	exports.encodeHTML  = encode.HTML;
	
	exports.decodeXML =
	exports.decodeXMLStrict = decode.XML;
	
	exports.decodeHTML4 =
	exports.decodeHTML5 =
	exports.decodeHTML = decode.HTML;
	
	exports.decodeHTML4Strict =
	exports.decodeHTML5Strict =
	exports.decodeHTMLStrict = decode.HTMLStrict;
	
	exports.escape = encode.escape;
	
})
/** END DEFINE BLOCK for entities@1.1.1/index.js **/


/** START DEFINE BLOCK for entities@1.1.1/lib/encode.js **/
jupyter.define('entities@1.1.1/lib/encode.js', function (module, exports, __jupyter_require__) {
	var inverseXML = getInverseObj(__jupyter_require__('entities@1.1.1/maps/xml.json')),
	    xmlReplacer = getInverseReplacer(inverseXML);
	
	exports.XML = getInverse(inverseXML, xmlReplacer);
	
	var inverseHTML = getInverseObj(__jupyter_require__('entities@1.1.1/maps/entities.json')),
	    htmlReplacer = getInverseReplacer(inverseHTML);
	
	exports.HTML = getInverse(inverseHTML, htmlReplacer);
	
	function getInverseObj(obj){
		return Object.keys(obj).sort().reduce(function(inverse, name){
			inverse[obj[name]] = "&" + name + ";";
			return inverse;
		}, {});
	}
	
	function getInverseReplacer(inverse){
		var single = [],
		    multiple = [];
	
		Object.keys(inverse).forEach(function(k){
			if(k.length === 1){
				single.push("\\" + k);
			} else {
				multiple.push(k);
			}
		});
	
		//TODO add ranges
		multiple.unshift("[" + single.join("") + "]");
	
		return new RegExp(multiple.join("|"), "g");
	}
	
	var re_nonASCII = /[^\0-\x7F]/g,
	    re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
	
	function singleCharReplacer(c){
		return "&#x" + c.charCodeAt(0).toString(16).toUpperCase() + ";";
	}
	
	function astralReplacer(c){
		// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
		var high = c.charCodeAt(0);
		var low  = c.charCodeAt(1);
		var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
		return "&#x" + codePoint.toString(16).toUpperCase() + ";";
	}
	
	function getInverse(inverse, re){
		function func(name){
			return inverse[name];
		}
	
		return function(data){
			return data
					.replace(re, func)
					.replace(re_astralSymbols, astralReplacer)
					.replace(re_nonASCII, singleCharReplacer);
		};
	}
	
	var re_xmlChars = getInverseReplacer(inverseXML);
	
	function escapeXML(data){
		return data
				.replace(re_xmlChars, singleCharReplacer)
				.replace(re_astralSymbols, astralReplacer)
				.replace(re_nonASCII, singleCharReplacer);
	}
	
	exports.escape = escapeXML;
	
})
/** END DEFINE BLOCK for entities@1.1.1/lib/encode.js **/


/** START DEFINE BLOCK for entities@1.1.1/lib/decode.js **/
jupyter.define('entities@1.1.1/lib/decode.js', function (module, exports, __jupyter_require__) {
	var entityMap = __jupyter_require__('entities@1.1.1/maps/entities.json'),
	    legacyMap = __jupyter_require__('entities@1.1.1/maps/legacy.json'),
	    xmlMap    = __jupyter_require__('entities@1.1.1/maps/xml.json'),
	    decodeCodePoint = __jupyter_require__('entities@1.1.1/lib/decode_codepoint.js');
	
	var decodeXMLStrict  = getStrictDecoder(xmlMap),
	    decodeHTMLStrict = getStrictDecoder(entityMap);
	
	function getStrictDecoder(map){
		var keys = Object.keys(map).join("|"),
		    replace = getReplacer(map);
	
		keys += "|#[xX][\\da-fA-F]+|#\\d+";
	
		var re = new RegExp("&(?:" + keys + ");", "g");
	
		return function(str){
			return String(str).replace(re, replace);
		};
	}
	
	var decodeHTML = (function(){
		var legacy = Object.keys(legacyMap)
			.sort(sorter);
	
		var keys = Object.keys(entityMap)
			.sort(sorter);
	
		for(var i = 0, j = 0; i < keys.length; i++){
			if(legacy[j] === keys[i]){
				keys[i] += ";?";
				j++;
			} else {
				keys[i] += ";";
			}
		}
	
		var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"),
		    replace = getReplacer(entityMap);
	
		function replacer(str){
			if(str.substr(-1) !== ";") str += ";";
			return replace(str);
		}
	
		//TODO consider creating a merged map
		return function(str){
			return String(str).replace(re, replacer);
		};
	}());
	
	function sorter(a, b){
		return a < b ? 1 : -1;
	}
	
	function getReplacer(map){
		return function replace(str){
			if(str.charAt(1) === "#"){
				if(str.charAt(2) === "X" || str.charAt(2) === "x"){
					return decodeCodePoint(parseInt(str.substr(3), 16));
				}
				return decodeCodePoint(parseInt(str.substr(2), 10));
			}
			return map[str.slice(1, -1)];
		};
	}
	
	module.exports = {
		XML: decodeXMLStrict,
		HTML: decodeHTML,
		HTMLStrict: decodeHTMLStrict
	};
})
/** END DEFINE BLOCK for entities@1.1.1/lib/decode.js **/


/** START DEFINE BLOCK for domutils@1.6.2/lib/traversal.js **/
jupyter.define('domutils@1.6.2/lib/traversal.js', function (module, exports, __jupyter_require__) {
	var getChildren = exports.getChildren = function(elem){
		return elem.children;
	};
	
	var getParent = exports.getParent = function(elem){
		return elem.parent;
	};
	
	exports.getSiblings = function(elem){
		var parent = getParent(elem);
		return parent ? getChildren(parent) : [elem];
	};
	
	exports.getAttributeValue = function(elem, name){
		return elem.attribs && elem.attribs[name];
	};
	
	exports.hasAttrib = function(elem, name){
		return !!elem.attribs && hasOwnProperty.call(elem.attribs, name);
	};
	
	exports.getName = function(elem){
		return elem.name;
	};
	
})
/** END DEFINE BLOCK for domutils@1.6.2/lib/traversal.js **/


/** START DEFINE BLOCK for domutils@1.6.2/lib/manipulation.js **/
jupyter.define('domutils@1.6.2/lib/manipulation.js', function (module, exports, __jupyter_require__) {
	exports.removeElement = function(elem){
		if(elem.prev) elem.prev.next = elem.next;
		if(elem.next) elem.next.prev = elem.prev;
	
		if(elem.parent){
			var childs = elem.parent.children;
			childs.splice(childs.lastIndexOf(elem), 1);
		}
	};
	
	exports.replaceElement = function(elem, replacement){
		var prev = replacement.prev = elem.prev;
		if(prev){
			prev.next = replacement;
		}
	
		var next = replacement.next = elem.next;
		if(next){
			next.prev = replacement;
		}
	
		var parent = replacement.parent = elem.parent;
		if(parent){
			var childs = parent.children;
			childs[childs.lastIndexOf(elem)] = replacement;
		}
	};
	
	exports.appendChild = function(elem, child){
		child.parent = elem;
	
		if(elem.children.push(child) !== 1){
			var sibling = elem.children[elem.children.length - 2];
			sibling.next = child;
			child.prev = sibling;
			child.next = null;
		}
	};
	
	exports.append = function(elem, next){
		var parent = elem.parent,
			currNext = elem.next;
	
		next.next = currNext;
		next.prev = elem;
		elem.next = next;
		next.parent = parent;
	
		if(currNext){
			currNext.prev = next;
			if(parent){
				var childs = parent.children;
				childs.splice(childs.lastIndexOf(currNext), 0, next);
			}
		} else if(parent){
			parent.children.push(next);
		}
	};
	
	exports.prepend = function(elem, prev){
		var parent = elem.parent;
		if(parent){
			var childs = parent.children;
			childs.splice(childs.lastIndexOf(elem), 0, prev);
		}
	
		if(elem.prev){
			elem.prev.next = prev;
		}
		
		prev.parent = parent;
		prev.prev = elem.prev;
		prev.next = elem;
		elem.prev = prev;
	};
	
	
	
})
/** END DEFINE BLOCK for domutils@1.6.2/lib/manipulation.js **/


/** START DEFINE BLOCK for domutils@1.6.2/lib/querying.js **/
jupyter.define('domutils@1.6.2/lib/querying.js', function (module, exports, __jupyter_require__) {
	var isTag = __jupyter_require__('domelementtype@1/index.js').isTag;
	
	module.exports = {
		filter: filter,
		find: find,
		findOneChild: findOneChild,
		findOne: findOne,
		existsOne: existsOne,
		findAll: findAll
	};
	
	function filter(test, element, recurse, limit){
		if(!Array.isArray(element)) element = [element];
	
		if(typeof limit !== "number" || !isFinite(limit)){
			limit = Infinity;
		}
		return find(test, element, recurse !== false, limit);
	}
	
	function find(test, elems, recurse, limit){
		var result = [], childs;
	
		for(var i = 0, j = elems.length; i < j; i++){
			if(test(elems[i])){
				result.push(elems[i]);
				if(--limit <= 0) break;
			}
	
			childs = elems[i].children;
			if(recurse && childs && childs.length > 0){
				childs = find(test, childs, recurse, limit);
				result = result.concat(childs);
				limit -= childs.length;
				if(limit <= 0) break;
			}
		}
	
		return result;
	}
	
	function findOneChild(test, elems){
		for(var i = 0, l = elems.length; i < l; i++){
			if(test(elems[i])) return elems[i];
		}
	
		return null;
	}
	
	function findOne(test, elems){
		var elem = null;
	
		for(var i = 0, l = elems.length; i < l && !elem; i++){
			if(!isTag(elems[i])){
				continue;
			} else if(test(elems[i])){
				elem = elems[i];
			} else if(elems[i].children.length > 0){
				elem = findOne(test, elems[i].children);
			}
		}
	
		return elem;
	}
	
	function existsOne(test, elems){
		for(var i = 0, l = elems.length; i < l; i++){
			if(
				isTag(elems[i]) && (
					test(elems[i]) || (
						elems[i].children.length > 0 &&
						existsOne(test, elems[i].children)
					)
				)
			){
				return true;
			}
		}
	
		return false;
	}
	
	function findAll(test, rootElems){
		var result = [];
		var stack = [rootElems];
		while(stack.length){
			var elems = stack.pop();
			for(var i = 0, j = elems.length; i < j; i++){
				if(!isTag(elems[i])) continue;
				if(test(elems[i])) result.push(elems[i]);
			}
			while(j-- > 0){
				if(elems[j].children && elems[j].children.length > 0){
					stack.push(elems[j].children);
				}
			}
		}
		return result;
	}
	
})
/** END DEFINE BLOCK for domutils@1.6.2/lib/querying.js **/


/** START DEFINE BLOCK for domutils@1.6.2/lib/legacy.js **/
jupyter.define('domutils@1.6.2/lib/legacy.js', function (module, exports, __jupyter_require__) {
	var ElementType = __jupyter_require__('domelementtype@1/index.js');
	var isTag = exports.isTag = ElementType.isTag;
	
	exports.testElement = function(options, element){
		for(var key in options){
			if(!options.hasOwnProperty(key));
			else if(key === "tag_name"){
				if(!isTag(element) || !options.tag_name(element.name)){
					return false;
				}
			} else if(key === "tag_type"){
				if(!options.tag_type(element.type)) return false;
			} else if(key === "tag_contains"){
				if(isTag(element) || !options.tag_contains(element.data)){
					return false;
				}
			} else if(!element.attribs || !options[key](element.attribs[key])){
				return false;
			}
		}
		return true;
	};
	
	var Checks = {
		tag_name: function(name){
			if(typeof name === "function"){
				return function(elem){ return isTag(elem) && name(elem.name); };
			} else if(name === "*"){
				return isTag;
			} else {
				return function(elem){ return isTag(elem) && elem.name === name; };
			}
		},
		tag_type: function(type){
			if(typeof type === "function"){
				return function(elem){ return type(elem.type); };
			} else {
				return function(elem){ return elem.type === type; };
			}
		},
		tag_contains: function(data){
			if(typeof data === "function"){
				return function(elem){ return !isTag(elem) && data(elem.data); };
			} else {
				return function(elem){ return !isTag(elem) && elem.data === data; };
			}
		}
	};
	
	function getAttribCheck(attrib, value){
		if(typeof value === "function"){
			return function(elem){ return elem.attribs && value(elem.attribs[attrib]); };
		} else {
			return function(elem){ return elem.attribs && elem.attribs[attrib] === value; };
		}
	}
	
	function combineFuncs(a, b){
		return function(elem){
			return a(elem) || b(elem);
		};
	}
	
	exports.getElements = function(options, element, recurse, limit){
		var funcs = Object.keys(options).map(function(key){
			var value = options[key];
			return key in Checks ? Checks[key](value) : getAttribCheck(key, value);
		});
	
		return funcs.length === 0 ? [] : this.filter(
			funcs.reduce(combineFuncs),
			element, recurse, limit
		);
	};
	
	exports.getElementById = function(id, element, recurse){
		if(!Array.isArray(element)) element = [element];
		return this.findOne(getAttribCheck("id", id), element, recurse !== false);
	};
	
	exports.getElementsByTagName = function(name, element, recurse, limit){
		return this.filter(Checks.tag_name(name), element, recurse, limit);
	};
	
	exports.getElementsByTagType = function(type, element, recurse, limit){
		return this.filter(Checks.tag_type(type), element, recurse, limit);
	};
	
})
/** END DEFINE BLOCK for domutils@1.6.2/lib/legacy.js **/


/** START DEFINE BLOCK for domutils@1.6.2/lib/helpers.js **/
jupyter.define('domutils@1.6.2/lib/helpers.js', function (module, exports, __jupyter_require__) {
	// removeSubsets
	// Given an array of nodes, remove any member that is contained by another.
	exports.removeSubsets = function(nodes) {
		var idx = nodes.length, node, ancestor, replace;
	
		// Check if each node (or one of its ancestors) is already contained in the
		// array.
		while (--idx > -1) {
			node = ancestor = nodes[idx];
	
			// Temporarily remove the node under consideration
			nodes[idx] = null;
			replace = true;
	
			while (ancestor) {
				if (nodes.indexOf(ancestor) > -1) {
					replace = false;
					nodes.splice(idx, 1);
					break;
				}
				ancestor = ancestor.parent;
			}
	
			// If the node has been found to be unique, re-insert it.
			if (replace) {
				nodes[idx] = node;
			}
		}
	
		return nodes;
	};
	
	// Source: http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
	var POSITION = {
		DISCONNECTED: 1,
		PRECEDING: 2,
		FOLLOWING: 4,
		CONTAINS: 8,
		CONTAINED_BY: 16
	};
	
	// Compare the position of one node against another node in any other document.
	// The return value is a bitmask with the following values:
	//
	// document order:
	// > There is an ordering, document order, defined on all the nodes in the
	// > document corresponding to the order in which the first character of the
	// > XML representation of each node occurs in the XML representation of the
	// > document after expansion of general entities. Thus, the document element
	// > node will be the first node. Element nodes occur before their children.
	// > Thus, document order orders element nodes in order of the occurrence of
	// > their start-tag in the XML (after expansion of entities). The attribute
	// > nodes of an element occur after the element and before its children. The
	// > relative order of attribute nodes is implementation-dependent./
	// Source:
	// http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
	//
	// @argument {Node} nodaA The first node to use in the comparison
	// @argument {Node} nodeB The second node to use in the comparison
	//
	// @return {Number} A bitmask describing the input nodes' relative position.
	//         See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
	//         a description of these values.
	var comparePos = exports.compareDocumentPosition = function(nodeA, nodeB) {
		var aParents = [];
		var bParents = [];
		var current, sharedParent, siblings, aSibling, bSibling, idx;
	
		if (nodeA === nodeB) {
			return 0;
		}
	
		current = nodeA;
		while (current) {
			aParents.unshift(current);
			current = current.parent;
		}
		current = nodeB;
		while (current) {
			bParents.unshift(current);
			current = current.parent;
		}
	
		idx = 0;
		while (aParents[idx] === bParents[idx]) {
			idx++;
		}
	
		if (idx === 0) {
			return POSITION.DISCONNECTED;
		}
	
		sharedParent = aParents[idx - 1];
		siblings = sharedParent.children;
		aSibling = aParents[idx];
		bSibling = bParents[idx];
	
		if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {
			if (sharedParent === nodeB) {
				return POSITION.FOLLOWING | POSITION.CONTAINED_BY;
			}
			return POSITION.FOLLOWING;
		} else {
			if (sharedParent === nodeA) {
				return POSITION.PRECEDING | POSITION.CONTAINS;
			}
			return POSITION.PRECEDING;
		}
	};
	
	// Sort an array of nodes based on their relative position in the document and
	// remove any duplicate nodes. If the array contains nodes that do not belong
	// to the same document, sort order is unspecified.
	//
	// @argument {Array} nodes Array of DOM nodes
	//
	// @returns {Array} collection of unique nodes, sorted in document order
	exports.uniqueSort = function(nodes) {
		var idx = nodes.length, node, position;
	
		nodes = nodes.slice();
	
		while (--idx > -1) {
			node = nodes[idx];
			position = nodes.indexOf(node);
			if (position > -1 && position < idx) {
				nodes.splice(idx, 1);
			}
		}
		nodes.sort(function(a, b) {
			var relative = comparePos(a, b);
			if (relative & POSITION.PRECEDING) {
				return -1;
			} else if (relative & POSITION.FOLLOWING) {
				return 1;
			}
			return 0;
		});
	
		return nodes;
	};
	
})
/** END DEFINE BLOCK for domutils@1.6.2/lib/helpers.js **/


/** START DEFINE BLOCK for htmlparser2@3.9.2/lib/CollectingHandler.js **/
jupyter.define('htmlparser2@3.9.2/lib/CollectingHandler.js', function (module, exports, __jupyter_require__) {
	module.exports = CollectingHandler;
	
	function CollectingHandler(cbs){
		this._cbs = cbs || {};
		this.events = [];
	}
	
	var EVENTS = __jupyter_require__('htmlparser2@3.9.2/lib/index.js').EVENTS;
	Object.keys(EVENTS).forEach(function(name){
		if(EVENTS[name] === 0){
			name = "on" + name;
			CollectingHandler.prototype[name] = function(){
				this.events.push([name]);
				if(this._cbs[name]) this._cbs[name]();
			};
		} else if(EVENTS[name] === 1){
			name = "on" + name;
			CollectingHandler.prototype[name] = function(a){
				this.events.push([name, a]);
				if(this._cbs[name]) this._cbs[name](a);
			};
		} else if(EVENTS[name] === 2){
			name = "on" + name;
			CollectingHandler.prototype[name] = function(a, b){
				this.events.push([name, a, b]);
				if(this._cbs[name]) this._cbs[name](a, b);
			};
		} else {
			throw Error("wrong number of arguments");
		}
	});
	
	CollectingHandler.prototype.onreset = function(){
		this.events = [];
		if(this._cbs.onreset) this._cbs.onreset();
	};
	
	CollectingHandler.prototype.restart = function(){
		if(this._cbs.onreset) this._cbs.onreset();
	
		for(var i = 0, len = this.events.length; i < len; i++){
			if(this._cbs[this.events[i][0]]){
	
				var num = this.events[i].length;
	
				if(num === 1){
					this._cbs[this.events[i][0]]();
				} else if(num === 2){
					this._cbs[this.events[i][0]](this.events[i][1]);
				} else {
					this._cbs[this.events[i][0]](this.events[i][1], this.events[i][2]);
				}
			}
		}
	};
	
})
/** END DEFINE BLOCK for htmlparser2@3.9.2/lib/CollectingHandler.js **/


/** START DEFINE BLOCK for xtend@4.0.1/immutable.js **/
jupyter.define('xtend@4.0.1/immutable.js', function (module, exports, __jupyter_require__) {
	module.exports = extend
	
	var hasOwnProperty = Object.prototype.hasOwnProperty;
	
	function extend() {
	    var target = {}
	
	    for (var i = 0; i < arguments.length; i++) {
	        var source = arguments[i]
	
	        for (var key in source) {
	            if (hasOwnProperty.call(source, key)) {
	                target[key] = source[key]
	            }
	        }
	    }
	
	    return target
	}
	
})
/** END DEFINE BLOCK for xtend@4.0.1/immutable.js **/


/** START DEFINE BLOCK for regexp-quote@0.0.0/regexp-quote.js **/
jupyter.define('regexp-quote@0.0.0/regexp-quote.js', function (module, exports, __jupyter_require__) {
	module.exports = function (string) {
	  return string.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&")
	}
	
})
/** END DEFINE BLOCK for regexp-quote@0.0.0/regexp-quote.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/statedb.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/statedb.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	/* tslint:disable */
	/**
	 * The default state database token.
	 */
	exports.IStateDB = new coreutils_1.Token('jupyter.services.statedb');
	/**
	 * The default concrete implementation of a state database.
	 */
	var StateDB = (function () {
	    /**
	     * Create a new state database.
	     *
	     * @param options - The instantiation options for a state database.
	     */
	    function StateDB(options) {
	        /**
	         * The maximum allowed length of the data after it has been serialized.
	         */
	        this.maxLength = 2000;
	        this.namespace = options.namespace;
	    }
	    /**
	     * Clear the entire database.
	     */
	    StateDB.prototype.clear = function () {
	        var prefix = this.namespace + ":";
	        var i = window.localStorage.length;
	        while (i) {
	            var key = window.localStorage.key(--i);
	            if (key.indexOf(prefix) === 0) {
	                window.localStorage.removeItem(key);
	            }
	        }
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Retrieve a saved bundle from the database.
	     *
	     * @param id - The identifier used to retrieve a data bundle.
	     *
	     * @returns A promise that bears a data payload if available.
	     *
	     * #### Notes
	     * The `id` values of stored items in the state database are formatted:
	     * `'namespace:identifier'`, which is the same convention that command
	     * identifiers in JupyterLab use as well. While this is not a technical
	     * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for
	     * using the `fetchNamespace()` method.
	     *
	     * The promise returned by this method may be rejected if an error occurs in
	     * retrieving the data. Non-existence of an `id` will succeed, however.
	     */
	    StateDB.prototype.fetch = function (id) {
	        var key = this.namespace + ":" + id;
	        try {
	            return Promise.resolve(JSON.parse(window.localStorage.getItem(key)));
	        }
	        catch (error) {
	            return Promise.reject(error);
	        }
	    };
	    /**
	     * Retrieve all the saved bundles for a namespace.
	     *
	     * @param namespace - The namespace to retrieve.
	     *
	     * @returns A promise that bears a collection data payloads for a namespace.
	     *
	     * #### Notes
	     * Namespaces are entirely conventional entities. The `id` values of stored
	     * items in the state database are formatted: `'namespace:identifier'`, which
	     * is the same convention that command identifiers in JupyterLab use as well.
	     *
	     * If there are any errors in retrieving the data, they will be logged to the
	     * console in order to optimistically return any extant data without failing.
	     * This promise will always succeed.
	     */
	    StateDB.prototype.fetchNamespace = function (namespace) {
	        var prefix = this.namespace + ":" + namespace + ":";
	        var regex = new RegExp("^" + this.namespace + ":");
	        var items = [];
	        var i = window.localStorage.length;
	        while (i) {
	            var key = window.localStorage.key(--i);
	            if (key.indexOf(prefix) === 0) {
	                try {
	                    items.push({
	                        id: key.replace(regex, ''),
	                        value: JSON.parse(window.localStorage.getItem(key))
	                    });
	                }
	                catch (error) {
	                    console.warn(error);
	                    window.localStorage.removeItem(key);
	                }
	            }
	        }
	        return Promise.resolve(items);
	    };
	    /**
	     * Remove a value from the database.
	     *
	     * @param id - The identifier for the data being removed.
	     *
	     * @returns A promise that is rejected if remove fails and succeeds otherwise.
	     */
	    StateDB.prototype.remove = function (id) {
	        window.localStorage.removeItem(this.namespace + ":" + id);
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Save a value in the database.
	     *
	     * @param id - The identifier for the data being saved.
	     *
	     * @param value - The data being saved.
	     *
	     * @returns A promise that is rejected if saving fails and succeeds otherwise.
	     *
	     * #### Notes
	     * The `id` values of stored items in the state database are formatted:
	     * `'namespace:identifier'`, which is the same convention that command
	     * identifiers in JupyterLab use as well. While this is not a technical
	     * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for
	     * using the `fetchNamespace()` method.
	     */
	    StateDB.prototype.save = function (id, value) {
	        try {
	            var key = this.namespace + ":" + id;
	            var serialized = JSON.stringify(value);
	            var length_1 = serialized.length;
	            var max = this.maxLength;
	            if (length_1 > max) {
	                throw new Error("Data length (" + length_1 + ") exceeds maximum (" + max + ")");
	            }
	            window.localStorage.setItem(key, serialized);
	            return Promise.resolve(void 0);
	        }
	        catch (error) {
	            return Promise.reject(error);
	        }
	    };
	    return StateDB;
	}());
	exports.StateDB = StateDB;
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/statedb.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/toolbar.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/toolbar.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var properties_1 = __jupyter_require__('@phosphor/properties@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	/**
	 * The class name added to toolbars.
	 */
	var TOOLBAR_CLASS = 'jp-Toolbar';
	/**
	 * The class name added to toolbar items.
	 */
	var TOOLBAR_ITEM_CLASS = 'jp-Toolbar-item';
	/**
	 * The class name added to toolbar buttons.
	 */
	var TOOLBAR_BUTTON_CLASS = 'jp-Toolbar-button';
	/**
	 * The class name added to a pressed button.
	 */
	var TOOLBAR_PRESSED_CLASS = 'jp-mod-pressed';
	/**
	 * The class name added to toolbar interrupt button.
	 */
	var TOOLBAR_INTERRUPT_CLASS = 'jp-StopIcon';
	/**
	 * The class name added to toolbar restart button.
	 */
	var TOOLBAR_RESTART_CLASS = 'jp-RefreshIcon';
	/**
	 * The class name added to toolbar kernel name text.
	 */
	var TOOLBAR_KERNEL_CLASS = 'jp-Kernel-toolbarKernelName';
	/**
	 * The class name added to toolbar kernel indicator icon.
	 */
	var TOOLBAR_INDICATOR_CLASS = 'jp-Kernel-toolbarKernelIndicator';
	/**
	 * The class name added to a busy kernel indicator.
	 */
	var TOOLBAR_BUSY_CLASS = 'jp-mod-busy';
	/**
	 * A class which provides a toolbar widget.
	 */
	var Toolbar = (function (_super) {
	    __extends(Toolbar, _super);
	    /**
	     * Construct a new toolbar widget.
	     */
	    function Toolbar() {
	        var _this = _super.call(this) || this;
	        _this.addClass(TOOLBAR_CLASS);
	        _this.layout = new widgets_1.PanelLayout();
	        return _this;
	    }
	    /**
	     * Get an iterator over the ordered toolbar item names.
	     *
	     * @returns An iterator over the toolbar item names.
	     */
	    Toolbar.prototype.names = function () {
	        var layout = this.layout;
	        return algorithm_1.map(layout.widgets, function (widget) {
	            return Private.nameProperty.get(widget);
	        });
	    };
	    /**
	     * Add an item to the end of the toolbar.
	     *
	     * @param name - The name of the widget to add to the toolbar.
	     *
	     * @param widget - The widget to add to the toolbar.
	     *
	     * @param index - The optional name of the item to insert after.
	     *
	     * @returns Whether the item was added to toolbar.  Returns false if
	     *   an item of the same name is already in the toolbar.
	     */
	    Toolbar.prototype.addItem = function (name, widget) {
	        var layout = this.layout;
	        return this.insertItem(layout.widgets.length, name, widget);
	    };
	    /**
	     * Insert an item into the toolbar at the specified index.
	     *
	     * @param index - The index at which to insert the item.
	     *
	     * @param name - The name of the item.
	     *
	     * @param widget - The widget to add.
	     *
	     * @returns Whether the item was added to the toolbar. Returns false if
	     *   an item of the same name is already in the toolbar.
	     *
	     * #### Notes
	     * The index will be clamped to the bounds of the items.
	     */
	    Toolbar.prototype.insertItem = function (index, name, widget) {
	        var existing = algorithm_1.find(this.names(), function (value) { return value === name; });
	        if (existing) {
	            return false;
	        }
	        widget.addClass(TOOLBAR_ITEM_CLASS);
	        var layout = this.layout;
	        layout.insertWidget(index, widget);
	        Private.nameProperty.set(widget, name);
	        return true;
	    };
	    /**
	     * Remove an item in the toolbar by value.
	     *
	     *  @param name - The name of the widget to remove from the toolbar.
	     */
	    Toolbar.prototype.removeItem = function (widget) {
	        var layout = this.layout;
	        layout.removeWidget(widget);
	    };
	    /**
	     * Handle the DOM events for the widget.
	     *
	     * @param event - The DOM event sent to the widget.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the dock panel's node. It should
	     * not be called directly by user code.
	     */
	    Toolbar.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                if (!this.node.contains(document.activeElement)) {
	                    this.parent.activate();
	                }
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `after-attach` messages for the widget.
	     */
	    Toolbar.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('click', this);
	    };
	    /**
	     * Handle `before-detach` messages for the widget.
	     */
	    Toolbar.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('click', this);
	    };
	    return Toolbar;
	}(widgets_1.Widget));
	exports.Toolbar = Toolbar;
	/**
	 * The namespace for Toolbar class statics.
	 */
	(function (Toolbar) {
	    /**
	     * Create an interrupt toolbar item.
	     */
	    function createInterruptButton(session) {
	        return new ToolbarButton({
	            className: TOOLBAR_INTERRUPT_CLASS,
	            onClick: function () {
	                if (session.kernel) {
	                    session.kernel.interrupt();
	                }
	            },
	            tooltip: 'Interrupt the kernel'
	        });
	    }
	    Toolbar.createInterruptButton = createInterruptButton;
	    /**
	     * Create a restart toolbar item.
	     */
	    function createRestartButton(session) {
	        return new ToolbarButton({
	            className: TOOLBAR_RESTART_CLASS,
	            onClick: function () {
	                session.restart();
	            },
	            tooltip: 'Restart the kernel'
	        });
	    }
	    Toolbar.createRestartButton = createRestartButton;
	    /**
	     * Create a kernel name indicator item.
	     *
	     * #### Notes
	     * It will display the `'display_name`' of the current kernel,
	     * or `'No Kernel!'` if there is no kernel.
	     * It can handle a change in context or kernel.
	     */
	    function createKernelNameItem(session) {
	        return new Private.KernelName(session);
	    }
	    Toolbar.createKernelNameItem = createKernelNameItem;
	    /**
	     * Create a kernel status indicator item.
	     *
	     * #### Notes
	     * It show display a busy status if the kernel status is
	     * not idle.
	     * It will show the current status in the node title.
	     * It can handle a change to the context or the kernel.
	     */
	    function createKernelStatusItem(session) {
	        return new Private.KernelIndicator(session);
	    }
	    Toolbar.createKernelStatusItem = createKernelStatusItem;
	})(Toolbar = exports.Toolbar || (exports.Toolbar = {}));
	exports.Toolbar = Toolbar;
	/**
	 * A widget which acts as a button in a toolbar.
	 */
	var ToolbarButton = (function (_super) {
	    __extends(ToolbarButton, _super);
	    /**
	     * Construct a new toolbar button.
	     */
	    function ToolbarButton(options) {
	        if (options === void 0) { options = {}; }
	        var _this = _super.call(this, { node: document.createElement('span') }) || this;
	        options = options || {};
	        _this.addClass(TOOLBAR_BUTTON_CLASS);
	        _this._onClick = options.onClick;
	        if (options.className) {
	            _this.addClass(options.className);
	        }
	        _this.node.title = options.tooltip || '';
	        return _this;
	    }
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    ToolbarButton.prototype.dispose = function () {
	        this._onClick = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Handle the DOM events for the widget.
	     *
	     * @param event - The DOM event sent to the widget.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the dock panel's node. It should
	     * not be called directly by user code.
	     */
	    ToolbarButton.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'click':
	                if (this._onClick) {
	                    this._onClick();
	                }
	                break;
	            case 'mousedown':
	                this.addClass(TOOLBAR_PRESSED_CLASS);
	                break;
	            case 'mouseup':
	            case 'mouseout':
	                this.removeClass(TOOLBAR_PRESSED_CLASS);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `after-attach` messages for the widget.
	     */
	    ToolbarButton.prototype.onAfterAttach = function (msg) {
	        this.node.addEventListener('click', this);
	        this.node.addEventListener('mousedown', this);
	        this.node.addEventListener('mouseup', this);
	        this.node.addEventListener('mouseout', this);
	    };
	    /**
	     * Handle `before-detach` messages for the widget.
	     */
	    ToolbarButton.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('click', this);
	        this.node.removeEventListener('mousedown', this);
	        this.node.removeEventListener('mouseup', this);
	        this.node.removeEventListener('mouseout', this);
	    };
	    return ToolbarButton;
	}(widgets_1.Widget));
	exports.ToolbarButton = ToolbarButton;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * An attached property for the name of a toolbar item.
	     */
	    Private.nameProperty = new properties_1.AttachedProperty({
	        name: 'name',
	        create: function () { return ''; }
	    });
	    /**
	     * A kernel name widget.
	     */
	    var KernelName = (function (_super) {
	        __extends(KernelName, _super);
	        /**
	         * Construct a new kernel name widget.
	         */
	        function KernelName(session) {
	            var _this = _super.call(this) || this;
	            _this.addClass(TOOLBAR_KERNEL_CLASS);
	            _this._onKernelChanged(session);
	            session.kernelChanged.connect(_this._onKernelChanged, _this);
	            return _this;
	        }
	        /**
	         * Update the text of the kernel name item.
	         */
	        KernelName.prototype._onKernelChanged = function (session) {
	            this.node.textContent = session.kernelDisplayName;
	        };
	        return KernelName;
	    }(widgets_1.Widget));
	    Private.KernelName = KernelName;
	    /**
	     * A toolbar item that displays kernel status.
	     */
	    var KernelIndicator = (function (_super) {
	        __extends(KernelIndicator, _super);
	        /**
	         * Construct a new kernel status widget.
	         */
	        function KernelIndicator(session) {
	            var _this = _super.call(this) || this;
	            _this.addClass(TOOLBAR_INDICATOR_CLASS);
	            _this._onStatusChanged(session);
	            session.statusChanged.connect(_this._onStatusChanged, _this);
	            return _this;
	        }
	        /**
	         * Handle a status on a kernel.
	         */
	        KernelIndicator.prototype._onStatusChanged = function (session) {
	            if (this.isDisposed) {
	                return;
	            }
	            var status = session.status;
	            this.toggleClass(TOOLBAR_BUSY_CLASS, status !== 'idle');
	            var title = 'Kernel ' + status[0].toUpperCase() + status.slice(1);
	            this.node.title = title;
	        };
	        return KernelIndicator;
	    }(widgets_1.Widget));
	    Private.KernelIndicator = KernelIndicator;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/toolbar.js **/


/** START DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/vdom.js **/
jupyter.define('@jupyterlab/apputils@0.3.1/lib/vdom.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var virtualdom_1 = __jupyter_require__('@phosphor/virtualdom@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	/**
	 * Phosphor widget that encodes best practices for VDOM based rendering.
	 */
	var VDomWidget = (function (_super) {
	    __extends(VDomWidget, _super);
	    function VDomWidget() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._modelChanged = new signaling_1.Signal(_this);
	        return _this;
	    }
	    Object.defineProperty(VDomWidget.prototype, "modelChanged", {
	        /**
	         * A signal emited when the model changes.
	         */
	        get: function () {
	            return this._modelChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(VDomWidget.prototype, "model", {
	        /**
	         * Get the current model.
	         */
	        get: function () {
	            return this._model;
	        },
	        /**
	         * Set the model and fire changed signals.
	         */
	        set: function (newValue) {
	            newValue = newValue || null;
	            if (this._model === newValue) {
	                return;
	            }
	            if (this._model) {
	                this._model.stateChanged.disconnect(this.update, this);
	            }
	            this._model = newValue;
	            if (this._model) {
	                this._model.stateChanged.connect(this.update, this);
	            }
	            this.update();
	            this._modelChanged.emit(void 0);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose this widget.
	     */
	    VDomWidget.prototype.dispose = function () {
	        this._model = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Called to update the state of the widget.
	     *
	     * The default implementation of this method triggers
	     * VDOM based rendering by calling the this.render() method.
	     */
	    VDomWidget.prototype.onUpdateRequest = function (msg) {
	        var vnode = this.render();
	        virtualdom_1.VirtualDOM.render(vnode, this.node);
	    };
	    return VDomWidget;
	}(widgets_1.Widget));
	exports.VDomWidget = VDomWidget;
	/**
	 * Concrete implementation of VDomWidget model.
	 */
	var VDomModel = (function () {
	    function VDomModel() {
	        /**
	         * A signal emitted when any model state changes.
	         */
	        this.stateChanged = new signaling_1.Signal(this);
	        this._isDisposed = false;
	    }
	    Object.defineProperty(VDomModel.prototype, "isDisposed", {
	        /**
	         * Test whether the model is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose the model.
	     */
	    VDomModel.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        signaling_1.Signal.clearData(this);
	    };
	    return VDomModel;
	}());
	exports.VDomModel = VDomModel;
	
})
/** END DEFINE BLOCK for @jupyterlab/apputils@0.3.1/lib/vdom.js **/


/** START DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/default.js **/
jupyter.define('@jupyterlab/docregistry@0.3.1/lib/default.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var codemirror_1 = __jupyter_require__('@jupyterlab/codemirror@^0.3.1/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var codeeditor_1 = __jupyter_require__('@jupyterlab/codeeditor@^0.3.1/lib/index.js');
	/**
	 * The default implementation of a document model.
	 */
	var DocumentModel = (function (_super) {
	    __extends(DocumentModel, _super);
	    /**
	     * Construct a new document model.
	     */
	    function DocumentModel(languagePreference, modelDB) {
	        var _this = _super.call(this, { modelDB: modelDB }) || this;
	        _this._defaultLang = '';
	        _this._dirty = false;
	        _this._readOnly = false;
	        _this._contentChanged = new signaling_1.Signal(_this);
	        _this._stateChanged = new signaling_1.Signal(_this);
	        _this._defaultLang = languagePreference || '';
	        _this.value.changed.connect(_this.triggerContentChange, _this);
	        return _this;
	    }
	    Object.defineProperty(DocumentModel.prototype, "contentChanged", {
	        /**
	         * A signal emitted when the document content changes.
	         */
	        get: function () {
	            return this._contentChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentModel.prototype, "stateChanged", {
	        /**
	         * A signal emitted when the document state changes.
	         */
	        get: function () {
	            return this._stateChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentModel.prototype, "dirty", {
	        /**
	         * The dirty state of the document.
	         */
	        get: function () {
	            return this._dirty;
	        },
	        set: function (newValue) {
	            if (newValue === this._dirty) {
	                return;
	            }
	            var oldValue = this._dirty;
	            this._dirty = newValue;
	            this.triggerStateChange({ name: 'dirty', oldValue: oldValue, newValue: newValue });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentModel.prototype, "readOnly", {
	        /**
	         * The read only state of the document.
	         */
	        get: function () {
	            return this._readOnly;
	        },
	        set: function (newValue) {
	            if (newValue === this._readOnly) {
	                return;
	            }
	            var oldValue = this._readOnly;
	            this._readOnly = newValue;
	            this.triggerStateChange({ name: 'readOnly', oldValue: oldValue, newValue: newValue });
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentModel.prototype, "defaultKernelName", {
	        /**
	         * The default kernel name of the document.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return '';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentModel.prototype, "defaultKernelLanguage", {
	        /**
	         * The default kernel language of the document.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return this._defaultLang;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Serialize the model to a string.
	     */
	    DocumentModel.prototype.toString = function () {
	        return this.value.text;
	    };
	    /**
	     * Deserialize the model from a string.
	     *
	     * #### Notes
	     * Should emit a [contentChanged] signal.
	     */
	    DocumentModel.prototype.fromString = function (value) {
	        this.value.text = value;
	    };
	    /**
	     * Serialize the model to JSON.
	     */
	    DocumentModel.prototype.toJSON = function () {
	        return JSON.stringify(this.value.text);
	    };
	    /**
	     * Deserialize the model from JSON.
	     *
	     * #### Notes
	     * Should emit a [contentChanged] signal.
	     */
	    DocumentModel.prototype.fromJSON = function (value) {
	        this.fromString(JSON.parse(value));
	    };
	    /**
	     * Trigger a state change signal.
	     */
	    DocumentModel.prototype.triggerStateChange = function (args) {
	        this._stateChanged.emit(args);
	    };
	    /**
	     * Trigger a content changed signal.
	     */
	    DocumentModel.prototype.triggerContentChange = function () {
	        this._contentChanged.emit(void 0);
	        this.dirty = true;
	    };
	    return DocumentModel;
	}(codeeditor_1.CodeEditor.Model));
	exports.DocumentModel = DocumentModel;
	/**
	 * An implementation of a model factory for text files.
	 */
	var TextModelFactory = (function () {
	    function TextModelFactory() {
	        this._isDisposed = false;
	    }
	    Object.defineProperty(TextModelFactory.prototype, "name", {
	        /**
	         * The name of the model type.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'text';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TextModelFactory.prototype, "contentType", {
	        /**
	         * The type of the file.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'file';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TextModelFactory.prototype, "fileFormat", {
	        /**
	         * The format of the file.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'text';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TextModelFactory.prototype, "isDisposed", {
	        /**
	         * Get whether the model factory has been disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the model factory.
	     */
	    TextModelFactory.prototype.dispose = function () {
	        this._isDisposed = true;
	    };
	    /**
	     * Create a new model.
	     *
	     * @param languagePreference - An optional kernel language preference.
	     *
	     * @returns A new document model.
	     */
	    TextModelFactory.prototype.createNew = function (languagePreference, modelDB) {
	        return new DocumentModel(languagePreference, modelDB);
	    };
	    /**
	     * Get the preferred kernel language given an extension.
	     */
	    TextModelFactory.prototype.preferredLanguage = function (ext) {
	        return codemirror_1.findModeByExtension(ext.slice(1));
	    };
	    return TextModelFactory;
	}());
	exports.TextModelFactory = TextModelFactory;
	/**
	 * An implementation of a model factory for base64 files.
	 */
	var Base64ModelFactory = (function (_super) {
	    __extends(Base64ModelFactory, _super);
	    function Base64ModelFactory() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    Object.defineProperty(Base64ModelFactory.prototype, "name", {
	        /**
	         * The name of the model type.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'base64';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Base64ModelFactory.prototype, "contentType", {
	        /**
	         * The type of the file.
	         *
	         * #### Notes
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'file';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(Base64ModelFactory.prototype, "fileFormat", {
	        /**
	         * The format of the file.
	         *
	         * This is a read-only property.
	         */
	        get: function () {
	            return 'base64';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return Base64ModelFactory;
	}(TextModelFactory));
	exports.Base64ModelFactory = Base64ModelFactory;
	/**
	 * The default implemetation of a widget factory.
	 */
	var ABCWidgetFactory = (function () {
	    /**
	     * Construct a new `ABCWidgetFactory`.
	     */
	    function ABCWidgetFactory(options) {
	        this._isDisposed = false;
	        this._widgetCreated = new signaling_1.Signal(this);
	        this._name = options.name;
	        this._defaultFor = options.defaultFor ? options.defaultFor.slice() : [];
	        this._fileExtensions = options.fileExtensions.slice();
	        this._modelName = options.modelName || 'text';
	        this._preferKernel = !!options.preferKernel;
	        this._canStartKernel = !!options.canStartKernel;
	    }
	    Object.defineProperty(ABCWidgetFactory.prototype, "widgetCreated", {
	        /**
	         * A signal emitted when a widget is created.
	         */
	        get: function () {
	            return this._widgetCreated;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCWidgetFactory.prototype, "isDisposed", {
	        /**
	         * Get whether the model factory has been disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the document manager.
	     */
	    ABCWidgetFactory.prototype.dispose = function () {
	        this._isDisposed = true;
	    };
	    Object.defineProperty(ABCWidgetFactory.prototype, "name", {
	        /**
	         * The name of the widget to display in dialogs.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCWidgetFactory.prototype, "fileExtensions", {
	        /**
	         * The file extensions the widget can view.
	         */
	        get: function () {
	            return this._fileExtensions.slice();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCWidgetFactory.prototype, "modelName", {
	        /**
	         * The registered name of the model type used to create the widgets.
	         */
	        get: function () {
	            return this._modelName;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCWidgetFactory.prototype, "defaultFor", {
	        /**
	         * The file extensions for which the factory should be the default.
	         */
	        get: function () {
	            return this._defaultFor.slice();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCWidgetFactory.prototype, "preferKernel", {
	        /**
	         * Whether the widgets prefer having a kernel started.
	         */
	        get: function () {
	            return this._preferKernel;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ABCWidgetFactory.prototype, "canStartKernel", {
	        /**
	         * Whether the widgets can start a kernel when opened.
	         */
	        get: function () {
	            return this._canStartKernel;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create a new widget given a document model and a context.
	     *
	     * #### Notes
	     * It should emit the [widgetCreated] signal with the new widget.
	     */
	    ABCWidgetFactory.prototype.createNew = function (context) {
	        var widget = this.createNewWidget(context);
	        this._widgetCreated.emit(widget);
	        return widget;
	    };
	    return ABCWidgetFactory;
	}());
	exports.ABCWidgetFactory = ABCWidgetFactory;
	
})
/** END DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/default.js **/


/** START DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/index.js **/
jupyter.define('@jupyterlab/codemirror@0.3.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	var factory_1 = __jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/factory.js');
	var mimetype_1 = __jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/mimetype.js');
	__export(__jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/mode.js'));
	__export(__jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/editor.js'));
	__export(__jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/factory.js'));
	__export(__jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/mimetype.js'));
	/**
	 * The default editor services.
	 */
	exports.editorServices = {
	    factoryService: new factory_1.CodeMirrorEditorFactory(),
	    mimeTypeService: new mimetype_1.CodeMirrorMimeTypeService()
	};
	
})
/** END DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/factory.js **/
jupyter.define('@jupyterlab/codemirror@0.3.1/lib/factory.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var editor_1 = __jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/editor.js');
	/**
	 * CodeMirror editor factory.
	 */
	var CodeMirrorEditorFactory = (function () {
	    /**
	     * Construct an IEditorFactoryService for CodeMirrorEditors.
	     */
	    function CodeMirrorEditorFactory(codeMirrorOptions) {
	        this.inlineCodeMirrorOptions = {
	            extraKeys: {
	                'Cmd-Right': 'goLineRight',
	                'End': 'goLineRight',
	                'Cmd-Left': 'goLineLeft',
	                'Tab': 'indentMore',
	                'Shift-Tab': 'indentLess',
	                'Cmd-Alt-[': 'indentAuto',
	                'Ctrl-Alt-[': 'indentAuto',
	                'Cmd-/': 'toggleComment',
	                'Ctrl-/': 'toggleComment',
	            }
	        };
	        this.documentCodeMirrorOptions = {
	            extraKeys: {
	                'Tab': 'indentMore',
	                'Shift-Enter': function () { }
	            },
	            lineNumbers: true,
	            lineWrapping: true
	        };
	        if (codeMirrorOptions !== undefined) {
	            // Note: If codeMirrorOptions include `extraKeys`,
	            // existing option will be overwritten.
	            Private.assign(this.inlineCodeMirrorOptions, codeMirrorOptions);
	            Private.assign(this.documentCodeMirrorOptions, codeMirrorOptions);
	        }
	    }
	    /**
	     * Create a new editor for inline code.
	     */
	    CodeMirrorEditorFactory.prototype.newInlineEditor = function (options) {
	        return new editor_1.CodeMirrorEditor(options, this.inlineCodeMirrorOptions);
	    };
	    /**
	     * Create a new editor for a full document.
	     */
	    CodeMirrorEditorFactory.prototype.newDocumentEditor = function (options) {
	        return new editor_1.CodeMirrorEditor(options, this.documentCodeMirrorOptions);
	    };
	    return CodeMirrorEditorFactory;
	}());
	exports.CodeMirrorEditorFactory = CodeMirrorEditorFactory;
	var Private;
	(function (Private) {
	    // Replace with Object.assign when available.
	    function assign(target) {
	        var configs = [];
	        for (var _i = 1; _i < arguments.length; _i++) {
	            configs[_i - 1] = arguments[_i];
	        }
	        var _loop_1 = function (source) {
	            if (source) {
	                Object.keys(source).forEach(function (key) {
	                    target[key] = source[key];
	                });
	            }
	        };
	        for (var _a = 0, configs_1 = configs; _a < configs_1.length; _a++) {
	            var source = configs_1[_a];
	            _loop_1(source);
	        }
	        return target;
	    }
	    Private.assign = assign;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/factory.js **/


/** START DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/editor.js **/
jupyter.define('@jupyterlab/codemirror@0.3.1/lib/editor.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var CodeMirror = __jupyter_require__('codemirror@^5.24.2/lib/codemirror.js');
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	var mode_1 = __jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/mode.js');
	__jupyter_require__('codemirror@^5.24.2/addon/edit/matchbrackets.js');
	__jupyter_require__('codemirror@^5.24.2/addon/edit/closebrackets.js');
	__jupyter_require__('codemirror@^5.24.2/addon/comment/comment.js');
	__jupyter_require__('codemirror@^5.24.2/keymap/vim.js');
	/**
	 * The class name added to CodeMirrorWidget instances.
	 */
	var EDITOR_CLASS = 'jp-CodeMirrorWidget';
	/**
	 * The class name added to read only cell editor widgets.
	 */
	var READ_ONLY_CLASS = 'jp-mod-readOnly';
	/**
	 * The key code for the up arrow key.
	 */
	var UP_ARROW = 38;
	/**
	 * The key code for the down arrow key.
	 */
	var DOWN_ARROW = 40;
	/**
	 * CodeMirror editor.
	 */
	var CodeMirrorEditor = (function () {
	    /**
	     * Construct a CodeMirror editor.
	     */
	    function CodeMirrorEditor(options, config) {
	        if (config === void 0) { config = {}; }
	        var _this = this;
	        /**
	         * A signal emitted when either the top or bottom edge is requested.
	         */
	        this.edgeRequested = new signaling_1.Signal(this);
	        this.selectionMarkers = {};
	        this._keydownHandlers = new Array();
	        this._changeGuard = false;
	        this._uuid = '';
	        var host = this.host = options.host;
	        host.classList.add(EDITOR_CLASS);
	        this._uuid = options.uuid || coreutils_1.uuid();
	        this._selectionStyle = options.selectionStyle || {};
	        Private.updateConfig(options, config);
	        var model = this._model = options.model;
	        var editor = this._editor = CodeMirror(host, config);
	        var doc = editor.getDoc();
	        // Handle initial values for text, mimetype, and selections.
	        doc.setValue(model.value.text);
	        this._onMimeTypeChanged();
	        this._onCursorActivity();
	        // Connect to changes.
	        model.value.changed.connect(this._onValueChanged, this);
	        model.mimeTypeChanged.connect(this._onMimeTypeChanged, this);
	        model.selections.changed.connect(this._onSelectionsChanged, this);
	        CodeMirror.on(editor, 'keydown', function (editor, event) {
	            var index = algorithm_1.ArrayExt.findFirstIndex(_this._keydownHandlers, function (handler) {
	                if (handler(_this, event) === true) {
	                    event.preventDefault();
	                    return true;
	                }
	            });
	            if (index === -1) {
	                _this.onKeydown(event);
	            }
	        });
	        CodeMirror.on(editor, 'cursorActivity', function () { return _this._onCursorActivity(); });
	        CodeMirror.on(editor.getDoc(), 'beforeChange', function (instance, change) {
	            _this._onDocChanged(instance, change);
	        });
	    }
	    Object.defineProperty(CodeMirrorEditor.prototype, "uuid", {
	        /**
	         * The uuid of this editor;
	         */
	        get: function () {
	            return this._uuid;
	        },
	        set: function (value) {
	            this._uuid = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "selectionStyle", {
	        /**
	         * The selection style of this editor.
	         */
	        get: function () {
	            return this._selectionStyle;
	        },
	        set: function (value) {
	            this._selectionStyle = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "editor", {
	        /**
	         * Get the codemirror editor wrapped by the editor.
	         */
	        get: function () {
	            return this._editor;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "doc", {
	        /**
	         * Get the codemirror doc wrapped by the widget.
	         */
	        get: function () {
	            return this._editor.getDoc();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "lineCount", {
	        /**
	         * Get the number of lines in the editor.
	         */
	        get: function () {
	            return this.doc.lineCount();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "lineNumbers", {
	        /**
	         * Control the rendering of line numbers.
	         */
	        get: function () {
	            return this._editor.getOption('lineNumbers');
	        },
	        set: function (value) {
	            this._editor.setOption('lineNumbers', value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "wordWrap", {
	        /**
	         * Set to false for horizontal scrolling. Defaults to true.
	         */
	        get: function () {
	            return this._editor.getOption('lineWrapping');
	        },
	        set: function (value) {
	            this._editor.setOption('lineWrapping', value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "readOnly", {
	        /**
	         * Should the editor be read only.
	         */
	        get: function () {
	            return this._editor.getOption('readOnly') !== false;
	        },
	        set: function (readOnly) {
	            this._editor.setOption('readOnly', readOnly);
	            if (readOnly) {
	                this.host.classList.add(READ_ONLY_CLASS);
	            }
	            else {
	                this.host.classList.remove(READ_ONLY_CLASS);
	                this.blur();
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "model", {
	        /**
	         * Returns a model for this editor.
	         */
	        get: function () {
	            return this._model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "lineHeight", {
	        /**
	         * The height of a line in the editor in pixels.
	         */
	        get: function () {
	            return this._editor.defaultTextHeight();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "charWidth", {
	        /**
	         * The widget of a character in the editor in pixels.
	         */
	        get: function () {
	            return this._editor.defaultCharWidth();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeMirrorEditor.prototype, "isDisposed", {
	        /**
	         * Tests whether the editor is disposed.
	         */
	        get: function () {
	            return this._editor === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    CodeMirrorEditor.prototype.dispose = function () {
	        if (this._editor === null) {
	            return;
	        }
	        this._editor = null;
	        this._model = null;
	        this._keydownHandlers.length = 0;
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * Returns the content for the given line number.
	     */
	    CodeMirrorEditor.prototype.getLine = function (line) {
	        return this.doc.getLine(line);
	    };
	    /**
	     * Find an offset for the given position.
	     */
	    CodeMirrorEditor.prototype.getOffsetAt = function (position) {
	        return this.doc.indexFromPos({
	            ch: position.column,
	            line: position.line
	        });
	    };
	    /**
	     * Find a position fot the given offset.
	     */
	    CodeMirrorEditor.prototype.getPositionAt = function (offset) {
	        var _a = this.doc.posFromIndex(offset), ch = _a.ch, line = _a.line;
	        return { line: line, column: ch };
	    };
	    /**
	     * Undo one edit (if any undo events are stored).
	     */
	    CodeMirrorEditor.prototype.undo = function () {
	        this.doc.undo();
	    };
	    /**
	     * Redo one undone edit.
	     */
	    CodeMirrorEditor.prototype.redo = function () {
	        this.doc.redo();
	    };
	    /**
	     * Clear the undo history.
	     */
	    CodeMirrorEditor.prototype.clearHistory = function () {
	        this.doc.clearHistory();
	    };
	    /**
	     * Brings browser focus to this editor text.
	     */
	    CodeMirrorEditor.prototype.focus = function () {
	        this._editor.focus();
	    };
	    /**
	     * Test whether the editor has keyboard focus.
	     */
	    CodeMirrorEditor.prototype.hasFocus = function () {
	        return this._editor.hasFocus();
	    };
	    /**
	     * Explicitly blur the editor.
	     */
	    CodeMirrorEditor.prototype.blur = function () {
	        this._editor.getInputField().blur();
	    };
	    /**
	     * Repaint editor.
	     */
	    CodeMirrorEditor.prototype.refresh = function () {
	        this._editor.refresh();
	    };
	    /**
	     * Add a keydown handler to the editor.
	     *
	     * @param handler - A keydown handler.
	     *
	     * @returns A disposable that can be used to remove the handler.
	     */
	    CodeMirrorEditor.prototype.addKeydownHandler = function (handler) {
	        var _this = this;
	        this._keydownHandlers.push(handler);
	        return new disposable_1.DisposableDelegate(function () {
	            algorithm_1.ArrayExt.removeAllWhere(_this._keydownHandlers, function (val) { return val === handler; });
	        });
	    };
	    /**
	     * Set the size of the editor in pixels.
	     */
	    CodeMirrorEditor.prototype.setSize = function (dimension) {
	        if (dimension) {
	            this._editor.setSize(dimension.width, dimension.height);
	        }
	        else {
	            this._editor.setSize(null, null);
	        }
	    };
	    /**
	     * Reveal the given position in the editor.
	     */
	    CodeMirrorEditor.prototype.revealPosition = function (position) {
	        var cmPosition = this._toCodeMirrorPosition(position);
	        this._editor.scrollIntoView(cmPosition);
	    };
	    /**
	     * Reveal the given selection in the editor.
	     */
	    CodeMirrorEditor.prototype.revealSelection = function (selection) {
	        var range = this._toCodeMirrorRange(selection);
	        this._editor.scrollIntoView(range);
	    };
	    /**
	     * Get the window coordinates given a cursor position.
	     */
	    CodeMirrorEditor.prototype.getCoordinateForPosition = function (position) {
	        var pos = this._toCodeMirrorPosition(position);
	        var rect = this.editor.charCoords(pos, 'page');
	        return rect;
	    };
	    /**
	     * Get the cursor position given window coordinates.
	     *
	     * @param coordinate - The desired coordinate.
	     *
	     * @returns The position of the coordinates, or null if not
	     *   contained in the editor.
	     */
	    CodeMirrorEditor.prototype.getPositionForCoordinate = function (coordinate) {
	        return this._toPosition(this.editor.coordsChar(coordinate)) || null;
	    };
	    /**
	     * Returns the primary position of the cursor, never `null`.
	     */
	    CodeMirrorEditor.prototype.getCursorPosition = function () {
	        var cursor = this.doc.getCursor();
	        return this._toPosition(cursor);
	    };
	    /**
	     * Set the primary position of the cursor.
	     *
	     * #### Notes
	     * This will remove any secondary cursors.
	     */
	    CodeMirrorEditor.prototype.setCursorPosition = function (position) {
	        var cursor = this._toCodeMirrorPosition(position);
	        this.doc.setCursor(cursor);
	    };
	    /**
	     * Returns the primary selection, never `null`.
	     */
	    CodeMirrorEditor.prototype.getSelection = function () {
	        return this.getSelections()[0];
	    };
	    /**
	     * Set the primary selection. This will remove any secondary cursors.
	     */
	    CodeMirrorEditor.prototype.setSelection = function (selection) {
	        this.setSelections([selection]);
	    };
	    /**
	     * Gets the selections for all the cursors, never `null` or empty.
	     */
	    CodeMirrorEditor.prototype.getSelections = function () {
	        var _this = this;
	        var selections = this.doc.listSelections();
	        if (selections.length > 0) {
	            return selections.map(function (selection) { return _this._toSelection(selection); });
	        }
	        var cursor = this.doc.getCursor();
	        var selection = this._toSelection({ anchor: cursor, head: cursor });
	        return [selection];
	    };
	    /**
	     * Sets the selections for all the cursors, should not be empty.
	     * Cursors will be removed or added, as necessary.
	     * Passing an empty array resets a cursor position to the start of a document.
	     */
	    CodeMirrorEditor.prototype.setSelections = function (selections) {
	        var cmSelections = this._toCodeMirrorSelections(selections);
	        this.doc.setSelections(cmSelections, 0);
	    };
	    /**
	     * Handle keydown events from the editor.
	     */
	    CodeMirrorEditor.prototype.onKeydown = function (event) {
	        var position = this.getCursorPosition();
	        var line = position.line, column = position.column;
	        if (line === 0 && column === 0 && event.keyCode === UP_ARROW) {
	            if (!event.shiftKey) {
	                this.edgeRequested.emit('top');
	            }
	            return false;
	        }
	        var lastLine = this.lineCount - 1;
	        var lastCh = this.getLine(lastLine).length;
	        if (line === lastLine && column === lastCh
	            && event.keyCode === DOWN_ARROW) {
	            if (!event.shiftKey) {
	                this.edgeRequested.emit('bottom');
	            }
	            return false;
	        }
	        return false;
	    };
	    /**
	     * Converts selections to code mirror selections.
	     */
	    CodeMirrorEditor.prototype._toCodeMirrorSelections = function (selections) {
	        var _this = this;
	        if (selections.length > 0) {
	            return selections.map(function (selection) { return _this._toCodeMirrorSelection(selection); });
	        }
	        var position = { line: 0, ch: 0 };
	        return [{ anchor: position, head: position }];
	    };
	    /**
	     * Handles a mime type change.
	     */
	    CodeMirrorEditor.prototype._onMimeTypeChanged = function () {
	        var mime = this._model.mimeType;
	        var editor = this._editor;
	        mode_1.loadModeByMIME(editor, mime);
	        var isCode = (mime !== 'text/plain') && (mime !== 'text/x-ipythongfm');
	        editor.setOption('matchBrackets', isCode);
	        editor.setOption('autoCloseBrackets', isCode);
	        var extraKeys = editor.getOption('extraKeys') || {};
	        if (isCode) {
	            extraKeys['Backspace'] = 'delSpaceToPrevTabStop';
	        }
	        else {
	            delete extraKeys['Backspace'];
	        }
	        editor.setOption('extraKeys', extraKeys);
	    };
	    /**
	     * Handles a selections change.
	     */
	    CodeMirrorEditor.prototype._onSelectionsChanged = function (selections, args) {
	        var uuid = args.key;
	        if (uuid !== this.uuid) {
	            this._cleanSelections(uuid);
	            this._markSelections(uuid, args.newValue);
	        }
	    };
	    /**
	     * Clean selections for the given uuid.
	     */
	    CodeMirrorEditor.prototype._cleanSelections = function (uuid) {
	        var markers = this.selectionMarkers[uuid];
	        if (markers) {
	            markers.forEach(function (marker) { marker.clear(); });
	        }
	        delete this.selectionMarkers[uuid];
	    };
	    /**
	     * Marks selections.
	     */
	    CodeMirrorEditor.prototype._markSelections = function (uuid, selections) {
	        var _this = this;
	        var markers = [];
	        selections.forEach(function (selection) {
	            var _a = _this._toCodeMirrorSelection(selection), anchor = _a.anchor, head = _a.head;
	            var markerOptions = _this._toTextMarkerOptions(selection);
	            _this.doc.markText(anchor, head, markerOptions);
	        });
	        this.selectionMarkers[uuid] = markers;
	    };
	    /**
	     * Handles a cursor activity event.
	     */
	    CodeMirrorEditor.prototype._onCursorActivity = function () {
	        var selections = this.getSelections();
	        this.model.selections.set(this.uuid, selections);
	    };
	    /**
	     * Converts a code mirror selection to an editor selection.
	     */
	    CodeMirrorEditor.prototype._toSelection = function (selection) {
	        return {
	            uuid: this.uuid,
	            start: this._toPosition(selection.anchor),
	            end: this._toPosition(selection.head),
	            style: this.selectionStyle
	        };
	    };
	    /**
	     * Converts the selection style to a text marker options.
	     */
	    CodeMirrorEditor.prototype._toTextMarkerOptions = function (style) {
	        if (style) {
	            return {
	                className: style.className,
	                title: style.displayName
	            };
	        }
	        return undefined;
	    };
	    /**
	     * Converts an editor selection to a code mirror selection.
	     */
	    CodeMirrorEditor.prototype._toCodeMirrorSelection = function (selection) {
	        return {
	            anchor: this._toCodeMirrorPosition(selection.start),
	            head: this._toCodeMirrorPosition(selection.end)
	        };
	    };
	    /**
	     * Converts an editor selection to a code mirror selection.
	     */
	    CodeMirrorEditor.prototype._toCodeMirrorRange = function (range) {
	        return {
	            from: this._toCodeMirrorPosition(range.start),
	            to: this._toCodeMirrorPosition(range.end)
	        };
	    };
	    /**
	     * Convert a code mirror position to an editor position.
	     */
	    CodeMirrorEditor.prototype._toPosition = function (position) {
	        return {
	            line: position.line,
	            column: position.ch
	        };
	    };
	    /**
	     * Convert an editor position to a code mirror position.
	     */
	    CodeMirrorEditor.prototype._toCodeMirrorPosition = function (position) {
	        return {
	            line: position.line,
	            ch: position.column
	        };
	    };
	    /**
	     * Handle model value changes.
	     */
	    CodeMirrorEditor.prototype._onValueChanged = function (value, args) {
	        if (this._changeGuard) {
	            return;
	        }
	        this._changeGuard = true;
	        var doc = this.doc;
	        switch (args.type) {
	            case 'insert':
	                var pos = doc.posFromIndex(args.start);
	                doc.replaceRange(args.value, pos, pos);
	                break;
	            case 'remove':
	                var from = doc.posFromIndex(args.start);
	                var to = doc.posFromIndex(args.end);
	                doc.replaceRange('', from, to);
	                break;
	            case 'set':
	                doc.setValue(args.value);
	                break;
	            default:
	                break;
	        }
	        this._changeGuard = false;
	    };
	    /**
	     * Handles document changes.
	     */
	    CodeMirrorEditor.prototype._onDocChanged = function (doc, change) {
	        if (this._changeGuard) {
	            return;
	        }
	        this._changeGuard = true;
	        var value = this._model.value;
	        var start = doc.indexFromPos(change.from);
	        var end = doc.indexFromPos(change.to);
	        var inserted = change.text.join('\n');
	        if (end !== start) {
	            value.remove(start, end);
	        }
	        if (inserted) {
	            value.insert(start, inserted);
	        }
	        this._changeGuard = false;
	    };
	    return CodeMirrorEditor;
	}());
	exports.CodeMirrorEditor = CodeMirrorEditor;
	/**
	 * The namespace for `CodeMirrorEditor` statics.
	 */
	(function (CodeMirrorEditor) {
	    /**
	     * The name of the default CodeMirror theme
	     */
	    CodeMirrorEditor.DEFAULT_THEME = 'jupyter';
	})(CodeMirrorEditor = exports.CodeMirrorEditor || (exports.CodeMirrorEditor = {}));
	exports.CodeMirrorEditor = CodeMirrorEditor;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Handle extra codemirror config from codeeditor options.
	     */
	    function updateConfig(options, config) {
	        if (options.readOnly !== undefined) {
	            config.readOnly = options.readOnly;
	        }
	        else {
	            config.readOnly = false;
	        }
	        if (options.lineNumbers !== undefined) {
	            config.lineNumbers = options.lineNumbers;
	        }
	        else {
	            config.lineNumbers = false;
	        }
	        if (options.wordWrap !== undefined) {
	            config.lineWrapping = options.wordWrap;
	        }
	        else {
	            config.lineWrapping = true;
	        }
	        config.theme = (config.theme || CodeMirrorEditor.DEFAULT_THEME);
	        config.indentUnit = config.indentUnit || 4;
	    }
	    Private.updateConfig = updateConfig;
	    /**
	     * Delete spaces to the previous tab stob in a codemirror editor.
	     */
	    function delSpaceToPrevTabStop(cm) {
	        var doc = cm.getDoc();
	        var from = doc.getCursor('from');
	        var to = doc.getCursor('to');
	        var sel = !posEq(from, to);
	        if (sel) {
	            var ranges = doc.listSelections();
	            for (var i = ranges.length - 1; i >= 0; i--) {
	                var head = ranges[i].head;
	                var anchor = ranges[i].anchor;
	                doc.replaceRange('', CodeMirror.Pos(head.line, head.ch), CodeMirror.Pos(anchor.line, anchor.ch));
	            }
	            return;
	        }
	        var cur = doc.getCursor();
	        var tabsize = cm.getOption('tabSize');
	        var chToPrevTabStop = cur.ch - (Math.ceil(cur.ch / tabsize) - 1) * tabsize;
	        from = { ch: cur.ch - chToPrevTabStop, line: cur.line };
	        var select = doc.getRange(from, cur);
	        if (select.match(/^\ +$/) !== null) {
	            doc.replaceRange('', from, cur);
	        }
	        else {
	            CodeMirror.commands['delCharBefore'](cm);
	        }
	    }
	    Private.delSpaceToPrevTabStop = delSpaceToPrevTabStop;
	    ;
	    /**
	     * Test whether two CodeMirror positions are equal.
	     */
	    function posEq(a, b) {
	        return a.line === b.line && a.ch === b.ch;
	    }
	    Private.posEq = posEq;
	    ;
	})(Private || (Private = {}));
	/**
	 * Add a CodeMirror command to delete until previous non blanking space
	 * character or first multiple of 4 tabstop.
	 */
	CodeMirror.commands['delSpaceToPrevTabStop'] = Private.delSpaceToPrevTabStop;
	
})
/** END DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/editor.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/lib/codemirror.js **/
jupyter.define('codemirror@5.27.2/lib/codemirror.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	// This is CodeMirror (http://codemirror.net), a code editor
	// implemented in JavaScript on top of the browser's DOM.
	//
	// You can find some technical background for some of the code below
	// at http://marijnhaverbeke.nl/blog/#cm-internals .
	
	(function (global, factory) {
		 true ? module.exports = factory() :
		typeof define === 'function' && define.amd ? define(factory) :
		(global.CodeMirror = factory());
	}(this, (function () { 'use strict';
	
	// Kludges for bugs and behavior differences that can't be feature
	// detected are enabled based on userAgent etc sniffing.
	var userAgent = navigator.userAgent;
	var platform = navigator.platform;
	
	var gecko = /gecko\/\d/i.test(userAgent);
	var ie_upto10 = /MSIE \d/.test(userAgent);
	var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
	var edge = /Edge\/(\d+)/.exec(userAgent);
	var ie = ie_upto10 || ie_11up || edge;
	var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]);
	var webkit = !edge && /WebKit\//.test(userAgent);
	var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
	var chrome = !edge && /Chrome\//.test(userAgent);
	var presto = /Opera\//.test(userAgent);
	var safari = /Apple Computer/.test(navigator.vendor);
	var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
	var phantom = /PhantomJS/.test(userAgent);
	
	var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
	var android = /Android/.test(userAgent);
	// This is woefully incomplete. Suggestions for alternative methods welcome.
	var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
	var mac = ios || /Mac/.test(platform);
	var chromeOS = /\bCrOS\b/.test(userAgent);
	var windows = /win/i.test(platform);
	
	var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
	if (presto_version) { presto_version = Number(presto_version[1]); }
	if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
	// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
	var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
	var captureRightClick = gecko || (ie && ie_version >= 9);
	
	function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
	
	var rmClass = function(node, cls) {
	  var current = node.className;
	  var match = classTest(cls).exec(current);
	  if (match) {
	    var after = current.slice(match.index + match[0].length);
	    node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
	  }
	};
	
	function removeChildren(e) {
	  for (var count = e.childNodes.length; count > 0; --count)
	    { e.removeChild(e.firstChild); }
	  return e
	}
	
	function removeChildrenAndAdd(parent, e) {
	  return removeChildren(parent).appendChild(e)
	}
	
	function elt(tag, content, className, style) {
	  var e = document.createElement(tag);
	  if (className) { e.className = className; }
	  if (style) { e.style.cssText = style; }
	  if (typeof content == "string") { e.appendChild(document.createTextNode(content)); }
	  else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } }
	  return e
	}
	// wrapper for elt, which removes the elt from the accessibility tree
	function eltP(tag, content, className, style) {
	  var e = elt(tag, content, className, style);
	  e.setAttribute("role", "presentation");
	  return e
	}
	
	var range;
	if (document.createRange) { range = function(node, start, end, endNode) {
	  var r = document.createRange();
	  r.setEnd(endNode || node, end);
	  r.setStart(node, start);
	  return r
	}; }
	else { range = function(node, start, end) {
	  var r = document.body.createTextRange();
	  try { r.moveToElementText(node.parentNode); }
	  catch(e) { return r }
	  r.collapse(true);
	  r.moveEnd("character", end);
	  r.moveStart("character", start);
	  return r
	}; }
	
	function contains(parent, child) {
	  if (child.nodeType == 3) // Android browser always returns false when child is a textnode
	    { child = child.parentNode; }
	  if (parent.contains)
	    { return parent.contains(child) }
	  do {
	    if (child.nodeType == 11) { child = child.host; }
	    if (child == parent) { return true }
	  } while (child = child.parentNode)
	}
	
	function activeElt() {
	  // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement.
	  // IE < 10 will throw when accessed while the page is loading or in an iframe.
	  // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
	  var activeElement;
	  try {
	    activeElement = document.activeElement;
	  } catch(e) {
	    activeElement = document.body || null;
	  }
	  while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
	    { activeElement = activeElement.shadowRoot.activeElement; }
	  return activeElement
	}
	
	function addClass(node, cls) {
	  var current = node.className;
	  if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; }
	}
	function joinClasses(a, b) {
	  var as = a.split(" ");
	  for (var i = 0; i < as.length; i++)
	    { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } }
	  return b
	}
	
	var selectInput = function(node) { node.select(); };
	if (ios) // Mobile Safari apparently has a bug where select() is broken.
	  { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; }
	else if (ie) // Suppress mysterious IE10 errors
	  { selectInput = function(node) { try { node.select(); } catch(_e) {} }; }
	
	function bind(f) {
	  var args = Array.prototype.slice.call(arguments, 1);
	  return function(){return f.apply(null, args)}
	}
	
	function copyObj(obj, target, overwrite) {
	  if (!target) { target = {}; }
	  for (var prop in obj)
	    { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
	      { target[prop] = obj[prop]; } }
	  return target
	}
	
	// Counts the column offset in a string, taking tabs into account.
	// Used mostly to find indentation.
	function countColumn(string, end, tabSize, startIndex, startValue) {
	  if (end == null) {
	    end = string.search(/[^\s\u00a0]/);
	    if (end == -1) { end = string.length; }
	  }
	  for (var i = startIndex || 0, n = startValue || 0;;) {
	    var nextTab = string.indexOf("\t", i);
	    if (nextTab < 0 || nextTab >= end)
	      { return n + (end - i) }
	    n += nextTab - i;
	    n += tabSize - (n % tabSize);
	    i = nextTab + 1;
	  }
	}
	
	var Delayed = function() {this.id = null;};
	Delayed.prototype.set = function (ms, f) {
	  clearTimeout(this.id);
	  this.id = setTimeout(f, ms);
	};
	
	function indexOf(array, elt) {
	  for (var i = 0; i < array.length; ++i)
	    { if (array[i] == elt) { return i } }
	  return -1
	}
	
	// Number of pixels added to scroller and sizer to hide scrollbar
	var scrollerGap = 30;
	
	// Returned or thrown by various protocols to signal 'I'm not
	// handling this'.
	var Pass = {toString: function(){return "CodeMirror.Pass"}};
	
	// Reused option objects for setSelection & friends
	var sel_dontScroll = {scroll: false};
	var sel_mouse = {origin: "*mouse"};
	var sel_move = {origin: "+move"};
	
	// The inverse of countColumn -- find the offset that corresponds to
	// a particular column.
	function findColumn(string, goal, tabSize) {
	  for (var pos = 0, col = 0;;) {
	    var nextTab = string.indexOf("\t", pos);
	    if (nextTab == -1) { nextTab = string.length; }
	    var skipped = nextTab - pos;
	    if (nextTab == string.length || col + skipped >= goal)
	      { return pos + Math.min(skipped, goal - col) }
	    col += nextTab - pos;
	    col += tabSize - (col % tabSize);
	    pos = nextTab + 1;
	    if (col >= goal) { return pos }
	  }
	}
	
	var spaceStrs = [""];
	function spaceStr(n) {
	  while (spaceStrs.length <= n)
	    { spaceStrs.push(lst(spaceStrs) + " "); }
	  return spaceStrs[n]
	}
	
	function lst(arr) { return arr[arr.length-1] }
	
	function map(array, f) {
	  var out = [];
	  for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); }
	  return out
	}
	
	function insertSorted(array, value, score) {
	  var pos = 0, priority = score(value);
	  while (pos < array.length && score(array[pos]) <= priority) { pos++; }
	  array.splice(pos, 0, value);
	}
	
	function nothing() {}
	
	function createObj(base, props) {
	  var inst;
	  if (Object.create) {
	    inst = Object.create(base);
	  } else {
	    nothing.prototype = base;
	    inst = new nothing();
	  }
	  if (props) { copyObj(props, inst); }
	  return inst
	}
	
	var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
	function isWordCharBasic(ch) {
	  return /\w/.test(ch) || ch > "\x80" &&
	    (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))
	}
	function isWordChar(ch, helper) {
	  if (!helper) { return isWordCharBasic(ch) }
	  if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true }
	  return helper.test(ch)
	}
	
	function isEmpty(obj) {
	  for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } }
	  return true
	}
	
	// Extending unicode characters. A series of a non-extending char +
	// any number of extending chars is treated as a single unit as far
	// as editing and measuring is concerned. This is not fully correct,
	// since some scripts/fonts/browsers also treat other configurations
	// of code points as a group.
	var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
	function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) }
	
	// Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range.
	function skipExtendingChars(str, pos, dir) {
	  while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; }
	  return pos
	}
	
	// Returns the value from the range [`from`; `to`] that satisfies
	// `pred` and is closest to `from`. Assumes that at least `to` satisfies `pred`.
	function findFirst(pred, from, to) {
	  for (;;) {
	    if (Math.abs(from - to) <= 1) { return pred(from) ? from : to }
	    var mid = Math.floor((from + to) / 2);
	    if (pred(mid)) { to = mid; }
	    else { from = mid; }
	  }
	}
	
	// The display handles the DOM integration, both for input reading
	// and content drawing. It holds references to DOM nodes and
	// display-related state.
	
	function Display(place, doc, input) {
	  var d = this;
	  this.input = input;
	
	  // Covers bottom-right square when both scrollbars are present.
	  d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
	  d.scrollbarFiller.setAttribute("cm-not-content", "true");
	  // Covers bottom of gutter when coverGutterNextToScrollbar is on
	  // and h scrollbar is present.
	  d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
	  d.gutterFiller.setAttribute("cm-not-content", "true");
	  // Will contain the actual code, positioned to cover the viewport.
	  d.lineDiv = eltP("div", null, "CodeMirror-code");
	  // Elements are added to these to represent selection and cursors.
	  d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
	  d.cursorDiv = elt("div", null, "CodeMirror-cursors");
	  // A visibility: hidden element used to find the size of things.
	  d.measure = elt("div", null, "CodeMirror-measure");
	  // When lines outside of the viewport are measured, they are drawn in this.
	  d.lineMeasure = elt("div", null, "CodeMirror-measure");
	  // Wraps everything that needs to exist inside the vertically-padded coordinate system
	  d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
	                    null, "position: relative; outline: none");
	  var lines = eltP("div", [d.lineSpace], "CodeMirror-lines");
	  // Moved around its parent to cover visible view.
	  d.mover = elt("div", [lines], null, "position: relative");
	  // Set to the height of the document, allowing scrolling.
	  d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
	  d.sizerWidth = null;
	  // Behavior of elts with overflow: auto and padding is
	  // inconsistent across browsers. This is used to ensure the
	  // scrollable area is big enough.
	  d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
	  // Will contain the gutters, if any.
	  d.gutters = elt("div", null, "CodeMirror-gutters");
	  d.lineGutter = null;
	  // Actual scrollable element.
	  d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
	  d.scroller.setAttribute("tabIndex", "-1");
	  // The element in which the editor lives.
	  d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
	
	  // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
	  if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
	  if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; }
	
	  if (place) {
	    if (place.appendChild) { place.appendChild(d.wrapper); }
	    else { place(d.wrapper); }
	  }
	
	  // Current rendered range (may be bigger than the view window).
	  d.viewFrom = d.viewTo = doc.first;
	  d.reportedViewFrom = d.reportedViewTo = doc.first;
	  // Information about the rendered lines.
	  d.view = [];
	  d.renderedView = null;
	  // Holds info about a single rendered line when it was rendered
	  // for measurement, while not in view.
	  d.externalMeasured = null;
	  // Empty space (in pixels) above the view
	  d.viewOffset = 0;
	  d.lastWrapHeight = d.lastWrapWidth = 0;
	  d.updateLineNumbers = null;
	
	  d.nativeBarWidth = d.barHeight = d.barWidth = 0;
	  d.scrollbarsClipped = false;
	
	  // Used to only resize the line number gutter when necessary (when
	  // the amount of lines crosses a boundary that makes its width change)
	  d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
	  // Set to true when a non-horizontal-scrolling line widget is
	  // added. As an optimization, line widget aligning is skipped when
	  // this is false.
	  d.alignWidgets = false;
	
	  d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
	
	  // Tracks the maximum line length so that the horizontal scrollbar
	  // can be kept static when scrolling.
	  d.maxLine = null;
	  d.maxLineLength = 0;
	  d.maxLineChanged = false;
	
	  // Used for measuring wheel scrolling granularity
	  d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
	
	  // True when shift is held down.
	  d.shift = false;
	
	  // Used to track whether anything happened since the context menu
	  // was opened.
	  d.selForContextMenu = null;
	
	  d.activeTouch = null;
	
	  input.init(d);
	}
	
	// Find the line object corresponding to the given line number.
	function getLine(doc, n) {
	  n -= doc.first;
	  if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") }
	  var chunk = doc;
	  while (!chunk.lines) {
	    for (var i = 0;; ++i) {
	      var child = chunk.children[i], sz = child.chunkSize();
	      if (n < sz) { chunk = child; break }
	      n -= sz;
	    }
	  }
	  return chunk.lines[n]
	}
	
	// Get the part of a document between two positions, as an array of
	// strings.
	function getBetween(doc, start, end) {
	  var out = [], n = start.line;
	  doc.iter(start.line, end.line + 1, function (line) {
	    var text = line.text;
	    if (n == end.line) { text = text.slice(0, end.ch); }
	    if (n == start.line) { text = text.slice(start.ch); }
	    out.push(text);
	    ++n;
	  });
	  return out
	}
	// Get the lines between from and to, as array of strings.
	function getLines(doc, from, to) {
	  var out = [];
	  doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value
	  return out
	}
	
	// Update the height of a line, propagating the height change
	// upwards to parent nodes.
	function updateLineHeight(line, height) {
	  var diff = height - line.height;
	  if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } }
	}
	
	// Given a line object, find its line number by walking up through
	// its parent links.
	function lineNo(line) {
	  if (line.parent == null) { return null }
	  var cur = line.parent, no = indexOf(cur.lines, line);
	  for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
	    for (var i = 0;; ++i) {
	      if (chunk.children[i] == cur) { break }
	      no += chunk.children[i].chunkSize();
	    }
	  }
	  return no + cur.first
	}
	
	// Find the line at the given vertical position, using the height
	// information in the document tree.
	function lineAtHeight(chunk, h) {
	  var n = chunk.first;
	  outer: do {
	    for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) {
	      var child = chunk.children[i$1], ch = child.height;
	      if (h < ch) { chunk = child; continue outer }
	      h -= ch;
	      n += child.chunkSize();
	    }
	    return n
	  } while (!chunk.lines)
	  var i = 0;
	  for (; i < chunk.lines.length; ++i) {
	    var line = chunk.lines[i], lh = line.height;
	    if (h < lh) { break }
	    h -= lh;
	  }
	  return n + i
	}
	
	function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
	
	function lineNumberFor(options, i) {
	  return String(options.lineNumberFormatter(i + options.firstLineNumber))
	}
	
	// A Pos instance represents a position within the text.
	function Pos(line, ch, sticky) {
	  if ( sticky === void 0 ) sticky = null;
	
	  if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) }
	  this.line = line;
	  this.ch = ch;
	  this.sticky = sticky;
	}
	
	// Compare two positions, return 0 if they are the same, a negative
	// number when a is less, and a positive number otherwise.
	function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
	
	function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }
	
	function copyPos(x) {return Pos(x.line, x.ch)}
	function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
	function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
	
	// Most of the external API clips given positions to make sure they
	// actually exist within the document.
	function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}
	function clipPos(doc, pos) {
	  if (pos.line < doc.first) { return Pos(doc.first, 0) }
	  var last = doc.first + doc.size - 1;
	  if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) }
	  return clipToLen(pos, getLine(doc, pos.line).text.length)
	}
	function clipToLen(pos, linelen) {
	  var ch = pos.ch;
	  if (ch == null || ch > linelen) { return Pos(pos.line, linelen) }
	  else if (ch < 0) { return Pos(pos.line, 0) }
	  else { return pos }
	}
	function clipPosArray(doc, array) {
	  var out = [];
	  for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); }
	  return out
	}
	
	// Optimize some code when these features are not used.
	var sawReadOnlySpans = false;
	var sawCollapsedSpans = false;
	
	function seeReadOnlySpans() {
	  sawReadOnlySpans = true;
	}
	
	function seeCollapsedSpans() {
	  sawCollapsedSpans = true;
	}
	
	// TEXTMARKER SPANS
	
	function MarkedSpan(marker, from, to) {
	  this.marker = marker;
	  this.from = from; this.to = to;
	}
	
	// Search an array of spans for a span matching the given marker.
	function getMarkedSpanFor(spans, marker) {
	  if (spans) { for (var i = 0; i < spans.length; ++i) {
	    var span = spans[i];
	    if (span.marker == marker) { return span }
	  } }
	}
	// Remove a span from an array, returning undefined if no spans are
	// left (we don't store arrays for lines without spans).
	function removeMarkedSpan(spans, span) {
	  var r;
	  for (var i = 0; i < spans.length; ++i)
	    { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } }
	  return r
	}
	// Add a span to a line.
	function addMarkedSpan(line, span) {
	  line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
	  span.marker.attachLine(line);
	}
	
	// Used for the algorithm that adjusts markers for a change in the
	// document. These functions cut an array of spans at a given
	// character position, returning an array of remaining chunks (or
	// undefined if nothing remains).
	function markedSpansBefore(old, startCh, isInsert) {
	  var nw;
	  if (old) { for (var i = 0; i < old.length; ++i) {
	    var span = old[i], marker = span.marker;
	    var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
	    if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
	      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
	    }
	  } }
	  return nw
	}
	function markedSpansAfter(old, endCh, isInsert) {
	  var nw;
	  if (old) { for (var i = 0; i < old.length; ++i) {
	    var span = old[i], marker = span.marker;
	    var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
	    if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
	      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
	                                            span.to == null ? null : span.to - endCh));
	    }
	  } }
	  return nw
	}
	
	// Given a change object, compute the new set of marker spans that
	// cover the line in which the change took place. Removes spans
	// entirely within the change, reconnects spans belonging to the
	// same marker that appear on both sides of the change, and cuts off
	// spans partially within the change. Returns an array of span
	// arrays with one element for each line in (after) the change.
	function stretchSpansOverChange(doc, change) {
	  if (change.full) { return null }
	  var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
	  var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
	  if (!oldFirst && !oldLast) { return null }
	
	  var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
	  // Get the spans that 'stick out' on both sides
	  var first = markedSpansBefore(oldFirst, startCh, isInsert);
	  var last = markedSpansAfter(oldLast, endCh, isInsert);
	
	  // Next, merge those two ends
	  var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
	  if (first) {
	    // Fix up .to properties of first
	    for (var i = 0; i < first.length; ++i) {
	      var span = first[i];
	      if (span.to == null) {
	        var found = getMarkedSpanFor(last, span.marker);
	        if (!found) { span.to = startCh; }
	        else if (sameLine) { span.to = found.to == null ? null : found.to + offset; }
	      }
	    }
	  }
	  if (last) {
	    // Fix up .from in last (or move them into first in case of sameLine)
	    for (var i$1 = 0; i$1 < last.length; ++i$1) {
	      var span$1 = last[i$1];
	      if (span$1.to != null) { span$1.to += offset; }
	      if (span$1.from == null) {
	        var found$1 = getMarkedSpanFor(first, span$1.marker);
	        if (!found$1) {
	          span$1.from = offset;
	          if (sameLine) { (first || (first = [])).push(span$1); }
	        }
	      } else {
	        span$1.from += offset;
	        if (sameLine) { (first || (first = [])).push(span$1); }
	      }
	    }
	  }
	  // Make sure we didn't create any zero-length spans
	  if (first) { first = clearEmptySpans(first); }
	  if (last && last != first) { last = clearEmptySpans(last); }
	
	  var newMarkers = [first];
	  if (!sameLine) {
	    // Fill gap with whole-line-spans
	    var gap = change.text.length - 2, gapMarkers;
	    if (gap > 0 && first)
	      { for (var i$2 = 0; i$2 < first.length; ++i$2)
	        { if (first[i$2].to == null)
	          { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } } }
	    for (var i$3 = 0; i$3 < gap; ++i$3)
	      { newMarkers.push(gapMarkers); }
	    newMarkers.push(last);
	  }
	  return newMarkers
	}
	
	// Remove spans that are empty and don't have a clearWhenEmpty
	// option of false.
	function clearEmptySpans(spans) {
	  for (var i = 0; i < spans.length; ++i) {
	    var span = spans[i];
	    if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
	      { spans.splice(i--, 1); }
	  }
	  if (!spans.length) { return null }
	  return spans
	}
	
	// Used to 'clip' out readOnly ranges when making a change.
	function removeReadOnlyRanges(doc, from, to) {
	  var markers = null;
	  doc.iter(from.line, to.line + 1, function (line) {
	    if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
	      var mark = line.markedSpans[i].marker;
	      if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
	        { (markers || (markers = [])).push(mark); }
	    } }
	  });
	  if (!markers) { return null }
	  var parts = [{from: from, to: to}];
	  for (var i = 0; i < markers.length; ++i) {
	    var mk = markers[i], m = mk.find(0);
	    for (var j = 0; j < parts.length; ++j) {
	      var p = parts[j];
	      if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue }
	      var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
	      if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
	        { newParts.push({from: p.from, to: m.from}); }
	      if (dto > 0 || !mk.inclusiveRight && !dto)
	        { newParts.push({from: m.to, to: p.to}); }
	      parts.splice.apply(parts, newParts);
	      j += newParts.length - 3;
	    }
	  }
	  return parts
	}
	
	// Connect or disconnect spans from a line.
	function detachMarkedSpans(line) {
	  var spans = line.markedSpans;
	  if (!spans) { return }
	  for (var i = 0; i < spans.length; ++i)
	    { spans[i].marker.detachLine(line); }
	  line.markedSpans = null;
	}
	function attachMarkedSpans(line, spans) {
	  if (!spans) { return }
	  for (var i = 0; i < spans.length; ++i)
	    { spans[i].marker.attachLine(line); }
	  line.markedSpans = spans;
	}
	
	// Helpers used when computing which overlapping collapsed span
	// counts as the larger one.
	function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
	function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
	
	// Returns a number indicating which of two overlapping collapsed
	// spans is larger (and thus includes the other). Falls back to
	// comparing ids when the spans cover exactly the same range.
	function compareCollapsedMarkers(a, b) {
	  var lenDiff = a.lines.length - b.lines.length;
	  if (lenDiff != 0) { return lenDiff }
	  var aPos = a.find(), bPos = b.find();
	  var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
	  if (fromCmp) { return -fromCmp }
	  var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
	  if (toCmp) { return toCmp }
	  return b.id - a.id
	}
	
	// Find out whether a line ends or starts in a collapsed span. If
	// so, return the marker for that span.
	function collapsedSpanAtSide(line, start) {
	  var sps = sawCollapsedSpans && line.markedSpans, found;
	  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
	    sp = sps[i];
	    if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
	        (!found || compareCollapsedMarkers(found, sp.marker) < 0))
	      { found = sp.marker; }
	  } }
	  return found
	}
	function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
	function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
	
	// Test whether there exists a collapsed span that partially
	// overlaps (covers the start or end, but not both) of a new span.
	// Such overlap is not allowed.
	function conflictingCollapsedRange(doc, lineNo$$1, from, to, marker) {
	  var line = getLine(doc, lineNo$$1);
	  var sps = sawCollapsedSpans && line.markedSpans;
	  if (sps) { for (var i = 0; i < sps.length; ++i) {
	    var sp = sps[i];
	    if (!sp.marker.collapsed) { continue }
	    var found = sp.marker.find(0);
	    var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
	    var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
	    if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue }
	    if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) ||
	        fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0))
	      { return true }
	  } }
	}
	
	// A visual line is a line as drawn on the screen. Folding, for
	// example, can cause multiple logical lines to appear on the same
	// visual line. This finds the start of the visual line that the
	// given line is part of (usually that is the line itself).
	function visualLine(line) {
	  var merged;
	  while (merged = collapsedSpanAtStart(line))
	    { line = merged.find(-1, true).line; }
	  return line
	}
	
	function visualLineEnd(line) {
	  var merged;
	  while (merged = collapsedSpanAtEnd(line))
	    { line = merged.find(1, true).line; }
	  return line
	}
	
	// Returns an array of logical lines that continue the visual line
	// started by the argument, or undefined if there are no such lines.
	function visualLineContinued(line) {
	  var merged, lines;
	  while (merged = collapsedSpanAtEnd(line)) {
	    line = merged.find(1, true).line
	    ;(lines || (lines = [])).push(line);
	  }
	  return lines
	}
	
	// Get the line number of the start of the visual line that the
	// given line number is part of.
	function visualLineNo(doc, lineN) {
	  var line = getLine(doc, lineN), vis = visualLine(line);
	  if (line == vis) { return lineN }
	  return lineNo(vis)
	}
	
	// Get the line number of the start of the next visual line after
	// the given line.
	function visualLineEndNo(doc, lineN) {
	  if (lineN > doc.lastLine()) { return lineN }
	  var line = getLine(doc, lineN), merged;
	  if (!lineIsHidden(doc, line)) { return lineN }
	  while (merged = collapsedSpanAtEnd(line))
	    { line = merged.find(1, true).line; }
	  return lineNo(line) + 1
	}
	
	// Compute whether a line is hidden. Lines count as hidden when they
	// are part of a visual line that starts with another line, or when
	// they are entirely covered by collapsed, non-widget span.
	function lineIsHidden(doc, line) {
	  var sps = sawCollapsedSpans && line.markedSpans;
	  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
	    sp = sps[i];
	    if (!sp.marker.collapsed) { continue }
	    if (sp.from == null) { return true }
	    if (sp.marker.widgetNode) { continue }
	    if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
	      { return true }
	  } }
	}
	function lineIsHiddenInner(doc, line, span) {
	  if (span.to == null) {
	    var end = span.marker.find(1, true);
	    return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker))
	  }
	  if (span.marker.inclusiveRight && span.to == line.text.length)
	    { return true }
	  for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) {
	    sp = line.markedSpans[i];
	    if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
	        (sp.to == null || sp.to != span.from) &&
	        (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
	        lineIsHiddenInner(doc, line, sp)) { return true }
	  }
	}
	
	// Find the height above the given line.
	function heightAtLine(lineObj) {
	  lineObj = visualLine(lineObj);
	
	  var h = 0, chunk = lineObj.parent;
	  for (var i = 0; i < chunk.lines.length; ++i) {
	    var line = chunk.lines[i];
	    if (line == lineObj) { break }
	    else { h += line.height; }
	  }
	  for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
	    for (var i$1 = 0; i$1 < p.children.length; ++i$1) {
	      var cur = p.children[i$1];
	      if (cur == chunk) { break }
	      else { h += cur.height; }
	    }
	  }
	  return h
	}
	
	// Compute the character length of a line, taking into account
	// collapsed ranges (see markText) that might hide parts, and join
	// other lines onto it.
	function lineLength(line) {
	  if (line.height == 0) { return 0 }
	  var len = line.text.length, merged, cur = line;
	  while (merged = collapsedSpanAtStart(cur)) {
	    var found = merged.find(0, true);
	    cur = found.from.line;
	    len += found.from.ch - found.to.ch;
	  }
	  cur = line;
	  while (merged = collapsedSpanAtEnd(cur)) {
	    var found$1 = merged.find(0, true);
	    len -= cur.text.length - found$1.from.ch;
	    cur = found$1.to.line;
	    len += cur.text.length - found$1.to.ch;
	  }
	  return len
	}
	
	// Find the longest line in the document.
	function findMaxLine(cm) {
	  var d = cm.display, doc = cm.doc;
	  d.maxLine = getLine(doc, doc.first);
	  d.maxLineLength = lineLength(d.maxLine);
	  d.maxLineChanged = true;
	  doc.iter(function (line) {
	    var len = lineLength(line);
	    if (len > d.maxLineLength) {
	      d.maxLineLength = len;
	      d.maxLine = line;
	    }
	  });
	}
	
	// BIDI HELPERS
	
	function iterateBidiSections(order, from, to, f) {
	  if (!order) { return f(from, to, "ltr") }
	  var found = false;
	  for (var i = 0; i < order.length; ++i) {
	    var part = order[i];
	    if (part.from < to && part.to > from || from == to && part.to == from) {
	      f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
	      found = true;
	    }
	  }
	  if (!found) { f(from, to, "ltr"); }
	}
	
	var bidiOther = null;
	function getBidiPartAt(order, ch, sticky) {
	  var found;
	  bidiOther = null;
	  for (var i = 0; i < order.length; ++i) {
	    var cur = order[i];
	    if (cur.from < ch && cur.to > ch) { return i }
	    if (cur.to == ch) {
	      if (cur.from != cur.to && sticky == "before") { found = i; }
	      else { bidiOther = i; }
	    }
	    if (cur.from == ch) {
	      if (cur.from != cur.to && sticky != "before") { found = i; }
	      else { bidiOther = i; }
	    }
	  }
	  return found != null ? found : bidiOther
	}
	
	// Bidirectional ordering algorithm
	// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
	// that this (partially) implements.
	
	// One-char codes used for character types:
	// L (L):   Left-to-Right
	// R (R):   Right-to-Left
	// r (AL):  Right-to-Left Arabic
	// 1 (EN):  European Number
	// + (ES):  European Number Separator
	// % (ET):  European Number Terminator
	// n (AN):  Arabic Number
	// , (CS):  Common Number Separator
	// m (NSM): Non-Spacing Mark
	// b (BN):  Boundary Neutral
	// s (B):   Paragraph Separator
	// t (S):   Segment Separator
	// w (WS):  Whitespace
	// N (ON):  Other Neutrals
	
	// Returns null if characters are ordered as they appear
	// (left-to-right), or an array of sections ({from, to, level}
	// objects) in the order in which they occur visually.
	var bidiOrdering = (function() {
	  // Character types for codepoints 0 to 0xff
	  var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
	  // Character types for codepoints 0x600 to 0x6f9
	  var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";
	  function charType(code) {
	    if (code <= 0xf7) { return lowTypes.charAt(code) }
	    else if (0x590 <= code && code <= 0x5f4) { return "R" }
	    else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) }
	    else if (0x6ee <= code && code <= 0x8ac) { return "r" }
	    else if (0x2000 <= code && code <= 0x200b) { return "w" }
	    else if (code == 0x200c) { return "b" }
	    else { return "L" }
	  }
	
	  var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
	  var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
	
	  function BidiSpan(level, from, to) {
	    this.level = level;
	    this.from = from; this.to = to;
	  }
	
	  return function(str, direction) {
	    var outerType = direction == "ltr" ? "L" : "R";
	
	    if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false }
	    var len = str.length, types = [];
	    for (var i = 0; i < len; ++i)
	      { types.push(charType(str.charCodeAt(i))); }
	
	    // W1. Examine each non-spacing mark (NSM) in the level run, and
	    // change the type of the NSM to the type of the previous
	    // character. If the NSM is at the start of the level run, it will
	    // get the type of sor.
	    for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) {
	      var type = types[i$1];
	      if (type == "m") { types[i$1] = prev; }
	      else { prev = type; }
	    }
	
	    // W2. Search backwards from each instance of a European number
	    // until the first strong type (R, L, AL, or sor) is found. If an
	    // AL is found, change the type of the European number to Arabic
	    // number.
	    // W3. Change all ALs to R.
	    for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) {
	      var type$1 = types[i$2];
	      if (type$1 == "1" && cur == "r") { types[i$2] = "n"; }
	      else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } }
	    }
	
	    // W4. A single European separator between two European numbers
	    // changes to a European number. A single common separator between
	    // two numbers of the same type changes to that type.
	    for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) {
	      var type$2 = types[i$3];
	      if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1"; }
	      else if (type$2 == "," && prev$1 == types[i$3+1] &&
	               (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; }
	      prev$1 = type$2;
	    }
	
	    // W5. A sequence of European terminators adjacent to European
	    // numbers changes to all European numbers.
	    // W6. Otherwise, separators and terminators change to Other
	    // Neutral.
	    for (var i$4 = 0; i$4 < len; ++i$4) {
	      var type$3 = types[i$4];
	      if (type$3 == ",") { types[i$4] = "N"; }
	      else if (type$3 == "%") {
	        var end = (void 0);
	        for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {}
	        var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
	        for (var j = i$4; j < end; ++j) { types[j] = replace; }
	        i$4 = end - 1;
	      }
	    }
	
	    // W7. Search backwards from each instance of a European number
	    // until the first strong type (R, L, or sor) is found. If an L is
	    // found, then change the type of the European number to L.
	    for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) {
	      var type$4 = types[i$5];
	      if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; }
	      else if (isStrong.test(type$4)) { cur$1 = type$4; }
	    }
	
	    // N1. A sequence of neutrals takes the direction of the
	    // surrounding strong text if the text on both sides has the same
	    // direction. European and Arabic numbers act as if they were R in
	    // terms of their influence on neutrals. Start-of-level-run (sor)
	    // and end-of-level-run (eor) are used at level run boundaries.
	    // N2. Any remaining neutrals take the embedding direction.
	    for (var i$6 = 0; i$6 < len; ++i$6) {
	      if (isNeutral.test(types[i$6])) {
	        var end$1 = (void 0);
	        for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {}
	        var before = (i$6 ? types[i$6-1] : outerType) == "L";
	        var after = (end$1 < len ? types[end$1] : outerType) == "L";
	        var replace$1 = before == after ? (before ? "L" : "R") : outerType;
	        for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; }
	        i$6 = end$1 - 1;
	      }
	    }
	
	    // Here we depart from the documented algorithm, in order to avoid
	    // building up an actual levels array. Since there are only three
	    // levels (0, 1, 2) in an implementation that doesn't take
	    // explicit embedding into account, we can build up the order on
	    // the fly, without following the level-based algorithm.
	    var order = [], m;
	    for (var i$7 = 0; i$7 < len;) {
	      if (countsAsLeft.test(types[i$7])) {
	        var start = i$7;
	        for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
	        order.push(new BidiSpan(0, start, i$7));
	      } else {
	        var pos = i$7, at = order.length;
	        for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
	        for (var j$2 = pos; j$2 < i$7;) {
	          if (countsAsNum.test(types[j$2])) {
	            if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
	            var nstart = j$2;
	            for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
	            order.splice(at, 0, new BidiSpan(2, nstart, j$2));
	            pos = j$2;
	          } else { ++j$2; }
	        }
	        if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); }
	      }
	    }
	    if (order[0].level == 1 && (m = str.match(/^\s+/))) {
	      order[0].from = m[0].length;
	      order.unshift(new BidiSpan(0, 0, m[0].length));
	    }
	    if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
	      lst(order).to -= m[0].length;
	      order.push(new BidiSpan(0, len - m[0].length, len));
	    }
	
	    return direction == "rtl" ? order.reverse() : order
	  }
	})();
	
	// Get the bidi ordering for the given line (and cache it). Returns
	// false for lines that are fully left-to-right, and an array of
	// BidiSpan objects otherwise.
	function getOrder(line, direction) {
	  var order = line.order;
	  if (order == null) { order = line.order = bidiOrdering(line.text, direction); }
	  return order
	}
	
	function moveCharLogically(line, ch, dir) {
	  var target = skipExtendingChars(line.text, ch + dir, dir);
	  return target < 0 || target > line.text.length ? null : target
	}
	
	function moveLogically(line, start, dir) {
	  var ch = moveCharLogically(line, start.ch, dir);
	  return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
	}
	
	function endOfLine(visually, cm, lineObj, lineNo, dir) {
	  if (visually) {
	    var order = getOrder(lineObj, cm.doc.direction);
	    if (order) {
	      var part = dir < 0 ? lst(order) : order[0];
	      var moveInStorageOrder = (dir < 0) == (part.level == 1);
	      var sticky = moveInStorageOrder ? "after" : "before";
	      var ch;
	      // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
	      // it could be that the last bidi part is not on the last visual line,
	      // since visual lines contain content order-consecutive chunks.
	      // Thus, in rtl, we are looking for the first (content-order) character
	      // in the rtl chunk that is on the last line (that is, the same line
	      // as the last (content-order) character).
	      if (part.level > 0) {
	        var prep = prepareMeasureForLine(cm, lineObj);
	        ch = dir < 0 ? lineObj.text.length - 1 : 0;
	        var targetTop = measureCharPrepared(cm, prep, ch).top;
	        ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch);
	        if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); }
	      } else { ch = dir < 0 ? part.to : part.from; }
	      return new Pos(lineNo, ch, sticky)
	    }
	  }
	  return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
	}
	
	function moveVisually(cm, line, start, dir) {
	  var bidi = getOrder(line, cm.doc.direction);
	  if (!bidi) { return moveLogically(line, start, dir) }
	  if (start.ch >= line.text.length) {
	    start.ch = line.text.length;
	    start.sticky = "before";
	  } else if (start.ch <= 0) {
	    start.ch = 0;
	    start.sticky = "after";
	  }
	  var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos];
	  if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
	    // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
	    // nothing interesting happens.
	    return moveLogically(line, start, dir)
	  }
	
	  var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); };
	  var prep;
	  var getWrappedLineExtent = function (ch) {
	    if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
	    prep = prep || prepareMeasureForLine(cm, line);
	    return wrappedLineExtentChar(cm, line, prep, ch)
	  };
	  var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch);
	
	  if (cm.doc.direction == "rtl" || part.level == 1) {
	    var moveInStorageOrder = (part.level == 1) == (dir < 0);
	    var ch = mv(start, moveInStorageOrder ? 1 : -1);
	    if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
	      // Case 2: We move within an rtl part or in an rtl editor on the same visual line
	      var sticky = moveInStorageOrder ? "before" : "after";
	      return new Pos(start.line, ch, sticky)
	    }
	  }
	
	  // Case 3: Could not move within this bidi part in this visual line, so leave
	  // the current bidi part
	
	  var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
	    var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
	      ? new Pos(start.line, mv(ch, 1), "before")
	      : new Pos(start.line, ch, "after"); };
	
	    for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
	      var part = bidi[partPos];
	      var moveInStorageOrder = (dir > 0) == (part.level != 1);
	      var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1);
	      if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
	      ch = moveInStorageOrder ? part.from : mv(part.to, -1);
	      if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
	    }
	  };
	
	  // Case 3a: Look for other bidi parts on the same visual line
	  var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent);
	  if (res) { return res }
	
	  // Case 3b: Look for other bidi parts on the next visual line
	  var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1);
	  if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
	    res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh));
	    if (res) { return res }
	  }
	
	  // Case 4: Nowhere to move
	  return null
	}
	
	// EVENT HANDLING
	
	// Lightweight event framework. on/off also work on DOM nodes,
	// registering native DOM handlers.
	
	var noHandlers = [];
	
	var on = function(emitter, type, f) {
	  if (emitter.addEventListener) {
	    emitter.addEventListener(type, f, false);
	  } else if (emitter.attachEvent) {
	    emitter.attachEvent("on" + type, f);
	  } else {
	    var map$$1 = emitter._handlers || (emitter._handlers = {});
	    map$$1[type] = (map$$1[type] || noHandlers).concat(f);
	  }
	};
	
	function getHandlers(emitter, type) {
	  return emitter._handlers && emitter._handlers[type] || noHandlers
	}
	
	function off(emitter, type, f) {
	  if (emitter.removeEventListener) {
	    emitter.removeEventListener(type, f, false);
	  } else if (emitter.detachEvent) {
	    emitter.detachEvent("on" + type, f);
	  } else {
	    var map$$1 = emitter._handlers, arr = map$$1 && map$$1[type];
	    if (arr) {
	      var index = indexOf(arr, f);
	      if (index > -1)
	        { map$$1[type] = arr.slice(0, index).concat(arr.slice(index + 1)); }
	    }
	  }
	}
	
	function signal(emitter, type /*, values...*/) {
	  var handlers = getHandlers(emitter, type);
	  if (!handlers.length) { return }
	  var args = Array.prototype.slice.call(arguments, 2);
	  for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); }
	}
	
	// The DOM events that CodeMirror handles can be overridden by
	// registering a (non-DOM) handler on the editor for the event name,
	// and preventDefault-ing the event in that handler.
	function signalDOMEvent(cm, e, override) {
	  if (typeof e == "string")
	    { e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; }
	  signal(cm, override || e.type, cm, e);
	  return e_defaultPrevented(e) || e.codemirrorIgnore
	}
	
	function signalCursorActivity(cm) {
	  var arr = cm._handlers && cm._handlers.cursorActivity;
	  if (!arr) { return }
	  var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
	  for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1)
	    { set.push(arr[i]); } }
	}
	
	function hasHandler(emitter, type) {
	  return getHandlers(emitter, type).length > 0
	}
	
	// Add on and off methods to a constructor's prototype, to make
	// registering events on such objects more convenient.
	function eventMixin(ctor) {
	  ctor.prototype.on = function(type, f) {on(this, type, f);};
	  ctor.prototype.off = function(type, f) {off(this, type, f);};
	}
	
	// Due to the fact that we still support jurassic IE versions, some
	// compatibility wrappers are needed.
	
	function e_preventDefault(e) {
	  if (e.preventDefault) { e.preventDefault(); }
	  else { e.returnValue = false; }
	}
	function e_stopPropagation(e) {
	  if (e.stopPropagation) { e.stopPropagation(); }
	  else { e.cancelBubble = true; }
	}
	function e_defaultPrevented(e) {
	  return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false
	}
	function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
	
	function e_target(e) {return e.target || e.srcElement}
	function e_button(e) {
	  var b = e.which;
	  if (b == null) {
	    if (e.button & 1) { b = 1; }
	    else if (e.button & 2) { b = 3; }
	    else if (e.button & 4) { b = 2; }
	  }
	  if (mac && e.ctrlKey && b == 1) { b = 3; }
	  return b
	}
	
	// Detect drag-and-drop
	var dragAndDrop = function() {
	  // There is *some* kind of drag-and-drop support in IE6-8, but I
	  // couldn't get it to work yet.
	  if (ie && ie_version < 9) { return false }
	  var div = elt('div');
	  return "draggable" in div || "dragDrop" in div
	}();
	
	var zwspSupported;
	function zeroWidthElement(measure) {
	  if (zwspSupported == null) {
	    var test = elt("span", "\u200b");
	    removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
	    if (measure.firstChild.offsetHeight != 0)
	      { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); }
	  }
	  var node = zwspSupported ? elt("span", "\u200b") :
	    elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
	  node.setAttribute("cm-text", "");
	  return node
	}
	
	// Feature-detect IE's crummy client rect reporting for bidi text
	var badBidiRects;
	function hasBadBidiRects(measure) {
	  if (badBidiRects != null) { return badBidiRects }
	  var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
	  var r0 = range(txt, 0, 1).getBoundingClientRect();
	  var r1 = range(txt, 1, 2).getBoundingClientRect();
	  removeChildren(measure);
	  if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780)
	  return badBidiRects = (r1.right - r0.right < 3)
	}
	
	// See if "".split is the broken IE version, if so, provide an
	// alternative way to split lines.
	var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) {
	  var pos = 0, result = [], l = string.length;
	  while (pos <= l) {
	    var nl = string.indexOf("\n", pos);
	    if (nl == -1) { nl = string.length; }
	    var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
	    var rt = line.indexOf("\r");
	    if (rt != -1) {
	      result.push(line.slice(0, rt));
	      pos += rt + 1;
	    } else {
	      result.push(line);
	      pos = nl + 1;
	    }
	  }
	  return result
	} : function (string) { return string.split(/\r\n?|\n/); };
	
	var hasSelection = window.getSelection ? function (te) {
	  try { return te.selectionStart != te.selectionEnd }
	  catch(e) { return false }
	} : function (te) {
	  var range$$1;
	  try {range$$1 = te.ownerDocument.selection.createRange();}
	  catch(e) {}
	  if (!range$$1 || range$$1.parentElement() != te) { return false }
	  return range$$1.compareEndPoints("StartToEnd", range$$1) != 0
	};
	
	var hasCopyEvent = (function () {
	  var e = elt("div");
	  if ("oncopy" in e) { return true }
	  e.setAttribute("oncopy", "return;");
	  return typeof e.oncopy == "function"
	})();
	
	var badZoomedRects = null;
	function hasBadZoomedRects(measure) {
	  if (badZoomedRects != null) { return badZoomedRects }
	  var node = removeChildrenAndAdd(measure, elt("span", "x"));
	  var normal = node.getBoundingClientRect();
	  var fromRange = range(node, 0, 1).getBoundingClientRect();
	  return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1
	}
	
	// Known modes, by name and by MIME
	var modes = {};
	var mimeModes = {};
	
	// Extra arguments are stored as the mode's dependencies, which is
	// used by (legacy) mechanisms like loadmode.js to automatically
	// load a mode. (Preferred mechanism is the require/define calls.)
	function defineMode(name, mode) {
	  if (arguments.length > 2)
	    { mode.dependencies = Array.prototype.slice.call(arguments, 2); }
	  modes[name] = mode;
	}
	
	function defineMIME(mime, spec) {
	  mimeModes[mime] = spec;
	}
	
	// Given a MIME type, a {name, ...options} config object, or a name
	// string, return a mode config object.
	function resolveMode(spec) {
	  if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
	    spec = mimeModes[spec];
	  } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
	    var found = mimeModes[spec.name];
	    if (typeof found == "string") { found = {name: found}; }
	    spec = createObj(found, spec);
	    spec.name = found.name;
	  } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
	    return resolveMode("application/xml")
	  } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
	    return resolveMode("application/json")
	  }
	  if (typeof spec == "string") { return {name: spec} }
	  else { return spec || {name: "null"} }
	}
	
	// Given a mode spec (anything that resolveMode accepts), find and
	// initialize an actual mode object.
	function getMode(options, spec) {
	  spec = resolveMode(spec);
	  var mfactory = modes[spec.name];
	  if (!mfactory) { return getMode(options, "text/plain") }
	  var modeObj = mfactory(options, spec);
	  if (modeExtensions.hasOwnProperty(spec.name)) {
	    var exts = modeExtensions[spec.name];
	    for (var prop in exts) {
	      if (!exts.hasOwnProperty(prop)) { continue }
	      if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
	      modeObj[prop] = exts[prop];
	    }
	  }
	  modeObj.name = spec.name;
	  if (spec.helperType) { modeObj.helperType = spec.helperType; }
	  if (spec.modeProps) { for (var prop$1 in spec.modeProps)
	    { modeObj[prop$1] = spec.modeProps[prop$1]; } }
	
	  return modeObj
	}
	
	// This can be used to attach properties to mode objects from
	// outside the actual mode definition.
	var modeExtensions = {};
	function extendMode(mode, properties) {
	  var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
	  copyObj(properties, exts);
	}
	
	function copyState(mode, state) {
	  if (state === true) { return state }
	  if (mode.copyState) { return mode.copyState(state) }
	  var nstate = {};
	  for (var n in state) {
	    var val = state[n];
	    if (val instanceof Array) { val = val.concat([]); }
	    nstate[n] = val;
	  }
	  return nstate
	}
	
	// Given a mode and a state (for that mode), find the inner mode and
	// state at the position that the state refers to.
	function innerMode(mode, state) {
	  var info;
	  while (mode.innerMode) {
	    info = mode.innerMode(state);
	    if (!info || info.mode == mode) { break }
	    state = info.state;
	    mode = info.mode;
	  }
	  return info || {mode: mode, state: state}
	}
	
	function startState(mode, a1, a2) {
	  return mode.startState ? mode.startState(a1, a2) : true
	}
	
	// STRING STREAM
	
	// Fed to the mode parsers, provides helper functions to make
	// parsers more succinct.
	
	var StringStream = function(string, tabSize, lineOracle) {
	  this.pos = this.start = 0;
	  this.string = string;
	  this.tabSize = tabSize || 8;
	  this.lastColumnPos = this.lastColumnValue = 0;
	  this.lineStart = 0;
	  this.lineOracle = lineOracle;
	};
	
	StringStream.prototype.eol = function () {return this.pos >= this.string.length};
	StringStream.prototype.sol = function () {return this.pos == this.lineStart};
	StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
	StringStream.prototype.next = function () {
	  if (this.pos < this.string.length)
	    { return this.string.charAt(this.pos++) }
	};
	StringStream.prototype.eat = function (match) {
	  var ch = this.string.charAt(this.pos);
	  var ok;
	  if (typeof match == "string") { ok = ch == match; }
	  else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
	  if (ok) {++this.pos; return ch}
	};
	StringStream.prototype.eatWhile = function (match) {
	  var start = this.pos;
	  while (this.eat(match)){}
	  return this.pos > start
	};
	StringStream.prototype.eatSpace = function () {
	    var this$1 = this;
	
	  var start = this.pos;
	  while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos; }
	  return this.pos > start
	};
	StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
	StringStream.prototype.skipTo = function (ch) {
	  var found = this.string.indexOf(ch, this.pos);
	  if (found > -1) {this.pos = found; return true}
	};
	StringStream.prototype.backUp = function (n) {this.pos -= n;};
	StringStream.prototype.column = function () {
	  if (this.lastColumnPos < this.start) {
	    this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
	    this.lastColumnPos = this.start;
	  }
	  return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
	};
	StringStream.prototype.indentation = function () {
	  return countColumn(this.string, null, this.tabSize) -
	    (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
	};
	StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
	  if (typeof pattern == "string") {
	    var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
	    var substr = this.string.substr(this.pos, pattern.length);
	    if (cased(substr) == cased(pattern)) {
	      if (consume !== false) { this.pos += pattern.length; }
	      return true
	    }
	  } else {
	    var match = this.string.slice(this.pos).match(pattern);
	    if (match && match.index > 0) { return null }
	    if (match && consume !== false) { this.pos += match[0].length; }
	    return match
	  }
	};
	StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
	StringStream.prototype.hideFirstChars = function (n, inner) {
	  this.lineStart += n;
	  try { return inner() }
	  finally { this.lineStart -= n; }
	};
	StringStream.prototype.lookAhead = function (n) {
	  var oracle = this.lineOracle;
	  return oracle && oracle.lookAhead(n)
	};
	
	var SavedContext = function(state, lookAhead) {
	  this.state = state;
	  this.lookAhead = lookAhead;
	};
	
	var Context = function(doc, state, line, lookAhead) {
	  this.state = state;
	  this.doc = doc;
	  this.line = line;
	  this.maxLookAhead = lookAhead || 0;
	};
	
	Context.prototype.lookAhead = function (n) {
	  var line = this.doc.getLine(this.line + n);
	  if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n; }
	  return line
	};
	
	Context.prototype.nextLine = function () {
	  this.line++;
	  if (this.maxLookAhead > 0) { this.maxLookAhead--; }
	};
	
	Context.fromSaved = function (doc, saved, line) {
	  if (saved instanceof SavedContext)
	    { return new Context(doc, copyState(doc.mode, saved.saved), line, saved.lookAhead) }
	  else
	    { return new Context(doc, copyState(doc.mode, saved), line) }
	};
	
	Context.prototype.save = function (copy) {
	  var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state;
	  return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state
	};
	
	
	// Compute a style array (an array starting with a mode generation
	// -- for invalidation -- followed by pairs of end positions and
	// style strings), which is used to highlight the tokens on the
	// line.
	function highlightLine(cm, line, context, forceToEnd) {
	  // A styles array always starts with a number identifying the
	  // mode/overlays that it is based on (for easy invalidation).
	  var st = [cm.state.modeGen], lineClasses = {};
	  // Compute the base array of styles
	  runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); },
	          lineClasses, forceToEnd);
	  var state = context.state;
	
	  // Run overlays, adjust style array.
	  var loop = function ( o ) {
	    var overlay = cm.state.overlays[o], i = 1, at = 0;
	    context.state = true;
	    runMode(cm, line.text, overlay.mode, context, function (end, style) {
	      var start = i;
	      // Ensure there's a token end at the current position, and that i points at it
	      while (at < end) {
	        var i_end = st[i];
	        if (i_end > end)
	          { st.splice(i, 1, end, st[i+1], i_end); }
	        i += 2;
	        at = Math.min(end, i_end);
	      }
	      if (!style) { return }
	      if (overlay.opaque) {
	        st.splice(start, i - start, end, "overlay " + style);
	        i = start + 2;
	      } else {
	        for (; start < i; start += 2) {
	          var cur = st[start+1];
	          st[start+1] = (cur ? cur + " " : "") + "overlay " + style;
	        }
	      }
	    }, lineClasses);
	  };
	
	  for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
	  context.state = state;
	
	  return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
	}
	
	function getLineStyles(cm, line, updateFrontier) {
	  if (!line.styles || line.styles[0] != cm.state.modeGen) {
	    var context = getContextBefore(cm, lineNo(line));
	    var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state);
	    var result = highlightLine(cm, line, context);
	    if (resetState) { context.state = resetState; }
	    line.stateAfter = context.save(!resetState);
	    line.styles = result.styles;
	    if (result.classes) { line.styleClasses = result.classes; }
	    else if (line.styleClasses) { line.styleClasses = null; }
	    if (updateFrontier === cm.doc.highlightFrontier)
	      { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier); }
	  }
	  return line.styles
	}
	
	function getContextBefore(cm, n, precise) {
	  var doc = cm.doc, display = cm.display;
	  if (!doc.mode.startState) { return new Context(doc, true, n) }
	  var start = findStartLine(cm, n, precise);
	  var saved = start > doc.first && getLine(doc, start - 1).stateAfter;
	  var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start);
	
	  doc.iter(start, n, function (line) {
	    processLine(cm, line.text, context);
	    var pos = context.line;
	    line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null;
	    context.nextLine();
	  });
	  if (precise) { doc.modeFrontier = context.line; }
	  return context
	}
	
	// Lightweight form of highlight -- proceed over this line and
	// update state, but don't save a style array. Used for lines that
	// aren't currently visible.
	function processLine(cm, text, context, startAt) {
	  var mode = cm.doc.mode;
	  var stream = new StringStream(text, cm.options.tabSize, context);
	  stream.start = stream.pos = startAt || 0;
	  if (text == "") { callBlankLine(mode, context.state); }
	  while (!stream.eol()) {
	    readToken(mode, stream, context.state);
	    stream.start = stream.pos;
	  }
	}
	
	function callBlankLine(mode, state) {
	  if (mode.blankLine) { return mode.blankLine(state) }
	  if (!mode.innerMode) { return }
	  var inner = innerMode(mode, state);
	  if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }
	}
	
	function readToken(mode, stream, state, inner) {
	  for (var i = 0; i < 10; i++) {
	    if (inner) { inner[0] = innerMode(mode, state).mode; }
	    var style = mode.token(stream, state);
	    if (stream.pos > stream.start) { return style }
	  }
	  throw new Error("Mode " + mode.name + " failed to advance stream.")
	}
	
	var Token = function(stream, type, state) {
	  this.start = stream.start; this.end = stream.pos;
	  this.string = stream.current();
	  this.type = type || null;
	  this.state = state;
	};
	
	// Utility for getTokenAt and getLineTokens
	function takeToken(cm, pos, precise, asArray) {
	  var doc = cm.doc, mode = doc.mode, style;
	  pos = clipPos(doc, pos);
	  var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise);
	  var stream = new StringStream(line.text, cm.options.tabSize, context), tokens;
	  if (asArray) { tokens = []; }
	  while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
	    stream.start = stream.pos;
	    style = readToken(mode, stream, context.state);
	    if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))); }
	  }
	  return asArray ? tokens : new Token(stream, style, context.state)
	}
	
	function extractLineClasses(type, output) {
	  if (type) { for (;;) {
	    var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
	    if (!lineClass) { break }
	    type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
	    var prop = lineClass[1] ? "bgClass" : "textClass";
	    if (output[prop] == null)
	      { output[prop] = lineClass[2]; }
	    else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
	      { output[prop] += " " + lineClass[2]; }
	  } }
	  return type
	}
	
	// Run the given mode's parser over a line, calling f for each token.
	function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
	  var flattenSpans = mode.flattenSpans;
	  if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; }
	  var curStart = 0, curStyle = null;
	  var stream = new StringStream(text, cm.options.tabSize, context), style;
	  var inner = cm.options.addModeClass && [null];
	  if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses); }
	  while (!stream.eol()) {
	    if (stream.pos > cm.options.maxHighlightLength) {
	      flattenSpans = false;
	      if (forceToEnd) { processLine(cm, text, context, stream.pos); }
	      stream.pos = text.length;
	      style = null;
	    } else {
	      style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses);
	    }
	    if (inner) {
	      var mName = inner[0].name;
	      if (mName) { style = "m-" + (style ? mName + " " + style : mName); }
	    }
	    if (!flattenSpans || curStyle != style) {
	      while (curStart < stream.start) {
	        curStart = Math.min(stream.start, curStart + 5000);
	        f(curStart, curStyle);
	      }
	      curStyle = style;
	    }
	    stream.start = stream.pos;
	  }
	  while (curStart < stream.pos) {
	    // Webkit seems to refuse to render text nodes longer than 57444
	    // characters, and returns inaccurate measurements in nodes
	    // starting around 5000 chars.
	    var pos = Math.min(stream.pos, curStart + 5000);
	    f(pos, curStyle);
	    curStart = pos;
	  }
	}
	
	// Finds the line to start with when starting a parse. Tries to
	// find a line with a stateAfter, so that it can start with a
	// valid state. If that fails, it returns the line with the
	// smallest indentation, which tends to need the least context to
	// parse correctly.
	function findStartLine(cm, n, precise) {
	  var minindent, minline, doc = cm.doc;
	  var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
	  for (var search = n; search > lim; --search) {
	    if (search <= doc.first) { return doc.first }
	    var line = getLine(doc, search - 1), after = line.stateAfter;
	    if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier))
	      { return search }
	    var indented = countColumn(line.text, null, cm.options.tabSize);
	    if (minline == null || minindent > indented) {
	      minline = search - 1;
	      minindent = indented;
	    }
	  }
	  return minline
	}
	
	function retreatFrontier(doc, n) {
	  doc.modeFrontier = Math.min(doc.modeFrontier, n);
	  if (doc.highlightFrontier < n - 10) { return }
	  var start = doc.first;
	  for (var line = n - 1; line > start; line--) {
	    var saved = getLine(doc, line).stateAfter;
	    // change is on 3
	    // state on line 1 looked ahead 2 -- so saw 3
	    // test 1 + 2 < 3 should cover this
	    if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) {
	      start = line + 1;
	      break
	    }
	  }
	  doc.highlightFrontier = Math.min(doc.highlightFrontier, start);
	}
	
	// LINE DATA STRUCTURE
	
	// Line objects. These hold state related to a line, including
	// highlighting info (the styles array).
	var Line = function(text, markedSpans, estimateHeight) {
	  this.text = text;
	  attachMarkedSpans(this, markedSpans);
	  this.height = estimateHeight ? estimateHeight(this) : 1;
	};
	
	Line.prototype.lineNo = function () { return lineNo(this) };
	eventMixin(Line);
	
	// Change the content (text, markers) of a line. Automatically
	// invalidates cached information and tries to re-estimate the
	// line's height.
	function updateLine(line, text, markedSpans, estimateHeight) {
	  line.text = text;
	  if (line.stateAfter) { line.stateAfter = null; }
	  if (line.styles) { line.styles = null; }
	  if (line.order != null) { line.order = null; }
	  detachMarkedSpans(line);
	  attachMarkedSpans(line, markedSpans);
	  var estHeight = estimateHeight ? estimateHeight(line) : 1;
	  if (estHeight != line.height) { updateLineHeight(line, estHeight); }
	}
	
	// Detach a line from the document tree and its markers.
	function cleanUpLine(line) {
	  line.parent = null;
	  detachMarkedSpans(line);
	}
	
	// Convert a style as returned by a mode (either null, or a string
	// containing one or more styles) to a CSS style. This is cached,
	// and also looks for line-wide styles.
	var styleToClassCache = {};
	var styleToClassCacheWithMode = {};
	function interpretTokenStyle(style, options) {
	  if (!style || /^\s*$/.test(style)) { return null }
	  var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
	  return cache[style] ||
	    (cache[style] = style.replace(/\S+/g, "cm-$&"))
	}
	
	// Render the DOM representation of the text of a line. Also builds
	// up a 'line map', which points at the DOM nodes that represent
	// specific stretches of text, and is used by the measuring code.
	// The returned object contains the DOM node, this map, and
	// information about line-wide styles that were set by the mode.
	function buildLineContent(cm, lineView) {
	  // The padding-right forces the element to have a 'border', which
	  // is needed on Webkit to be able to get line-level bounding
	  // rectangles for it (in measureChar).
	  var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null);
	  var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
	                 col: 0, pos: 0, cm: cm,
	                 trailingSpace: false,
	                 splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
	  lineView.measure = {};
	
	  // Iterate over the logical lines that make up this visual line.
	  for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
	    var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0);
	    builder.pos = 0;
	    builder.addToken = buildToken;
	    // Optionally wire in some hacks into the token-rendering
	    // algorithm, to deal with browser quirks.
	    if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction)))
	      { builder.addToken = buildTokenBadBidi(builder.addToken, order); }
	    builder.map = [];
	    var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
	    insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
	    if (line.styleClasses) {
	      if (line.styleClasses.bgClass)
	        { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); }
	      if (line.styleClasses.textClass)
	        { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); }
	    }
	
	    // Ensure at least a single node is present, for measuring.
	    if (builder.map.length == 0)
	      { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); }
	
	    // Store the map and a cache object for the current logical line
	    if (i == 0) {
	      lineView.measure.map = builder.map;
	      lineView.measure.cache = {};
	    } else {
	      (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map)
	      ;(lineView.measure.caches || (lineView.measure.caches = [])).push({});
	    }
	  }
	
	  // See issue #2901
	  if (webkit) {
	    var last = builder.content.lastChild;
	    if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab")))
	      { builder.content.className = "cm-tab-wrap-hack"; }
	  }
	
	  signal(cm, "renderLine", cm, lineView.line, builder.pre);
	  if (builder.pre.className)
	    { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); }
	
	  return builder
	}
	
	function defaultSpecialCharPlaceholder(ch) {
	  var token = elt("span", "\u2022", "cm-invalidchar");
	  token.title = "\\u" + ch.charCodeAt(0).toString(16);
	  token.setAttribute("aria-label", token.title);
	  return token
	}
	
	// Build up the DOM representation for a single token, and add it to
	// the line map. Takes care to render special characters separately.
	function buildToken(builder, text, style, startStyle, endStyle, title, css) {
	  if (!text) { return }
	  var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text;
	  var special = builder.cm.state.specialChars, mustWrap = false;
	  var content;
	  if (!special.test(text)) {
	    builder.col += text.length;
	    content = document.createTextNode(displayText);
	    builder.map.push(builder.pos, builder.pos + text.length, content);
	    if (ie && ie_version < 9) { mustWrap = true; }
	    builder.pos += text.length;
	  } else {
	    content = document.createDocumentFragment();
	    var pos = 0;
	    while (true) {
	      special.lastIndex = pos;
	      var m = special.exec(text);
	      var skipped = m ? m.index - pos : text.length - pos;
	      if (skipped) {
	        var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
	        if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); }
	        else { content.appendChild(txt); }
	        builder.map.push(builder.pos, builder.pos + skipped, txt);
	        builder.col += skipped;
	        builder.pos += skipped;
	      }
	      if (!m) { break }
	      pos += skipped + 1;
	      var txt$1 = (void 0);
	      if (m[0] == "\t") {
	        var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
	        txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
	        txt$1.setAttribute("role", "presentation");
	        txt$1.setAttribute("cm-text", "\t");
	        builder.col += tabWidth;
	      } else if (m[0] == "\r" || m[0] == "\n") {
	        txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
	        txt$1.setAttribute("cm-text", m[0]);
	        builder.col += 1;
	      } else {
	        txt$1 = builder.cm.options.specialCharPlaceholder(m[0]);
	        txt$1.setAttribute("cm-text", m[0]);
	        if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); }
	        else { content.appendChild(txt$1); }
	        builder.col += 1;
	      }
	      builder.map.push(builder.pos, builder.pos + 1, txt$1);
	      builder.pos++;
	    }
	  }
	  builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32;
	  if (style || startStyle || endStyle || mustWrap || css) {
	    var fullStyle = style || "";
	    if (startStyle) { fullStyle += startStyle; }
	    if (endStyle) { fullStyle += endStyle; }
	    var token = elt("span", [content], fullStyle, css);
	    if (title) { token.title = title; }
	    return builder.content.appendChild(token)
	  }
	  builder.content.appendChild(content);
	}
	
	function splitSpaces(text, trailingBefore) {
	  if (text.length > 1 && !/  /.test(text)) { return text }
	  var spaceBefore = trailingBefore, result = "";
	  for (var i = 0; i < text.length; i++) {
	    var ch = text.charAt(i);
	    if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32))
	      { ch = "\u00a0"; }
	    result += ch;
	    spaceBefore = ch == " ";
	  }
	  return result
	}
	
	// Work around nonsense dimensions being reported for stretches of
	// right-to-left text.
	function buildTokenBadBidi(inner, order) {
	  return function (builder, text, style, startStyle, endStyle, title, css) {
	    style = style ? style + " cm-force-border" : "cm-force-border";
	    var start = builder.pos, end = start + text.length;
	    for (;;) {
	      // Find the part that overlaps with the start of this text
	      var part = (void 0);
	      for (var i = 0; i < order.length; i++) {
	        part = order[i];
	        if (part.to > start && part.from <= start) { break }
	      }
	      if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) }
	      inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css);
	      startStyle = null;
	      text = text.slice(part.to - start);
	      start = part.to;
	    }
	  }
	}
	
	function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
	  var widget = !ignoreWidget && marker.widgetNode;
	  if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); }
	  if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
	    if (!widget)
	      { widget = builder.content.appendChild(document.createElement("span")); }
	    widget.setAttribute("cm-marker", marker.id);
	  }
	  if (widget) {
	    builder.cm.display.input.setUneditable(widget);
	    builder.content.appendChild(widget);
	  }
	  builder.pos += size;
	  builder.trailingSpace = false;
	}
	
	// Outputs a number of spans to make up a line, taking highlighting
	// and marked text into account.
	function insertLineContent(line, builder, styles) {
	  var spans = line.markedSpans, allText = line.text, at = 0;
	  if (!spans) {
	    for (var i$1 = 1; i$1 < styles.length; i$1+=2)
	      { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)); }
	    return
	  }
	
	  var len = allText.length, pos = 0, i = 1, text = "", style, css;
	  var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
	  for (;;) {
	    if (nextChange == pos) { // Update current marker set
	      spanStyle = spanEndStyle = spanStartStyle = title = css = "";
	      collapsed = null; nextChange = Infinity;
	      var foundBookmarks = [], endStyles = (void 0);
	      for (var j = 0; j < spans.length; ++j) {
	        var sp = spans[j], m = sp.marker;
	        if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
	          foundBookmarks.push(m);
	        } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
	          if (sp.to != null && sp.to != pos && nextChange > sp.to) {
	            nextChange = sp.to;
	            spanEndStyle = "";
	          }
	          if (m.className) { spanStyle += " " + m.className; }
	          if (m.css) { css = (css ? css + ";" : "") + m.css; }
	          if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; }
	          if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); }
	          if (m.title && !title) { title = m.title; }
	          if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
	            { collapsed = sp; }
	        } else if (sp.from > pos && nextChange > sp.from) {
	          nextChange = sp.from;
	        }
	      }
	      if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2)
	        { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } }
	
	      if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2)
	        { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } }
	      if (collapsed && (collapsed.from || 0) == pos) {
	        buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
	                           collapsed.marker, collapsed.from == null);
	        if (collapsed.to == null) { return }
	        if (collapsed.to == pos) { collapsed = false; }
	      }
	    }
	    if (pos >= len) { break }
	
	    var upto = Math.min(len, nextChange);
	    while (true) {
	      if (text) {
	        var end = pos + text.length;
	        if (!collapsed) {
	          var tokenText = end > upto ? text.slice(0, upto - pos) : text;
	          builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
	                           spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
	        }
	        if (end >= upto) {text = text.slice(upto - pos); pos = upto; break}
	        pos = end;
	        spanStartStyle = "";
	      }
	      text = allText.slice(at, at = styles[i++]);
	      style = interpretTokenStyle(styles[i++], builder.cm.options);
	    }
	  }
	}
	
	
	// These objects are used to represent the visible (currently drawn)
	// part of the document. A LineView may correspond to multiple
	// logical lines, if those are connected by collapsed ranges.
	function LineView(doc, line, lineN) {
	  // The starting line
	  this.line = line;
	  // Continuing lines, if any
	  this.rest = visualLineContinued(line);
	  // Number of logical lines in this visual line
	  this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
	  this.node = this.text = null;
	  this.hidden = lineIsHidden(doc, line);
	}
	
	// Create a range of LineView objects for the given lines.
	function buildViewArray(cm, from, to) {
	  var array = [], nextPos;
	  for (var pos = from; pos < to; pos = nextPos) {
	    var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
	    nextPos = pos + view.size;
	    array.push(view);
	  }
	  return array
	}
	
	var operationGroup = null;
	
	function pushOperation(op) {
	  if (operationGroup) {
	    operationGroup.ops.push(op);
	  } else {
	    op.ownsGroup = operationGroup = {
	      ops: [op],
	      delayedCallbacks: []
	    };
	  }
	}
	
	function fireCallbacksForOps(group) {
	  // Calls delayed callbacks and cursorActivity handlers until no
	  // new ones appear
	  var callbacks = group.delayedCallbacks, i = 0;
	  do {
	    for (; i < callbacks.length; i++)
	      { callbacks[i].call(null); }
	    for (var j = 0; j < group.ops.length; j++) {
	      var op = group.ops[j];
	      if (op.cursorActivityHandlers)
	        { while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
	          { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } }
	    }
	  } while (i < callbacks.length)
	}
	
	function finishOperation(op, endCb) {
	  var group = op.ownsGroup;
	  if (!group) { return }
	
	  try { fireCallbacksForOps(group); }
	  finally {
	    operationGroup = null;
	    endCb(group);
	  }
	}
	
	var orphanDelayedCallbacks = null;
	
	// Often, we want to signal events at a point where we are in the
	// middle of some work, but don't want the handler to start calling
	// other methods on the editor, which might be in an inconsistent
	// state or simply not expect any other events to happen.
	// signalLater looks whether there are any handlers, and schedules
	// them to be executed when the last operation ends, or, if no
	// operation is active, when a timeout fires.
	function signalLater(emitter, type /*, values...*/) {
	  var arr = getHandlers(emitter, type);
	  if (!arr.length) { return }
	  var args = Array.prototype.slice.call(arguments, 2), list;
	  if (operationGroup) {
	    list = operationGroup.delayedCallbacks;
	  } else if (orphanDelayedCallbacks) {
	    list = orphanDelayedCallbacks;
	  } else {
	    list = orphanDelayedCallbacks = [];
	    setTimeout(fireOrphanDelayed, 0);
	  }
	  var loop = function ( i ) {
	    list.push(function () { return arr[i].apply(null, args); });
	  };
	
	  for (var i = 0; i < arr.length; ++i)
	    loop( i );
	}
	
	function fireOrphanDelayed() {
	  var delayed = orphanDelayedCallbacks;
	  orphanDelayedCallbacks = null;
	  for (var i = 0; i < delayed.length; ++i) { delayed[i](); }
	}
	
	// When an aspect of a line changes, a string is added to
	// lineView.changes. This updates the relevant part of the line's
	// DOM structure.
	function updateLineForChanges(cm, lineView, lineN, dims) {
	  for (var j = 0; j < lineView.changes.length; j++) {
	    var type = lineView.changes[j];
	    if (type == "text") { updateLineText(cm, lineView); }
	    else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); }
	    else if (type == "class") { updateLineClasses(cm, lineView); }
	    else if (type == "widget") { updateLineWidgets(cm, lineView, dims); }
	  }
	  lineView.changes = null;
	}
	
	// Lines with gutter elements, widgets or a background class need to
	// be wrapped, and have the extra elements added to the wrapper div
	function ensureLineWrapped(lineView) {
	  if (lineView.node == lineView.text) {
	    lineView.node = elt("div", null, null, "position: relative");
	    if (lineView.text.parentNode)
	      { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); }
	    lineView.node.appendChild(lineView.text);
	    if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; }
	  }
	  return lineView.node
	}
	
	function updateLineBackground(cm, lineView) {
	  var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
	  if (cls) { cls += " CodeMirror-linebackground"; }
	  if (lineView.background) {
	    if (cls) { lineView.background.className = cls; }
	    else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
	  } else if (cls) {
	    var wrap = ensureLineWrapped(lineView);
	    lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
	    cm.display.input.setUneditable(lineView.background);
	  }
	}
	
	// Wrapper around buildLineContent which will reuse the structure
	// in display.externalMeasured when possible.
	function getLineContent(cm, lineView) {
	  var ext = cm.display.externalMeasured;
	  if (ext && ext.line == lineView.line) {
	    cm.display.externalMeasured = null;
	    lineView.measure = ext.measure;
	    return ext.built
	  }
	  return buildLineContent(cm, lineView)
	}
	
	// Redraw the line's text. Interacts with the background and text
	// classes because the mode may output tokens that influence these
	// classes.
	function updateLineText(cm, lineView) {
	  var cls = lineView.text.className;
	  var built = getLineContent(cm, lineView);
	  if (lineView.text == lineView.node) { lineView.node = built.pre; }
	  lineView.text.parentNode.replaceChild(built.pre, lineView.text);
	  lineView.text = built.pre;
	  if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
	    lineView.bgClass = built.bgClass;
	    lineView.textClass = built.textClass;
	    updateLineClasses(cm, lineView);
	  } else if (cls) {
	    lineView.text.className = cls;
	  }
	}
	
	function updateLineClasses(cm, lineView) {
	  updateLineBackground(cm, lineView);
	  if (lineView.line.wrapClass)
	    { ensureLineWrapped(lineView).className = lineView.line.wrapClass; }
	  else if (lineView.node != lineView.text)
	    { lineView.node.className = ""; }
	  var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
	  lineView.text.className = textClass || "";
	}
	
	function updateLineGutter(cm, lineView, lineN, dims) {
	  if (lineView.gutter) {
	    lineView.node.removeChild(lineView.gutter);
	    lineView.gutter = null;
	  }
	  if (lineView.gutterBackground) {
	    lineView.node.removeChild(lineView.gutterBackground);
	    lineView.gutterBackground = null;
	  }
	  if (lineView.line.gutterClass) {
	    var wrap = ensureLineWrapped(lineView);
	    lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
	                                    ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px"));
	    cm.display.input.setUneditable(lineView.gutterBackground);
	    wrap.insertBefore(lineView.gutterBackground, lineView.text);
	  }
	  var markers = lineView.line.gutterMarkers;
	  if (cm.options.lineNumbers || markers) {
	    var wrap$1 = ensureLineWrapped(lineView);
	    var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
	    cm.display.input.setUneditable(gutterWrap);
	    wrap$1.insertBefore(gutterWrap, lineView.text);
	    if (lineView.line.gutterClass)
	      { gutterWrap.className += " " + lineView.line.gutterClass; }
	    if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
	      { lineView.lineNumber = gutterWrap.appendChild(
	        elt("div", lineNumberFor(cm.options, lineN),
	            "CodeMirror-linenumber CodeMirror-gutter-elt",
	            ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); }
	    if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) {
	      var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
	      if (found)
	        { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt",
	                                   ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); }
	    } }
	  }
	}
	
	function updateLineWidgets(cm, lineView, dims) {
	  if (lineView.alignable) { lineView.alignable = null; }
	  for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
	    next = node.nextSibling;
	    if (node.className == "CodeMirror-linewidget")
	      { lineView.node.removeChild(node); }
	  }
	  insertLineWidgets(cm, lineView, dims);
	}
	
	// Build a line's DOM representation from scratch
	function buildLineElement(cm, lineView, lineN, dims) {
	  var built = getLineContent(cm, lineView);
	  lineView.text = lineView.node = built.pre;
	  if (built.bgClass) { lineView.bgClass = built.bgClass; }
	  if (built.textClass) { lineView.textClass = built.textClass; }
	
	  updateLineClasses(cm, lineView);
	  updateLineGutter(cm, lineView, lineN, dims);
	  insertLineWidgets(cm, lineView, dims);
	  return lineView.node
	}
	
	// A lineView may contain multiple logical lines (when merged by
	// collapsed spans). The widgets for all of them need to be drawn.
	function insertLineWidgets(cm, lineView, dims) {
	  insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
	  if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
	    { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } }
	}
	
	function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
	  if (!line.widgets) { return }
	  var wrap = ensureLineWrapped(lineView);
	  for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
	    var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
	    if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); }
	    positionLineWidget(widget, node, lineView, dims);
	    cm.display.input.setUneditable(node);
	    if (allowAbove && widget.above)
	      { wrap.insertBefore(node, lineView.gutter || lineView.text); }
	    else
	      { wrap.appendChild(node); }
	    signalLater(widget, "redraw");
	  }
	}
	
	function positionLineWidget(widget, node, lineView, dims) {
	  if (widget.noHScroll) {
	    (lineView.alignable || (lineView.alignable = [])).push(node);
	    var width = dims.wrapperWidth;
	    node.style.left = dims.fixedPos + "px";
	    if (!widget.coverGutter) {
	      width -= dims.gutterTotalWidth;
	      node.style.paddingLeft = dims.gutterTotalWidth + "px";
	    }
	    node.style.width = width + "px";
	  }
	  if (widget.coverGutter) {
	    node.style.zIndex = 5;
	    node.style.position = "relative";
	    if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; }
	  }
	}
	
	function widgetHeight(widget) {
	  if (widget.height != null) { return widget.height }
	  var cm = widget.doc.cm;
	  if (!cm) { return 0 }
	  if (!contains(document.body, widget.node)) {
	    var parentStyle = "position: relative;";
	    if (widget.coverGutter)
	      { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; }
	    if (widget.noHScroll)
	      { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; }
	    removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
	  }
	  return widget.height = widget.node.parentNode.offsetHeight
	}
	
	// Return true when the given mouse event happened in a widget
	function eventInWidget(display, e) {
	  for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
	    if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
	        (n.parentNode == display.sizer && n != display.mover))
	      { return true }
	  }
	}
	
	// POSITION MEASUREMENT
	
	function paddingTop(display) {return display.lineSpace.offsetTop}
	function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
	function paddingH(display) {
	  if (display.cachedPaddingH) { return display.cachedPaddingH }
	  var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
	  var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
	  var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
	  if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; }
	  return data
	}
	
	function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
	function displayWidth(cm) {
	  return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth
	}
	function displayHeight(cm) {
	  return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight
	}
	
	// Ensure the lineView.wrapping.heights array is populated. This is
	// an array of bottom offsets for the lines that make up a drawn
	// line. When lineWrapping is on, there might be more than one
	// height.
	function ensureLineHeights(cm, lineView, rect) {
	  var wrapping = cm.options.lineWrapping;
	  var curWidth = wrapping && displayWidth(cm);
	  if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
	    var heights = lineView.measure.heights = [];
	    if (wrapping) {
	      lineView.measure.width = curWidth;
	      var rects = lineView.text.firstChild.getClientRects();
	      for (var i = 0; i < rects.length - 1; i++) {
	        var cur = rects[i], next = rects[i + 1];
	        if (Math.abs(cur.bottom - next.bottom) > 2)
	          { heights.push((cur.bottom + next.top) / 2 - rect.top); }
	      }
	    }
	    heights.push(rect.bottom - rect.top);
	  }
	}
	
	// Find a line map (mapping character offsets to text nodes) and a
	// measurement cache for the given line number. (A line view might
	// contain multiple lines when collapsed ranges are present.)
	function mapFromLineView(lineView, line, lineN) {
	  if (lineView.line == line)
	    { return {map: lineView.measure.map, cache: lineView.measure.cache} }
	  for (var i = 0; i < lineView.rest.length; i++)
	    { if (lineView.rest[i] == line)
	      { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
	  for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
	    { if (lineNo(lineView.rest[i$1]) > lineN)
	      { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
	}
	
	// Render a line into the hidden node display.externalMeasured. Used
	// when measurement is needed for a line that's not in the viewport.
	function updateExternalMeasurement(cm, line) {
	  line = visualLine(line);
	  var lineN = lineNo(line);
	  var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
	  view.lineN = lineN;
	  var built = view.built = buildLineContent(cm, view);
	  view.text = built.pre;
	  removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
	  return view
	}
	
	// Get a {top, bottom, left, right} box (in line-local coordinates)
	// for a given character.
	function measureChar(cm, line, ch, bias) {
	  return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)
	}
	
	// Find a line view that corresponds to the given line number.
	function findViewForLine(cm, lineN) {
	  if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
	    { return cm.display.view[findViewIndex(cm, lineN)] }
	  var ext = cm.display.externalMeasured;
	  if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
	    { return ext }
	}
	
	// Measurement can be split in two steps, the set-up work that
	// applies to the whole line, and the measurement of the actual
	// character. Functions like coordsChar, that need to do a lot of
	// measurements in a row, can thus ensure that the set-up work is
	// only done once.
	function prepareMeasureForLine(cm, line) {
	  var lineN = lineNo(line);
	  var view = findViewForLine(cm, lineN);
	  if (view && !view.text) {
	    view = null;
	  } else if (view && view.changes) {
	    updateLineForChanges(cm, view, lineN, getDimensions(cm));
	    cm.curOp.forceUpdate = true;
	  }
	  if (!view)
	    { view = updateExternalMeasurement(cm, line); }
	
	  var info = mapFromLineView(view, line, lineN);
	  return {
	    line: line, view: view, rect: null,
	    map: info.map, cache: info.cache, before: info.before,
	    hasHeights: false
	  }
	}
	
	// Given a prepared measurement object, measures the position of an
	// actual character (or fetches it from the cache).
	function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
	  if (prepared.before) { ch = -1; }
	  var key = ch + (bias || ""), found;
	  if (prepared.cache.hasOwnProperty(key)) {
	    found = prepared.cache[key];
	  } else {
	    if (!prepared.rect)
	      { prepared.rect = prepared.view.text.getBoundingClientRect(); }
	    if (!prepared.hasHeights) {
	      ensureLineHeights(cm, prepared.view, prepared.rect);
	      prepared.hasHeights = true;
	    }
	    found = measureCharInner(cm, prepared, ch, bias);
	    if (!found.bogus) { prepared.cache[key] = found; }
	  }
	  return {left: found.left, right: found.right,
	          top: varHeight ? found.rtop : found.top,
	          bottom: varHeight ? found.rbottom : found.bottom}
	}
	
	var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
	
	function nodeAndOffsetInLineMap(map$$1, ch, bias) {
	  var node, start, end, collapse, mStart, mEnd;
	  // First, search the line map for the text node corresponding to,
	  // or closest to, the target character.
	  for (var i = 0; i < map$$1.length; i += 3) {
	    mStart = map$$1[i];
	    mEnd = map$$1[i + 1];
	    if (ch < mStart) {
	      start = 0; end = 1;
	      collapse = "left";
	    } else if (ch < mEnd) {
	      start = ch - mStart;
	      end = start + 1;
	    } else if (i == map$$1.length - 3 || ch == mEnd && map$$1[i + 3] > ch) {
	      end = mEnd - mStart;
	      start = end - 1;
	      if (ch >= mEnd) { collapse = "right"; }
	    }
	    if (start != null) {
	      node = map$$1[i + 2];
	      if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
	        { collapse = bias; }
	      if (bias == "left" && start == 0)
	        { while (i && map$$1[i - 2] == map$$1[i - 3] && map$$1[i - 1].insertLeft) {
	          node = map$$1[(i -= 3) + 2];
	          collapse = "left";
	        } }
	      if (bias == "right" && start == mEnd - mStart)
	        { while (i < map$$1.length - 3 && map$$1[i + 3] == map$$1[i + 4] && !map$$1[i + 5].insertLeft) {
	          node = map$$1[(i += 3) + 2];
	          collapse = "right";
	        } }
	      break
	    }
	  }
	  return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}
	}
	
	function getUsefulRect(rects, bias) {
	  var rect = nullRect;
	  if (bias == "left") { for (var i = 0; i < rects.length; i++) {
	    if ((rect = rects[i]).left != rect.right) { break }
	  } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) {
	    if ((rect = rects[i$1]).left != rect.right) { break }
	  } }
	  return rect
	}
	
	function measureCharInner(cm, prepared, ch, bias) {
	  var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
	  var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
	
	  var rect;
	  if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
	    for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned
	      while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; }
	      while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; }
	      if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)
	        { rect = node.parentNode.getBoundingClientRect(); }
	      else
	        { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); }
	      if (rect.left || rect.right || start == 0) { break }
	      end = start;
	      start = start - 1;
	      collapse = "right";
	    }
	    if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); }
	  } else { // If it is a widget, simply get the box for the whole widget.
	    if (start > 0) { collapse = bias = "right"; }
	    var rects;
	    if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
	      { rect = rects[bias == "right" ? rects.length - 1 : 0]; }
	    else
	      { rect = node.getBoundingClientRect(); }
	  }
	  if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
	    var rSpan = node.parentNode.getClientRects()[0];
	    if (rSpan)
	      { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; }
	    else
	      { rect = nullRect; }
	  }
	
	  var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
	  var mid = (rtop + rbot) / 2;
	  var heights = prepared.view.measure.heights;
	  var i = 0;
	  for (; i < heights.length - 1; i++)
	    { if (mid < heights[i]) { break } }
	  var top = i ? heights[i - 1] : 0, bot = heights[i];
	  var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
	                right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
	                top: top, bottom: bot};
	  if (!rect.left && !rect.right) { result.bogus = true; }
	  if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
	
	  return result
	}
	
	// Work around problem with bounding client rects on ranges being
	// returned incorrectly when zoomed on IE10 and below.
	function maybeUpdateRectForZooming(measure, rect) {
	  if (!window.screen || screen.logicalXDPI == null ||
	      screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
	    { return rect }
	  var scaleX = screen.logicalXDPI / screen.deviceXDPI;
	  var scaleY = screen.logicalYDPI / screen.deviceYDPI;
	  return {left: rect.left * scaleX, right: rect.right * scaleX,
	          top: rect.top * scaleY, bottom: rect.bottom * scaleY}
	}
	
	function clearLineMeasurementCacheFor(lineView) {
	  if (lineView.measure) {
	    lineView.measure.cache = {};
	    lineView.measure.heights = null;
	    if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
	      { lineView.measure.caches[i] = {}; } }
	  }
	}
	
	function clearLineMeasurementCache(cm) {
	  cm.display.externalMeasure = null;
	  removeChildren(cm.display.lineMeasure);
	  for (var i = 0; i < cm.display.view.length; i++)
	    { clearLineMeasurementCacheFor(cm.display.view[i]); }
	}
	
	function clearCaches(cm) {
	  clearLineMeasurementCache(cm);
	  cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
	  if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; }
	  cm.display.lineNumChars = null;
	}
	
	function pageScrollX() {
	  // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
	  // which causes page_Offset and bounding client rects to use
	  // different reference viewports and invalidate our calculations.
	  if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }
	  return window.pageXOffset || (document.documentElement || document.body).scrollLeft
	}
	function pageScrollY() {
	  if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }
	  return window.pageYOffset || (document.documentElement || document.body).scrollTop
	}
	
	// Converts a {top, bottom, left, right} box from line-local
	// coordinates into another coordinate system. Context may be one of
	// "line", "div" (display.lineDiv), "local"./null (editor), "window",
	// or "page".
	function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
	  if (!includeWidgets && lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) {
	    var size = widgetHeight(lineObj.widgets[i]);
	    rect.top += size; rect.bottom += size;
	  } } }
	  if (context == "line") { return rect }
	  if (!context) { context = "local"; }
	  var yOff = heightAtLine(lineObj);
	  if (context == "local") { yOff += paddingTop(cm.display); }
	  else { yOff -= cm.display.viewOffset; }
	  if (context == "page" || context == "window") {
	    var lOff = cm.display.lineSpace.getBoundingClientRect();
	    yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
	    var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
	    rect.left += xOff; rect.right += xOff;
	  }
	  rect.top += yOff; rect.bottom += yOff;
	  return rect
	}
	
	// Coverts a box from "div" coords to another coordinate system.
	// Context may be "window", "page", "div", or "local"./null.
	function fromCoordSystem(cm, coords, context) {
	  if (context == "div") { return coords }
	  var left = coords.left, top = coords.top;
	  // First move into "page" coordinate system
	  if (context == "page") {
	    left -= pageScrollX();
	    top -= pageScrollY();
	  } else if (context == "local" || !context) {
	    var localBox = cm.display.sizer.getBoundingClientRect();
	    left += localBox.left;
	    top += localBox.top;
	  }
	
	  var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
	  return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}
	}
	
	function charCoords(cm, pos, context, lineObj, bias) {
	  if (!lineObj) { lineObj = getLine(cm.doc, pos.line); }
	  return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)
	}
	
	// Returns a box for a given cursor position, which may have an
	// 'other' property containing the position of the secondary cursor
	// on a bidi boundary.
	// A cursor Pos(line, char, "before") is on the same visual line as `char - 1`
	// and after `char - 1` in writing order of `char - 1`
	// A cursor Pos(line, char, "after") is on the same visual line as `char`
	// and before `char` in writing order of `char`
	// Examples (upper-case letters are RTL, lower-case are LTR):
	//     Pos(0, 1, ...)
	//     before   after
	// ab     a|b     a|b
	// aB     a|B     aB|
	// Ab     |Ab     A|b
	// AB     B|A     B|A
	// Every position after the last character on a line is considered to stick
	// to the last character on the line.
	function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
	  lineObj = lineObj || getLine(cm.doc, pos.line);
	  if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
	  function get(ch, right) {
	    var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
	    if (right) { m.left = m.right; } else { m.right = m.left; }
	    return intoCoordSystem(cm, lineObj, m, context)
	  }
	  var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky;
	  if (ch >= lineObj.text.length) {
	    ch = lineObj.text.length;
	    sticky = "before";
	  } else if (ch <= 0) {
	    ch = 0;
	    sticky = "after";
	  }
	  if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") }
	
	  function getBidi(ch, partPos, invert) {
	    var part = order[partPos], right = (part.level % 2) != 0;
	    return get(invert ? ch - 1 : ch, right != invert)
	  }
	  var partPos = getBidiPartAt(order, ch, sticky);
	  var other = bidiOther;
	  var val = getBidi(ch, partPos, sticky == "before");
	  if (other != null) { val.other = getBidi(ch, other, sticky != "before"); }
	  return val
	}
	
	// Used to cheaply estimate the coordinates for a position. Used for
	// intermediate scroll updates.
	function estimateCoords(cm, pos) {
	  var left = 0;
	  pos = clipPos(cm.doc, pos);
	  if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; }
	  var lineObj = getLine(cm.doc, pos.line);
	  var top = heightAtLine(lineObj) + paddingTop(cm.display);
	  return {left: left, right: left, top: top, bottom: top + lineObj.height}
	}
	
	// Positions returned by coordsChar contain some extra information.
	// xRel is the relative x position of the input coordinates compared
	// to the found position (so xRel > 0 means the coordinates are to
	// the right of the character position, for example). When outside
	// is true, that means the coordinates lie outside the line's
	// vertical range.
	function PosWithInfo(line, ch, sticky, outside, xRel) {
	  var pos = Pos(line, ch, sticky);
	  pos.xRel = xRel;
	  if (outside) { pos.outside = true; }
	  return pos
	}
	
	// Compute the character position closest to the given coordinates.
	// Input must be lineSpace-local ("div" coordinate system).
	function coordsChar(cm, x, y) {
	  var doc = cm.doc;
	  y += cm.display.viewOffset;
	  if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }
	  var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
	  if (lineN > last)
	    { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }
	  if (x < 0) { x = 0; }
	
	  var lineObj = getLine(doc, lineN);
	  for (;;) {
	    var found = coordsCharInner(cm, lineObj, lineN, x, y);
	    var merged = collapsedSpanAtEnd(lineObj);
	    var mergedPos = merged && merged.find(0, true);
	    if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
	      { lineN = lineNo(lineObj = mergedPos.to.line); }
	    else
	      { return found }
	  }
	}
	
	function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
	  var measure = function (ch) { return intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); };
	  var end = lineObj.text.length;
	  var begin = findFirst(function (ch) { return measure(ch - 1).bottom <= y; }, end, 0);
	  end = findFirst(function (ch) { return measure(ch).top > y; }, begin, end);
	  return {begin: begin, end: end}
	}
	
	function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
	  var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top;
	  return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
	}
	
	function coordsCharInner(cm, lineObj, lineNo$$1, x, y) {
	  y -= heightAtLine(lineObj);
	  var begin = 0, end = lineObj.text.length;
	  var preparedMeasure = prepareMeasureForLine(cm, lineObj);
	  var pos;
	  var order = getOrder(lineObj, cm.doc.direction);
	  if (order) {
	    if (cm.options.lineWrapping) {
	      var assign;
	      ((assign = wrappedLineExtent(cm, lineObj, preparedMeasure, y), begin = assign.begin, end = assign.end, assign));
	    }
	    pos = new Pos(lineNo$$1, Math.floor(begin + (end - begin) / 2));
	    var beginLeft = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left;
	    var dir = beginLeft < x ? 1 : -1;
	    var prevDiff, diff = beginLeft - x, prevPos;
	    var steps = Math.ceil((end - begin) / 4);
	    outer: do {
	      prevDiff = diff;
	      prevPos = pos;
	      var i = 0;
	      for (; i < steps; ++i) {
	        var prevPos$1 = pos;
	        pos = moveVisually(cm, lineObj, pos, dir);
	        if (pos == null || pos.ch < begin || end <= (pos.sticky == "before" ? pos.ch - 1 : pos.ch)) {
	          pos = prevPos$1;
	          break outer
	        }
	      }
	      diff = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left - x;
	      if (steps > 1) {
	        var diff_change_per_step = Math.abs(diff - prevDiff) / steps;
	        steps = Math.min(steps, Math.ceil(Math.abs(diff) / diff_change_per_step));
	        dir = diff < 0 ? 1 : -1;
	      }
	    } while (diff != 0 && (steps > 1 || ((dir < 0) != (diff < 0) && (Math.abs(diff) <= Math.abs(prevDiff)))))
	    if (Math.abs(diff) > Math.abs(prevDiff)) {
	      if ((diff < 0) == (prevDiff < 0)) { throw new Error("Broke out of infinite loop in coordsCharInner") }
	      pos = prevPos;
	    }
	  } else {
	    var ch = findFirst(function (ch) {
	      var box = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line");
	      if (box.top > y) {
	        // For the cursor stickiness
	        end = Math.min(ch, end);
	        return true
	      }
	      else if (box.bottom <= y) { return false }
	      else if (box.left > x) { return true }
	      else if (box.right < x) { return false }
	      else { return (x - box.left < box.right - x) }
	    }, begin, end);
	    ch = skipExtendingChars(lineObj.text, ch, 1);
	    pos = new Pos(lineNo$$1, ch, ch == end ? "before" : "after");
	  }
	  var coords = cursorCoords(cm, pos, "line", lineObj, preparedMeasure);
	  if (y < coords.top || coords.bottom < y) { pos.outside = true; }
	  pos.xRel = x < coords.left ? -1 : (x > coords.right ? 1 : 0);
	  return pos
	}
	
	var measureText;
	// Compute the default text height.
	function textHeight(display) {
	  if (display.cachedTextHeight != null) { return display.cachedTextHeight }
	  if (measureText == null) {
	    measureText = elt("pre");
	    // Measure a bunch of lines, for browsers that compute
	    // fractional heights.
	    for (var i = 0; i < 49; ++i) {
	      measureText.appendChild(document.createTextNode("x"));
	      measureText.appendChild(elt("br"));
	    }
	    measureText.appendChild(document.createTextNode("x"));
	  }
	  removeChildrenAndAdd(display.measure, measureText);
	  var height = measureText.offsetHeight / 50;
	  if (height > 3) { display.cachedTextHeight = height; }
	  removeChildren(display.measure);
	  return height || 1
	}
	
	// Compute the default character width.
	function charWidth(display) {
	  if (display.cachedCharWidth != null) { return display.cachedCharWidth }
	  var anchor = elt("span", "xxxxxxxxxx");
	  var pre = elt("pre", [anchor]);
	  removeChildrenAndAdd(display.measure, pre);
	  var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
	  if (width > 2) { display.cachedCharWidth = width; }
	  return width || 10
	}
	
	// Do a bulk-read of the DOM positions and sizes needed to draw the
	// view, so that we don't interleave reading and writing to the DOM.
	function getDimensions(cm) {
	  var d = cm.display, left = {}, width = {};
	  var gutterLeft = d.gutters.clientLeft;
	  for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
	    left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
	    width[cm.options.gutters[i]] = n.clientWidth;
	  }
	  return {fixedPos: compensateForHScroll(d),
	          gutterTotalWidth: d.gutters.offsetWidth,
	          gutterLeft: left,
	          gutterWidth: width,
	          wrapperWidth: d.wrapper.clientWidth}
	}
	
	// Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
	// but using getBoundingClientRect to get a sub-pixel-accurate
	// result.
	function compensateForHScroll(display) {
	  return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left
	}
	
	// Returns a function that estimates the height of a line, to use as
	// first approximation until the line becomes visible (and is thus
	// properly measurable).
	function estimateHeight(cm) {
	  var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
	  var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
	  return function (line) {
	    if (lineIsHidden(cm.doc, line)) { return 0 }
	
	    var widgetsHeight = 0;
	    if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) {
	      if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; }
	    } }
	
	    if (wrapping)
	      { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th }
	    else
	      { return widgetsHeight + th }
	  }
	}
	
	function estimateLineHeights(cm) {
	  var doc = cm.doc, est = estimateHeight(cm);
	  doc.iter(function (line) {
	    var estHeight = est(line);
	    if (estHeight != line.height) { updateLineHeight(line, estHeight); }
	  });
	}
	
	// Given a mouse event, find the corresponding position. If liberal
	// is false, it checks whether a gutter or scrollbar was clicked,
	// and returns null if it was. forRect is used by rectangular
	// selections, and tries to estimate a character position even for
	// coordinates beyond the right of the text.
	function posFromMouse(cm, e, liberal, forRect) {
	  var display = cm.display;
	  if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null }
	
	  var x, y, space = display.lineSpace.getBoundingClientRect();
	  // Fails unpredictably on IE[67] when mouse is dragged around quickly.
	  try { x = e.clientX - space.left; y = e.clientY - space.top; }
	  catch (e) { return null }
	  var coords = coordsChar(cm, x, y), line;
	  if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
	    var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
	    coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
	  }
	  return coords
	}
	
	// Find the view element corresponding to a given line. Return null
	// when the line isn't visible.
	function findViewIndex(cm, n) {
	  if (n >= cm.display.viewTo) { return null }
	  n -= cm.display.viewFrom;
	  if (n < 0) { return null }
	  var view = cm.display.view;
	  for (var i = 0; i < view.length; i++) {
	    n -= view[i].size;
	    if (n < 0) { return i }
	  }
	}
	
	function updateSelection(cm) {
	  cm.display.input.showSelection(cm.display.input.prepareSelection());
	}
	
	function prepareSelection(cm, primary) {
	  var doc = cm.doc, result = {};
	  var curFragment = result.cursors = document.createDocumentFragment();
	  var selFragment = result.selection = document.createDocumentFragment();
	
	  for (var i = 0; i < doc.sel.ranges.length; i++) {
	    if (primary === false && i == doc.sel.primIndex) { continue }
	    var range$$1 = doc.sel.ranges[i];
	    if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue }
	    var collapsed = range$$1.empty();
	    if (collapsed || cm.options.showCursorWhenSelecting)
	      { drawSelectionCursor(cm, range$$1.head, curFragment); }
	    if (!collapsed)
	      { drawSelectionRange(cm, range$$1, selFragment); }
	  }
	  return result
	}
	
	// Draws a cursor for the given range
	function drawSelectionCursor(cm, head, output) {
	  var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
	
	  var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
	  cursor.style.left = pos.left + "px";
	  cursor.style.top = pos.top + "px";
	  cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
	
	  if (pos.other) {
	    // Secondary cursor, shown when on a 'jump' in bi-directional text
	    var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
	    otherCursor.style.display = "";
	    otherCursor.style.left = pos.other.left + "px";
	    otherCursor.style.top = pos.other.top + "px";
	    otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
	  }
	}
	
	// Draws the given range as a highlighted selection
	function drawSelectionRange(cm, range$$1, output) {
	  var display = cm.display, doc = cm.doc;
	  var fragment = document.createDocumentFragment();
	  var padding = paddingH(cm.display), leftSide = padding.left;
	  var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
	
	  function add(left, top, width, bottom) {
	    if (top < 0) { top = 0; }
	    top = Math.round(top);
	    bottom = Math.round(bottom);
	    fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n                             top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n                             height: " + (bottom - top) + "px")));
	  }
	
	  function drawForLine(line, fromArg, toArg) {
	    var lineObj = getLine(doc, line);
	    var lineLen = lineObj.text.length;
	    var start, end;
	    function coords(ch, bias) {
	      return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
	    }
	
	    iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) {
	      var leftPos = coords(from, "left"), rightPos, left, right;
	      if (from == to) {
	        rightPos = leftPos;
	        left = right = leftPos.left;
	      } else {
	        rightPos = coords(to - 1, "right");
	        if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
	        left = leftPos.left;
	        right = rightPos.right;
	      }
	      if (fromArg == null && from == 0) { left = leftSide; }
	      if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
	        add(left, leftPos.top, null, leftPos.bottom);
	        left = leftSide;
	        if (leftPos.bottom < rightPos.top) { add(left, leftPos.bottom, null, rightPos.top); }
	      }
	      if (toArg == null && to == lineLen) { right = rightSide; }
	      if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
	        { start = leftPos; }
	      if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
	        { end = rightPos; }
	      if (left < leftSide + 1) { left = leftSide; }
	      add(left, rightPos.top, right - left, rightPos.bottom);
	    });
	    return {start: start, end: end}
	  }
	
	  var sFrom = range$$1.from(), sTo = range$$1.to();
	  if (sFrom.line == sTo.line) {
	    drawForLine(sFrom.line, sFrom.ch, sTo.ch);
	  } else {
	    var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
	    var singleVLine = visualLine(fromLine) == visualLine(toLine);
	    var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
	    var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
	    if (singleVLine) {
	      if (leftEnd.top < rightStart.top - 2) {
	        add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
	        add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
	      } else {
	        add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
	      }
	    }
	    if (leftEnd.bottom < rightStart.top)
	      { add(leftSide, leftEnd.bottom, null, rightStart.top); }
	  }
	
	  output.appendChild(fragment);
	}
	
	// Cursor-blinking
	function restartBlink(cm) {
	  if (!cm.state.focused) { return }
	  var display = cm.display;
	  clearInterval(display.blinker);
	  var on = true;
	  display.cursorDiv.style.visibility = "";
	  if (cm.options.cursorBlinkRate > 0)
	    { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; },
	      cm.options.cursorBlinkRate); }
	  else if (cm.options.cursorBlinkRate < 0)
	    { display.cursorDiv.style.visibility = "hidden"; }
	}
	
	function ensureFocus(cm) {
	  if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
	}
	
	function delayBlurEvent(cm) {
	  cm.state.delayingBlurEvent = true;
	  setTimeout(function () { if (cm.state.delayingBlurEvent) {
	    cm.state.delayingBlurEvent = false;
	    onBlur(cm);
	  } }, 100);
	}
	
	function onFocus(cm, e) {
	  if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; }
	
	  if (cm.options.readOnly == "nocursor") { return }
	  if (!cm.state.focused) {
	    signal(cm, "focus", cm, e);
	    cm.state.focused = true;
	    addClass(cm.display.wrapper, "CodeMirror-focused");
	    // This test prevents this from firing when a context
	    // menu is closed (since the input reset would kill the
	    // select-all detection hack)
	    if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
	      cm.display.input.reset();
	      if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730
	    }
	    cm.display.input.receivedFocus();
	  }
	  restartBlink(cm);
	}
	function onBlur(cm, e) {
	  if (cm.state.delayingBlurEvent) { return }
	
	  if (cm.state.focused) {
	    signal(cm, "blur", cm, e);
	    cm.state.focused = false;
	    rmClass(cm.display.wrapper, "CodeMirror-focused");
	  }
	  clearInterval(cm.display.blinker);
	  setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150);
	}
	
	// Read the actual heights of the rendered lines, and update their
	// stored heights to match.
	function updateHeightsInViewport(cm) {
	  var display = cm.display;
	  var prevBottom = display.lineDiv.offsetTop;
	  for (var i = 0; i < display.view.length; i++) {
	    var cur = display.view[i], height = (void 0);
	    if (cur.hidden) { continue }
	    if (ie && ie_version < 8) {
	      var bot = cur.node.offsetTop + cur.node.offsetHeight;
	      height = bot - prevBottom;
	      prevBottom = bot;
	    } else {
	      var box = cur.node.getBoundingClientRect();
	      height = box.bottom - box.top;
	    }
	    var diff = cur.line.height - height;
	    if (height < 2) { height = textHeight(display); }
	    if (diff > .001 || diff < -.001) {
	      updateLineHeight(cur.line, height);
	      updateWidgetHeight(cur.line);
	      if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
	        { updateWidgetHeight(cur.rest[j]); } }
	    }
	  }
	}
	
	// Read and store the height of line widgets associated with the
	// given line.
	function updateWidgetHeight(line) {
	  if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i)
	    { line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight; } }
	}
	
	// Compute the lines that are visible in a given viewport (defaults
	// the the current scroll position). viewport may contain top,
	// height, and ensure (see op.scrollToPos) properties.
	function visibleLines(display, doc, viewport) {
	  var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
	  top = Math.floor(top - paddingTop(display));
	  var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
	
	  var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
	  // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
	  // forces those lines into the viewport (if possible).
	  if (viewport && viewport.ensure) {
	    var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
	    if (ensureFrom < from) {
	      from = ensureFrom;
	      to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
	    } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
	      from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
	      to = ensureTo;
	    }
	  }
	  return {from: from, to: Math.max(to, from + 1)}
	}
	
	// Re-align line numbers and gutter marks to compensate for
	// horizontal scrolling.
	function alignHorizontally(cm) {
	  var display = cm.display, view = display.view;
	  if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return }
	  var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
	  var gutterW = display.gutters.offsetWidth, left = comp + "px";
	  for (var i = 0; i < view.length; i++) { if (!view[i].hidden) {
	    if (cm.options.fixedGutter) {
	      if (view[i].gutter)
	        { view[i].gutter.style.left = left; }
	      if (view[i].gutterBackground)
	        { view[i].gutterBackground.style.left = left; }
	    }
	    var align = view[i].alignable;
	    if (align) { for (var j = 0; j < align.length; j++)
	      { align[j].style.left = left; } }
	  } }
	  if (cm.options.fixedGutter)
	    { display.gutters.style.left = (comp + gutterW) + "px"; }
	}
	
	// Used to ensure that the line number gutter is still the right
	// size for the current document size. Returns true when an update
	// is needed.
	function maybeUpdateLineNumberWidth(cm) {
	  if (!cm.options.lineNumbers) { return false }
	  var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
	  if (last.length != display.lineNumChars) {
	    var test = display.measure.appendChild(elt("div", [elt("div", last)],
	                                               "CodeMirror-linenumber CodeMirror-gutter-elt"));
	    var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
	    display.lineGutter.style.width = "";
	    display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
	    display.lineNumWidth = display.lineNumInnerWidth + padding;
	    display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
	    display.lineGutter.style.width = display.lineNumWidth + "px";
	    updateGutterSpace(cm);
	    return true
	  }
	  return false
	}
	
	// SCROLLING THINGS INTO VIEW
	
	// If an editor sits on the top or bottom of the window, partially
	// scrolled out of view, this ensures that the cursor is visible.
	function maybeScrollWindow(cm, rect) {
	  if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
	
	  var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
	  if (rect.top + box.top < 0) { doScroll = true; }
	  else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; }
	  if (doScroll != null && !phantom) {
	    var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n                         top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n                         height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n                         left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;"));
	    cm.display.lineSpace.appendChild(scrollNode);
	    scrollNode.scrollIntoView(doScroll);
	    cm.display.lineSpace.removeChild(scrollNode);
	  }
	}
	
	// Scroll a given position into view (immediately), verifying that
	// it actually became visible (as line heights are accurately
	// measured, the position of something may 'drift' during drawing).
	function scrollPosIntoView(cm, pos, end, margin) {
	  if (margin == null) { margin = 0; }
	  var rect;
	  for (var limit = 0; limit < 5; limit++) {
	    var changed = false;
	    var coords = cursorCoords(cm, pos);
	    var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
	    rect = {left: Math.min(coords.left, endCoords.left),
	            top: Math.min(coords.top, endCoords.top) - margin,
	            right: Math.max(coords.left, endCoords.left),
	            bottom: Math.max(coords.bottom, endCoords.bottom) + margin};
	    var scrollPos = calculateScrollPos(cm, rect);
	    var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
	    if (scrollPos.scrollTop != null) {
	      updateScrollTop(cm, scrollPos.scrollTop);
	      if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; }
	    }
	    if (scrollPos.scrollLeft != null) {
	      setScrollLeft(cm, scrollPos.scrollLeft);
	      if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; }
	    }
	    if (!changed) { break }
	  }
	  return rect
	}
	
	// Scroll a given set of coordinates into view (immediately).
	function scrollIntoView(cm, rect) {
	  var scrollPos = calculateScrollPos(cm, rect);
	  if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop); }
	  if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); }
	}
	
	// Calculate a new scroll position needed to scroll the given
	// rectangle into view. Returns an object with scrollTop and
	// scrollLeft properties. When these are undefined, the
	// vertical/horizontal position does not need to be adjusted.
	function calculateScrollPos(cm, rect) {
	  var display = cm.display, snapMargin = textHeight(cm.display);
	  if (rect.top < 0) { rect.top = 0; }
	  var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
	  var screen = displayHeight(cm), result = {};
	  if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; }
	  var docBottom = cm.doc.height + paddingVert(display);
	  var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin;
	  if (rect.top < screentop) {
	    result.scrollTop = atTop ? 0 : rect.top;
	  } else if (rect.bottom > screentop + screen) {
	    var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen);
	    if (newTop != screentop) { result.scrollTop = newTop; }
	  }
	
	  var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
	  var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
	  var tooWide = rect.right - rect.left > screenw;
	  if (tooWide) { rect.right = rect.left + screenw; }
	  if (rect.left < 10)
	    { result.scrollLeft = 0; }
	  else if (rect.left < screenleft)
	    { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)); }
	  else if (rect.right > screenw + screenleft - 3)
	    { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; }
	  return result
	}
	
	// Store a relative adjustment to the scroll position in the current
	// operation (to be applied when the operation finishes).
	function addToScrollTop(cm, top) {
	  if (top == null) { return }
	  resolveScrollToPos(cm);
	  cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
	}
	
	// Make sure that at the end of the operation the current cursor is
	// shown.
	function ensureCursorVisible(cm) {
	  resolveScrollToPos(cm);
	  var cur = cm.getCursor(), from = cur, to = cur;
	  if (!cm.options.lineWrapping) {
	    from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
	    to = Pos(cur.line, cur.ch + 1);
	  }
	  cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin};
	}
	
	function scrollToCoords(cm, x, y) {
	  if (x != null || y != null) { resolveScrollToPos(cm); }
	  if (x != null) { cm.curOp.scrollLeft = x; }
	  if (y != null) { cm.curOp.scrollTop = y; }
	}
	
	function scrollToRange(cm, range$$1) {
	  resolveScrollToPos(cm);
	  cm.curOp.scrollToPos = range$$1;
	}
	
	// When an operation has its scrollToPos property set, and another
	// scroll action is applied before the end of the operation, this
	// 'simulates' scrolling that position into view in a cheap way, so
	// that the effect of intermediate scroll commands is not ignored.
	function resolveScrollToPos(cm) {
	  var range$$1 = cm.curOp.scrollToPos;
	  if (range$$1) {
	    cm.curOp.scrollToPos = null;
	    var from = estimateCoords(cm, range$$1.from), to = estimateCoords(cm, range$$1.to);
	    scrollToCoordsRange(cm, from, to, range$$1.margin);
	  }
	}
	
	function scrollToCoordsRange(cm, from, to, margin) {
	  var sPos = calculateScrollPos(cm, {
	    left: Math.min(from.left, to.left),
	    top: Math.min(from.top, to.top) - margin,
	    right: Math.max(from.right, to.right),
	    bottom: Math.max(from.bottom, to.bottom) + margin
	  });
	  scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop);
	}
	
	// Sync the scrollable area and scrollbars, ensure the viewport
	// covers the visible area.
	function updateScrollTop(cm, val) {
	  if (Math.abs(cm.doc.scrollTop - val) < 2) { return }
	  if (!gecko) { updateDisplaySimple(cm, {top: val}); }
	  setScrollTop(cm, val, true);
	  if (gecko) { updateDisplaySimple(cm); }
	  startWorker(cm, 100);
	}
	
	function setScrollTop(cm, val, forceScroll) {
	  val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
	  if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
	  cm.doc.scrollTop = val;
	  cm.display.scrollbars.setScrollTop(val);
	  if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; }
	}
	
	// Sync scroller and scrollbar, ensure the gutter elements are
	// aligned.
	function setScrollLeft(cm, val, isScroller, forceScroll) {
	  val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
	  if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
	  cm.doc.scrollLeft = val;
	  alignHorizontally(cm);
	  if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; }
	  cm.display.scrollbars.setScrollLeft(val);
	}
	
	// SCROLLBARS
	
	// Prepare DOM reads needed to update the scrollbars. Done in one
	// shot to minimize update/measure roundtrips.
	function measureForScrollbars(cm) {
	  var d = cm.display, gutterW = d.gutters.offsetWidth;
	  var docH = Math.round(cm.doc.height + paddingVert(cm.display));
	  return {
	    clientHeight: d.scroller.clientHeight,
	    viewHeight: d.wrapper.clientHeight,
	    scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
	    viewWidth: d.wrapper.clientWidth,
	    barLeft: cm.options.fixedGutter ? gutterW : 0,
	    docHeight: docH,
	    scrollHeight: docH + scrollGap(cm) + d.barHeight,
	    nativeBarWidth: d.nativeBarWidth,
	    gutterWidth: gutterW
	  }
	}
	
	var NativeScrollbars = function(place, scroll, cm) {
	  this.cm = cm;
	  var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
	  var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
	  place(vert); place(horiz);
	
	  on(vert, "scroll", function () {
	    if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); }
	  });
	  on(horiz, "scroll", function () {
	    if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); }
	  });
	
	  this.checkedZeroWidth = false;
	  // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
	  if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; }
	};
	
	NativeScrollbars.prototype.update = function (measure) {
	  var needsH = measure.scrollWidth > measure.clientWidth + 1;
	  var needsV = measure.scrollHeight > measure.clientHeight + 1;
	  var sWidth = measure.nativeBarWidth;
	
	  if (needsV) {
	    this.vert.style.display = "block";
	    this.vert.style.bottom = needsH ? sWidth + "px" : "0";
	    var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
	    // A bug in IE8 can cause this value to be negative, so guard it.
	    this.vert.firstChild.style.height =
	      Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
	  } else {
	    this.vert.style.display = "";
	    this.vert.firstChild.style.height = "0";
	  }
	
	  if (needsH) {
	    this.horiz.style.display = "block";
	    this.horiz.style.right = needsV ? sWidth + "px" : "0";
	    this.horiz.style.left = measure.barLeft + "px";
	    var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
	    this.horiz.firstChild.style.width =
	      Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
	  } else {
	    this.horiz.style.display = "";
	    this.horiz.firstChild.style.width = "0";
	  }
	
	  if (!this.checkedZeroWidth && measure.clientHeight > 0) {
	    if (sWidth == 0) { this.zeroWidthHack(); }
	    this.checkedZeroWidth = true;
	  }
	
	  return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}
	};
	
	NativeScrollbars.prototype.setScrollLeft = function (pos) {
	  if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; }
	  if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz"); }
	};
	
	NativeScrollbars.prototype.setScrollTop = function (pos) {
	  if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; }
	  if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert"); }
	};
	
	NativeScrollbars.prototype.zeroWidthHack = function () {
	  var w = mac && !mac_geMountainLion ? "12px" : "18px";
	  this.horiz.style.height = this.vert.style.width = w;
	  this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
	  this.disableHoriz = new Delayed;
	  this.disableVert = new Delayed;
	};
	
	NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
	  bar.style.pointerEvents = "auto";
	  function maybeDisable() {
	    // To find out whether the scrollbar is still visible, we
	    // check whether the element under the pixel in the bottom
	    // right corner of the scrollbar box is the scrollbar box
	    // itself (when the bar is still visible) or its filler child
	    // (when the bar is hidden). If it is still visible, we keep
	    // it enabled, if it's hidden, we disable pointer events.
	    var box = bar.getBoundingClientRect();
	    var elt$$1 = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
	        : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1);
	    if (elt$$1 != bar) { bar.style.pointerEvents = "none"; }
	    else { delay.set(1000, maybeDisable); }
	  }
	  delay.set(1000, maybeDisable);
	};
	
	NativeScrollbars.prototype.clear = function () {
	  var parent = this.horiz.parentNode;
	  parent.removeChild(this.horiz);
	  parent.removeChild(this.vert);
	};
	
	var NullScrollbars = function () {};
	
	NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} };
	NullScrollbars.prototype.setScrollLeft = function () {};
	NullScrollbars.prototype.setScrollTop = function () {};
	NullScrollbars.prototype.clear = function () {};
	
	function updateScrollbars(cm, measure) {
	  if (!measure) { measure = measureForScrollbars(cm); }
	  var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
	  updateScrollbarsInner(cm, measure);
	  for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
	    if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
	      { updateHeightsInViewport(cm); }
	    updateScrollbarsInner(cm, measureForScrollbars(cm));
	    startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
	  }
	}
	
	// Re-synchronize the fake scrollbars with the actual size of the
	// content.
	function updateScrollbarsInner(cm, measure) {
	  var d = cm.display;
	  var sizes = d.scrollbars.update(measure);
	
	  d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
	  d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
	  d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent";
	
	  if (sizes.right && sizes.bottom) {
	    d.scrollbarFiller.style.display = "block";
	    d.scrollbarFiller.style.height = sizes.bottom + "px";
	    d.scrollbarFiller.style.width = sizes.right + "px";
	  } else { d.scrollbarFiller.style.display = ""; }
	  if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
	    d.gutterFiller.style.display = "block";
	    d.gutterFiller.style.height = sizes.bottom + "px";
	    d.gutterFiller.style.width = measure.gutterWidth + "px";
	  } else { d.gutterFiller.style.display = ""; }
	}
	
	var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
	
	function initScrollbars(cm) {
	  if (cm.display.scrollbars) {
	    cm.display.scrollbars.clear();
	    if (cm.display.scrollbars.addClass)
	      { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
	  }
	
	  cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) {
	    cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
	    // Prevent clicks in the scrollbars from killing focus
	    on(node, "mousedown", function () {
	      if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); }
	    });
	    node.setAttribute("cm-not-content", "true");
	  }, function (pos, axis) {
	    if (axis == "horizontal") { setScrollLeft(cm, pos); }
	    else { updateScrollTop(cm, pos); }
	  }, cm);
	  if (cm.display.scrollbars.addClass)
	    { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
	}
	
	// Operations are used to wrap a series of changes to the editor
	// state in such a way that each change won't have to update the
	// cursor and display (which would be awkward, slow, and
	// error-prone). Instead, display updates are batched and then all
	// combined and executed at once.
	
	var nextOpId = 0;
	// Start a new operation.
	function startOperation(cm) {
	  cm.curOp = {
	    cm: cm,
	    viewChanged: false,      // Flag that indicates that lines might need to be redrawn
	    startHeight: cm.doc.height, // Used to detect need to update scrollbar
	    forceUpdate: false,      // Used to force a redraw
	    updateInput: null,       // Whether to reset the input textarea
	    typing: false,           // Whether this reset should be careful to leave existing text (for compositing)
	    changeObjs: null,        // Accumulated changes, for firing change events
	    cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
	    cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
	    selectionChanged: false, // Whether the selection needs to be redrawn
	    updateMaxLine: false,    // Set when the widest line needs to be determined anew
	    scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
	    scrollToPos: null,       // Used to scroll to a specific position
	    focus: false,
	    id: ++nextOpId           // Unique ID
	  };
	  pushOperation(cm.curOp);
	}
	
	// Finish an operation, updating the display and signalling delayed events
	function endOperation(cm) {
	  var op = cm.curOp;
	  finishOperation(op, function (group) {
	    for (var i = 0; i < group.ops.length; i++)
	      { group.ops[i].cm.curOp = null; }
	    endOperations(group);
	  });
	}
	
	// The DOM updates done when an operation finishes are batched so
	// that the minimum number of relayouts are required.
	function endOperations(group) {
	  var ops = group.ops;
	  for (var i = 0; i < ops.length; i++) // Read DOM
	    { endOperation_R1(ops[i]); }
	  for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe)
	    { endOperation_W1(ops[i$1]); }
	  for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM
	    { endOperation_R2(ops[i$2]); }
	  for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe)
	    { endOperation_W2(ops[i$3]); }
	  for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM
	    { endOperation_finish(ops[i$4]); }
	}
	
	function endOperation_R1(op) {
	  var cm = op.cm, display = cm.display;
	  maybeClipScrollbars(cm);
	  if (op.updateMaxLine) { findMaxLine(cm); }
	
	  op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
	    op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
	                       op.scrollToPos.to.line >= display.viewTo) ||
	    display.maxLineChanged && cm.options.lineWrapping;
	  op.update = op.mustUpdate &&
	    new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
	}
	
	function endOperation_W1(op) {
	  op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
	}
	
	function endOperation_R2(op) {
	  var cm = op.cm, display = cm.display;
	  if (op.updatedDisplay) { updateHeightsInViewport(cm); }
	
	  op.barMeasure = measureForScrollbars(cm);
	
	  // If the max line changed since it was last measured, measure it,
	  // and ensure the document's width matches it.
	  // updateDisplay_W2 will use these properties to do the actual resizing
	  if (display.maxLineChanged && !cm.options.lineWrapping) {
	    op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
	    cm.display.sizerWidth = op.adjustWidthTo;
	    op.barMeasure.scrollWidth =
	      Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
	    op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
	  }
	
	  if (op.updatedDisplay || op.selectionChanged)
	    { op.preparedSelection = display.input.prepareSelection(op.focus); }
	}
	
	function endOperation_W2(op) {
	  var cm = op.cm;
	
	  if (op.adjustWidthTo != null) {
	    cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
	    if (op.maxScrollLeft < cm.doc.scrollLeft)
	      { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); }
	    cm.display.maxLineChanged = false;
	  }
	
	  var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus());
	  if (op.preparedSelection)
	    { cm.display.input.showSelection(op.preparedSelection, takeFocus); }
	  if (op.updatedDisplay || op.startHeight != cm.doc.height)
	    { updateScrollbars(cm, op.barMeasure); }
	  if (op.updatedDisplay)
	    { setDocumentHeight(cm, op.barMeasure); }
	
	  if (op.selectionChanged) { restartBlink(cm); }
	
	  if (cm.state.focused && op.updateInput)
	    { cm.display.input.reset(op.typing); }
	  if (takeFocus) { ensureFocus(op.cm); }
	}
	
	function endOperation_finish(op) {
	  var cm = op.cm, display = cm.display, doc = cm.doc;
	
	  if (op.updatedDisplay) { postUpdateDisplay(cm, op.update); }
	
	  // Abort mouse wheel delta measurement, when scrolling explicitly
	  if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
	    { display.wheelStartX = display.wheelStartY = null; }
	
	  // Propagate the scroll position to the actual DOM scroller
	  if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll); }
	
	  if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true); }
	  // If we need to scroll a specific position into view, do so.
	  if (op.scrollToPos) {
	    var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
	                                 clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
	    maybeScrollWindow(cm, rect);
	  }
	
	  // Fire events for markers that are hidden/unidden by editing or
	  // undoing
	  var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
	  if (hidden) { for (var i = 0; i < hidden.length; ++i)
	    { if (!hidden[i].lines.length) { signal(hidden[i], "hide"); } } }
	  if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1)
	    { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide"); } } }
	
	  if (display.wrapper.offsetHeight)
	    { doc.scrollTop = cm.display.scroller.scrollTop; }
	
	  // Fire change events, and delayed event handlers
	  if (op.changeObjs)
	    { signal(cm, "changes", cm, op.changeObjs); }
	  if (op.update)
	    { op.update.finish(); }
	}
	
	// Run the given function in an operation
	function runInOp(cm, f) {
	  if (cm.curOp) { return f() }
	  startOperation(cm);
	  try { return f() }
	  finally { endOperation(cm); }
	}
	// Wraps a function in an operation. Returns the wrapped function.
	function operation(cm, f) {
	  return function() {
	    if (cm.curOp) { return f.apply(cm, arguments) }
	    startOperation(cm);
	    try { return f.apply(cm, arguments) }
	    finally { endOperation(cm); }
	  }
	}
	// Used to add methods to editor and doc instances, wrapping them in
	// operations.
	function methodOp(f) {
	  return function() {
	    if (this.curOp) { return f.apply(this, arguments) }
	    startOperation(this);
	    try { return f.apply(this, arguments) }
	    finally { endOperation(this); }
	  }
	}
	function docMethodOp(f) {
	  return function() {
	    var cm = this.cm;
	    if (!cm || cm.curOp) { return f.apply(this, arguments) }
	    startOperation(cm);
	    try { return f.apply(this, arguments) }
	    finally { endOperation(cm); }
	  }
	}
	
	// Updates the display.view data structure for a given change to the
	// document. From and to are in pre-change coordinates. Lendiff is
	// the amount of lines added or subtracted by the change. This is
	// used for changes that span multiple lines, or change the way
	// lines are divided into visual lines. regLineChange (below)
	// registers single-line changes.
	function regChange(cm, from, to, lendiff) {
	  if (from == null) { from = cm.doc.first; }
	  if (to == null) { to = cm.doc.first + cm.doc.size; }
	  if (!lendiff) { lendiff = 0; }
	
	  var display = cm.display;
	  if (lendiff && to < display.viewTo &&
	      (display.updateLineNumbers == null || display.updateLineNumbers > from))
	    { display.updateLineNumbers = from; }
	
	  cm.curOp.viewChanged = true;
	
	  if (from >= display.viewTo) { // Change after
	    if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
	      { resetView(cm); }
	  } else if (to <= display.viewFrom) { // Change before
	    if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
	      resetView(cm);
	    } else {
	      display.viewFrom += lendiff;
	      display.viewTo += lendiff;
	    }
	  } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
	    resetView(cm);
	  } else if (from <= display.viewFrom) { // Top overlap
	    var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
	    if (cut) {
	      display.view = display.view.slice(cut.index);
	      display.viewFrom = cut.lineN;
	      display.viewTo += lendiff;
	    } else {
	      resetView(cm);
	    }
	  } else if (to >= display.viewTo) { // Bottom overlap
	    var cut$1 = viewCuttingPoint(cm, from, from, -1);
	    if (cut$1) {
	      display.view = display.view.slice(0, cut$1.index);
	      display.viewTo = cut$1.lineN;
	    } else {
	      resetView(cm);
	    }
	  } else { // Gap in the middle
	    var cutTop = viewCuttingPoint(cm, from, from, -1);
	    var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
	    if (cutTop && cutBot) {
	      display.view = display.view.slice(0, cutTop.index)
	        .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
	        .concat(display.view.slice(cutBot.index));
	      display.viewTo += lendiff;
	    } else {
	      resetView(cm);
	    }
	  }
	
	  var ext = display.externalMeasured;
	  if (ext) {
	    if (to < ext.lineN)
	      { ext.lineN += lendiff; }
	    else if (from < ext.lineN + ext.size)
	      { display.externalMeasured = null; }
	  }
	}
	
	// Register a change to a single line. Type must be one of "text",
	// "gutter", "class", "widget"
	function regLineChange(cm, line, type) {
	  cm.curOp.viewChanged = true;
	  var display = cm.display, ext = cm.display.externalMeasured;
	  if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
	    { display.externalMeasured = null; }
	
	  if (line < display.viewFrom || line >= display.viewTo) { return }
	  var lineView = display.view[findViewIndex(cm, line)];
	  if (lineView.node == null) { return }
	  var arr = lineView.changes || (lineView.changes = []);
	  if (indexOf(arr, type) == -1) { arr.push(type); }
	}
	
	// Clear the view.
	function resetView(cm) {
	  cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
	  cm.display.view = [];
	  cm.display.viewOffset = 0;
	}
	
	function viewCuttingPoint(cm, oldN, newN, dir) {
	  var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
	  if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
	    { return {index: index, lineN: newN} }
	  var n = cm.display.viewFrom;
	  for (var i = 0; i < index; i++)
	    { n += view[i].size; }
	  if (n != oldN) {
	    if (dir > 0) {
	      if (index == view.length - 1) { return null }
	      diff = (n + view[index].size) - oldN;
	      index++;
	    } else {
	      diff = n - oldN;
	    }
	    oldN += diff; newN += diff;
	  }
	  while (visualLineNo(cm.doc, newN) != newN) {
	    if (index == (dir < 0 ? 0 : view.length - 1)) { return null }
	    newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
	    index += dir;
	  }
	  return {index: index, lineN: newN}
	}
	
	// Force the view to cover a given range, adding empty view element
	// or clipping off existing ones as needed.
	function adjustView(cm, from, to) {
	  var display = cm.display, view = display.view;
	  if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
	    display.view = buildViewArray(cm, from, to);
	    display.viewFrom = from;
	  } else {
	    if (display.viewFrom > from)
	      { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); }
	    else if (display.viewFrom < from)
	      { display.view = display.view.slice(findViewIndex(cm, from)); }
	    display.viewFrom = from;
	    if (display.viewTo < to)
	      { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); }
	    else if (display.viewTo > to)
	      { display.view = display.view.slice(0, findViewIndex(cm, to)); }
	  }
	  display.viewTo = to;
	}
	
	// Count the number of lines in the view whose DOM representation is
	// out of date (or nonexistent).
	function countDirtyView(cm) {
	  var view = cm.display.view, dirty = 0;
	  for (var i = 0; i < view.length; i++) {
	    var lineView = view[i];
	    if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty; }
	  }
	  return dirty
	}
	
	// HIGHLIGHT WORKER
	
	function startWorker(cm, time) {
	  if (cm.doc.highlightFrontier < cm.display.viewTo)
	    { cm.state.highlight.set(time, bind(highlightWorker, cm)); }
	}
	
	function highlightWorker(cm) {
	  var doc = cm.doc;
	  if (doc.highlightFrontier >= cm.display.viewTo) { return }
	  var end = +new Date + cm.options.workTime;
	  var context = getContextBefore(cm, doc.highlightFrontier);
	  var changedLines = [];
	
	  doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
	    if (context.line >= cm.display.viewFrom) { // Visible
	      var oldStyles = line.styles;
	      var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null;
	      var highlighted = highlightLine(cm, line, context, true);
	      if (resetState) { context.state = resetState; }
	      line.styles = highlighted.styles;
	      var oldCls = line.styleClasses, newCls = highlighted.classes;
	      if (newCls) { line.styleClasses = newCls; }
	      else if (oldCls) { line.styleClasses = null; }
	      var ischange = !oldStyles || oldStyles.length != line.styles.length ||
	        oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
	      for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i]; }
	      if (ischange) { changedLines.push(context.line); }
	      line.stateAfter = context.save();
	      context.nextLine();
	    } else {
	      if (line.text.length <= cm.options.maxHighlightLength)
	        { processLine(cm, line.text, context); }
	      line.stateAfter = context.line % 5 == 0 ? context.save() : null;
	      context.nextLine();
	    }
	    if (+new Date > end) {
	      startWorker(cm, cm.options.workDelay);
	      return true
	    }
	  });
	  doc.highlightFrontier = context.line;
	  doc.modeFrontier = Math.max(doc.modeFrontier, context.line);
	  if (changedLines.length) { runInOp(cm, function () {
	    for (var i = 0; i < changedLines.length; i++)
	      { regLineChange(cm, changedLines[i], "text"); }
	  }); }
	}
	
	// DISPLAY DRAWING
	
	var DisplayUpdate = function(cm, viewport, force) {
	  var display = cm.display;
	
	  this.viewport = viewport;
	  // Store some values that we'll need later (but don't want to force a relayout for)
	  this.visible = visibleLines(display, cm.doc, viewport);
	  this.editorIsHidden = !display.wrapper.offsetWidth;
	  this.wrapperHeight = display.wrapper.clientHeight;
	  this.wrapperWidth = display.wrapper.clientWidth;
	  this.oldDisplayWidth = displayWidth(cm);
	  this.force = force;
	  this.dims = getDimensions(cm);
	  this.events = [];
	};
	
	DisplayUpdate.prototype.signal = function (emitter, type) {
	  if (hasHandler(emitter, type))
	    { this.events.push(arguments); }
	};
	DisplayUpdate.prototype.finish = function () {
	    var this$1 = this;
	
	  for (var i = 0; i < this.events.length; i++)
	    { signal.apply(null, this$1.events[i]); }
	};
	
	function maybeClipScrollbars(cm) {
	  var display = cm.display;
	  if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
	    display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
	    display.heightForcer.style.height = scrollGap(cm) + "px";
	    display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
	    display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
	    display.scrollbarsClipped = true;
	  }
	}
	
	function selectionSnapshot(cm) {
	  if (cm.hasFocus()) { return null }
	  var active = activeElt();
	  if (!active || !contains(cm.display.lineDiv, active)) { return null }
	  var result = {activeElt: active};
	  if (window.getSelection) {
	    var sel = window.getSelection();
	    if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
	      result.anchorNode = sel.anchorNode;
	      result.anchorOffset = sel.anchorOffset;
	      result.focusNode = sel.focusNode;
	      result.focusOffset = sel.focusOffset;
	    }
	  }
	  return result
	}
	
	function restoreSelection(snapshot) {
	  if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
	  snapshot.activeElt.focus();
	  if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
	    var sel = window.getSelection(), range$$1 = document.createRange();
	    range$$1.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
	    range$$1.collapse(false);
	    sel.removeAllRanges();
	    sel.addRange(range$$1);
	    sel.extend(snapshot.focusNode, snapshot.focusOffset);
	  }
	}
	
	// Does the actual updating of the line display. Bails out
	// (returning false) when there is nothing to be done and forced is
	// false.
	function updateDisplayIfNeeded(cm, update) {
	  var display = cm.display, doc = cm.doc;
	
	  if (update.editorIsHidden) {
	    resetView(cm);
	    return false
	  }
	
	  // Bail out if the visible area is already rendered and nothing changed.
	  if (!update.force &&
	      update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
	      (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
	      display.renderedView == display.view && countDirtyView(cm) == 0)
	    { return false }
	
	  if (maybeUpdateLineNumberWidth(cm)) {
	    resetView(cm);
	    update.dims = getDimensions(cm);
	  }
	
	  // Compute a suitable new viewport (from & to)
	  var end = doc.first + doc.size;
	  var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
	  var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
	  if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); }
	  if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); }
	  if (sawCollapsedSpans) {
	    from = visualLineNo(cm.doc, from);
	    to = visualLineEndNo(cm.doc, to);
	  }
	
	  var different = from != display.viewFrom || to != display.viewTo ||
	    display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
	  adjustView(cm, from, to);
	
	  display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
	  // Position the mover div to align with the current scroll position
	  cm.display.mover.style.top = display.viewOffset + "px";
	
	  var toUpdate = countDirtyView(cm);
	  if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
	      (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
	    { return false }
	
	  // For big changes, we hide the enclosing element during the
	  // update, since that speeds up the operations on most browsers.
	  var selSnapshot = selectionSnapshot(cm);
	  if (toUpdate > 4) { display.lineDiv.style.display = "none"; }
	  patchDisplay(cm, display.updateLineNumbers, update.dims);
	  if (toUpdate > 4) { display.lineDiv.style.display = ""; }
	  display.renderedView = display.view;
	  // There might have been a widget with a focused element that got
	  // hidden or updated, if so re-focus it.
	  restoreSelection(selSnapshot);
	
	  // Prevent selection and cursors from interfering with the scroll
	  // width and height.
	  removeChildren(display.cursorDiv);
	  removeChildren(display.selectionDiv);
	  display.gutters.style.height = display.sizer.style.minHeight = 0;
	
	  if (different) {
	    display.lastWrapHeight = update.wrapperHeight;
	    display.lastWrapWidth = update.wrapperWidth;
	    startWorker(cm, 400);
	  }
	
	  display.updateLineNumbers = null;
	
	  return true
	}
	
	function postUpdateDisplay(cm, update) {
	  var viewport = update.viewport;
	
	  for (var first = true;; first = false) {
	    if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
	      // Clip forced viewport to actual scrollable area.
	      if (viewport && viewport.top != null)
	        { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; }
	      // Updated line heights might result in the drawn area not
	      // actually covering the viewport. Keep looping until it does.
	      update.visible = visibleLines(cm.display, cm.doc, viewport);
	      if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
	        { break }
	    }
	    if (!updateDisplayIfNeeded(cm, update)) { break }
	    updateHeightsInViewport(cm);
	    var barMeasure = measureForScrollbars(cm);
	    updateSelection(cm);
	    updateScrollbars(cm, barMeasure);
	    setDocumentHeight(cm, barMeasure);
	    update.force = false;
	  }
	
	  update.signal(cm, "update", cm);
	  if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
	    update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
	    cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
	  }
	}
	
	function updateDisplaySimple(cm, viewport) {
	  var update = new DisplayUpdate(cm, viewport);
	  if (updateDisplayIfNeeded(cm, update)) {
	    updateHeightsInViewport(cm);
	    postUpdateDisplay(cm, update);
	    var barMeasure = measureForScrollbars(cm);
	    updateSelection(cm);
	    updateScrollbars(cm, barMeasure);
	    setDocumentHeight(cm, barMeasure);
	    update.finish();
	  }
	}
	
	// Sync the actual display DOM structure with display.view, removing
	// nodes for lines that are no longer in view, and creating the ones
	// that are not there yet, and updating the ones that are out of
	// date.
	function patchDisplay(cm, updateNumbersFrom, dims) {
	  var display = cm.display, lineNumbers = cm.options.lineNumbers;
	  var container = display.lineDiv, cur = container.firstChild;
	
	  function rm(node) {
	    var next = node.nextSibling;
	    // Works around a throw-scroll bug in OS X Webkit
	    if (webkit && mac && cm.display.currentWheelTarget == node)
	      { node.style.display = "none"; }
	    else
	      { node.parentNode.removeChild(node); }
	    return next
	  }
	
	  var view = display.view, lineN = display.viewFrom;
	  // Loop over the elements in the view, syncing cur (the DOM nodes
	  // in display.lineDiv) with the view as we go.
	  for (var i = 0; i < view.length; i++) {
	    var lineView = view[i];
	    if (lineView.hidden) {
	    } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
	      var node = buildLineElement(cm, lineView, lineN, dims);
	      container.insertBefore(node, cur);
	    } else { // Already drawn
	      while (cur != lineView.node) { cur = rm(cur); }
	      var updateNumber = lineNumbers && updateNumbersFrom != null &&
	        updateNumbersFrom <= lineN && lineView.lineNumber;
	      if (lineView.changes) {
	        if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false; }
	        updateLineForChanges(cm, lineView, lineN, dims);
	      }
	      if (updateNumber) {
	        removeChildren(lineView.lineNumber);
	        lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
	      }
	      cur = lineView.node.nextSibling;
	    }
	    lineN += lineView.size;
	  }
	  while (cur) { cur = rm(cur); }
	}
	
	function updateGutterSpace(cm) {
	  var width = cm.display.gutters.offsetWidth;
	  cm.display.sizer.style.marginLeft = width + "px";
	}
	
	function setDocumentHeight(cm, measure) {
	  cm.display.sizer.style.minHeight = measure.docHeight + "px";
	  cm.display.heightForcer.style.top = measure.docHeight + "px";
	  cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px";
	}
	
	// Rebuild the gutter elements, ensure the margin to the left of the
	// code matches their width.
	function updateGutters(cm) {
	  var gutters = cm.display.gutters, specs = cm.options.gutters;
	  removeChildren(gutters);
	  var i = 0;
	  for (; i < specs.length; ++i) {
	    var gutterClass = specs[i];
	    var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
	    if (gutterClass == "CodeMirror-linenumbers") {
	      cm.display.lineGutter = gElt;
	      gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
	    }
	  }
	  gutters.style.display = i ? "" : "none";
	  updateGutterSpace(cm);
	}
	
	// Make sure the gutters options contains the element
	// "CodeMirror-linenumbers" when the lineNumbers option is true.
	function setGuttersForLineNumbers(options) {
	  var found = indexOf(options.gutters, "CodeMirror-linenumbers");
	  if (found == -1 && options.lineNumbers) {
	    options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
	  } else if (found > -1 && !options.lineNumbers) {
	    options.gutters = options.gutters.slice(0);
	    options.gutters.splice(found, 1);
	  }
	}
	
	// Since the delta values reported on mouse wheel events are
	// unstandardized between browsers and even browser versions, and
	// generally horribly unpredictable, this code starts by measuring
	// the scroll effect that the first few mouse wheel events have,
	// and, from that, detects the way it can convert deltas to pixel
	// offsets afterwards.
	//
	// The reason we want to know the amount a wheel event will scroll
	// is that it gives us a chance to update the display before the
	// actual scrolling happens, reducing flickering.
	
	var wheelSamples = 0;
	var wheelPixelsPerUnit = null;
	// Fill in a browser-detected starting value on browsers where we
	// know one. These don't have to be accurate -- the result of them
	// being wrong would just be a slight flicker on the first wheel
	// scroll (if it is large enough).
	if (ie) { wheelPixelsPerUnit = -.53; }
	else if (gecko) { wheelPixelsPerUnit = 15; }
	else if (chrome) { wheelPixelsPerUnit = -.7; }
	else if (safari) { wheelPixelsPerUnit = -1/3; }
	
	function wheelEventDelta(e) {
	  var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
	  if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; }
	  if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; }
	  else if (dy == null) { dy = e.wheelDelta; }
	  return {x: dx, y: dy}
	}
	function wheelEventPixels(e) {
	  var delta = wheelEventDelta(e);
	  delta.x *= wheelPixelsPerUnit;
	  delta.y *= wheelPixelsPerUnit;
	  return delta
	}
	
	function onScrollWheel(cm, e) {
	  var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
	
	  var display = cm.display, scroll = display.scroller;
	  // Quit if there's nothing to scroll here
	  var canScrollX = scroll.scrollWidth > scroll.clientWidth;
	  var canScrollY = scroll.scrollHeight > scroll.clientHeight;
	  if (!(dx && canScrollX || dy && canScrollY)) { return }
	
	  // Webkit browsers on OS X abort momentum scrolls when the target
	  // of the scroll event is removed from the scrollable element.
	  // This hack (see related code in patchDisplay) makes sure the
	  // element is kept around.
	  if (dy && mac && webkit) {
	    outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
	      for (var i = 0; i < view.length; i++) {
	        if (view[i].node == cur) {
	          cm.display.currentWheelTarget = cur;
	          break outer
	        }
	      }
	    }
	  }
	
	  // On some browsers, horizontal scrolling will cause redraws to
	  // happen before the gutter has been realigned, causing it to
	  // wriggle around in a most unseemly way. When we have an
	  // estimated pixels/delta value, we just handle horizontal
	  // scrolling entirely here. It'll be slightly off from native, but
	  // better than glitching out.
	  if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
	    if (dy && canScrollY)
	      { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); }
	    setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit));
	    // Only prevent default scrolling if vertical scrolling is
	    // actually possible. Otherwise, it causes vertical scroll
	    // jitter on OSX trackpads when deltaX is small and deltaY
	    // is large (issue #3579)
	    if (!dy || (dy && canScrollY))
	      { e_preventDefault(e); }
	    display.wheelStartX = null; // Abort measurement, if in progress
	    return
	  }
	
	  // 'Project' the visible viewport to cover the area that is being
	  // scrolled into view (if we know enough to estimate it).
	  if (dy && wheelPixelsPerUnit != null) {
	    var pixels = dy * wheelPixelsPerUnit;
	    var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
	    if (pixels < 0) { top = Math.max(0, top + pixels - 50); }
	    else { bot = Math.min(cm.doc.height, bot + pixels + 50); }
	    updateDisplaySimple(cm, {top: top, bottom: bot});
	  }
	
	  if (wheelSamples < 20) {
	    if (display.wheelStartX == null) {
	      display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
	      display.wheelDX = dx; display.wheelDY = dy;
	      setTimeout(function () {
	        if (display.wheelStartX == null) { return }
	        var movedX = scroll.scrollLeft - display.wheelStartX;
	        var movedY = scroll.scrollTop - display.wheelStartY;
	        var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
	          (movedX && display.wheelDX && movedX / display.wheelDX);
	        display.wheelStartX = display.wheelStartY = null;
	        if (!sample) { return }
	        wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
	        ++wheelSamples;
	      }, 200);
	    } else {
	      display.wheelDX += dx; display.wheelDY += dy;
	    }
	  }
	}
	
	// Selection objects are immutable. A new one is created every time
	// the selection changes. A selection is one or more non-overlapping
	// (and non-touching) ranges, sorted, and an integer that indicates
	// which one is the primary selection (the one that's scrolled into
	// view, that getCursor returns, etc).
	var Selection = function(ranges, primIndex) {
	  this.ranges = ranges;
	  this.primIndex = primIndex;
	};
	
	Selection.prototype.primary = function () { return this.ranges[this.primIndex] };
	
	Selection.prototype.equals = function (other) {
	    var this$1 = this;
	
	  if (other == this) { return true }
	  if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }
	  for (var i = 0; i < this.ranges.length; i++) {
	    var here = this$1.ranges[i], there = other.ranges[i];
	    if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }
	  }
	  return true
	};
	
	Selection.prototype.deepCopy = function () {
	    var this$1 = this;
	
	  var out = [];
	  for (var i = 0; i < this.ranges.length; i++)
	    { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)); }
	  return new Selection(out, this.primIndex)
	};
	
	Selection.prototype.somethingSelected = function () {
	    var this$1 = this;
	
	  for (var i = 0; i < this.ranges.length; i++)
	    { if (!this$1.ranges[i].empty()) { return true } }
	  return false
	};
	
	Selection.prototype.contains = function (pos, end) {
	    var this$1 = this;
	
	  if (!end) { end = pos; }
	  for (var i = 0; i < this.ranges.length; i++) {
	    var range = this$1.ranges[i];
	    if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
	      { return i }
	  }
	  return -1
	};
	
	var Range = function(anchor, head) {
	  this.anchor = anchor; this.head = head;
	};
	
	Range.prototype.from = function () { return minPos(this.anchor, this.head) };
	Range.prototype.to = function () { return maxPos(this.anchor, this.head) };
	Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch };
	
	// Take an unsorted, potentially overlapping set of ranges, and
	// build a selection out of it. 'Consumes' ranges array (modifying
	// it).
	function normalizeSelection(ranges, primIndex) {
	  var prim = ranges[primIndex];
	  ranges.sort(function (a, b) { return cmp(a.from(), b.from()); });
	  primIndex = indexOf(ranges, prim);
	  for (var i = 1; i < ranges.length; i++) {
	    var cur = ranges[i], prev = ranges[i - 1];
	    if (cmp(prev.to(), cur.from()) >= 0) {
	      var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
	      var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
	      if (i <= primIndex) { --primIndex; }
	      ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
	    }
	  }
	  return new Selection(ranges, primIndex)
	}
	
	function simpleSelection(anchor, head) {
	  return new Selection([new Range(anchor, head || anchor)], 0)
	}
	
	// Compute the position of the end of a change (its 'to' property
	// refers to the pre-change end).
	function changeEnd(change) {
	  if (!change.text) { return change.to }
	  return Pos(change.from.line + change.text.length - 1,
	             lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0))
	}
	
	// Adjust a position to refer to the post-change position of the
	// same text, or the end of the change if the change covers it.
	function adjustForChange(pos, change) {
	  if (cmp(pos, change.from) < 0) { return pos }
	  if (cmp(pos, change.to) <= 0) { return changeEnd(change) }
	
	  var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
	  if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch; }
	  return Pos(line, ch)
	}
	
	function computeSelAfterChange(doc, change) {
	  var out = [];
	  for (var i = 0; i < doc.sel.ranges.length; i++) {
	    var range = doc.sel.ranges[i];
	    out.push(new Range(adjustForChange(range.anchor, change),
	                       adjustForChange(range.head, change)));
	  }
	  return normalizeSelection(out, doc.sel.primIndex)
	}
	
	function offsetPos(pos, old, nw) {
	  if (pos.line == old.line)
	    { return Pos(nw.line, pos.ch - old.ch + nw.ch) }
	  else
	    { return Pos(nw.line + (pos.line - old.line), pos.ch) }
	}
	
	// Used by replaceSelections to allow moving the selection to the
	// start or around the replaced test. Hint may be "start" or "around".
	function computeReplacedSel(doc, changes, hint) {
	  var out = [];
	  var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
	  for (var i = 0; i < changes.length; i++) {
	    var change = changes[i];
	    var from = offsetPos(change.from, oldPrev, newPrev);
	    var to = offsetPos(changeEnd(change), oldPrev, newPrev);
	    oldPrev = change.to;
	    newPrev = to;
	    if (hint == "around") {
	      var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
	      out[i] = new Range(inv ? to : from, inv ? from : to);
	    } else {
	      out[i] = new Range(from, from);
	    }
	  }
	  return new Selection(out, doc.sel.primIndex)
	}
	
	// Used to get the editor into a consistent state again when options change.
	
	function loadMode(cm) {
	  cm.doc.mode = getMode(cm.options, cm.doc.modeOption);
	  resetModeState(cm);
	}
	
	function resetModeState(cm) {
	  cm.doc.iter(function (line) {
	    if (line.stateAfter) { line.stateAfter = null; }
	    if (line.styles) { line.styles = null; }
	  });
	  cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first;
	  startWorker(cm, 100);
	  cm.state.modeGen++;
	  if (cm.curOp) { regChange(cm); }
	}
	
	// DOCUMENT DATA STRUCTURE
	
	// By default, updates that start and end at the beginning of a line
	// are treated specially, in order to make the association of line
	// widgets and marker elements with the text behave more intuitive.
	function isWholeLineUpdate(doc, change) {
	  return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
	    (!doc.cm || doc.cm.options.wholeLineUpdateBefore)
	}
	
	// Perform a change on the document data structure.
	function updateDoc(doc, change, markedSpans, estimateHeight$$1) {
	  function spansFor(n) {return markedSpans ? markedSpans[n] : null}
	  function update(line, text, spans) {
	    updateLine(line, text, spans, estimateHeight$$1);
	    signalLater(line, "change", line, change);
	  }
	  function linesFor(start, end) {
	    var result = [];
	    for (var i = start; i < end; ++i)
	      { result.push(new Line(text[i], spansFor(i), estimateHeight$$1)); }
	    return result
	  }
	
	  var from = change.from, to = change.to, text = change.text;
	  var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
	  var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
	
	  // Adjust the line structure
	  if (change.full) {
	    doc.insert(0, linesFor(0, text.length));
	    doc.remove(text.length, doc.size - text.length);
	  } else if (isWholeLineUpdate(doc, change)) {
	    // This is a whole-line replace. Treated specially to make
	    // sure line objects move the way they are supposed to.
	    var added = linesFor(0, text.length - 1);
	    update(lastLine, lastLine.text, lastSpans);
	    if (nlines) { doc.remove(from.line, nlines); }
	    if (added.length) { doc.insert(from.line, added); }
	  } else if (firstLine == lastLine) {
	    if (text.length == 1) {
	      update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
	    } else {
	      var added$1 = linesFor(1, text.length - 1);
	      added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight$$1));
	      update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
	      doc.insert(from.line + 1, added$1);
	    }
	  } else if (text.length == 1) {
	    update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
	    doc.remove(from.line + 1, nlines);
	  } else {
	    update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
	    update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
	    var added$2 = linesFor(1, text.length - 1);
	    if (nlines > 1) { doc.remove(from.line + 1, nlines - 1); }
	    doc.insert(from.line + 1, added$2);
	  }
	
	  signalLater(doc, "change", doc, change);
	}
	
	// Call f for all linked documents.
	function linkedDocs(doc, f, sharedHistOnly) {
	  function propagate(doc, skip, sharedHist) {
	    if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) {
	      var rel = doc.linked[i];
	      if (rel.doc == skip) { continue }
	      var shared = sharedHist && rel.sharedHist;
	      if (sharedHistOnly && !shared) { continue }
	      f(rel.doc, shared);
	      propagate(rel.doc, doc, shared);
	    } }
	  }
	  propagate(doc, null, true);
	}
	
	// Attach a document to an editor.
	function attachDoc(cm, doc) {
	  if (doc.cm) { throw new Error("This document is already in use.") }
	  cm.doc = doc;
	  doc.cm = cm;
	  estimateLineHeights(cm);
	  loadMode(cm);
	  setDirectionClass(cm);
	  if (!cm.options.lineWrapping) { findMaxLine(cm); }
	  cm.options.mode = doc.modeOption;
	  regChange(cm);
	}
	
	function setDirectionClass(cm) {
	  (cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl");
	}
	
	function directionChanged(cm) {
	  runInOp(cm, function () {
	    setDirectionClass(cm);
	    regChange(cm);
	  });
	}
	
	function History(startGen) {
	  // Arrays of change events and selections. Doing something adds an
	  // event to done and clears undo. Undoing moves events from done
	  // to undone, redoing moves them in the other direction.
	  this.done = []; this.undone = [];
	  this.undoDepth = Infinity;
	  // Used to track when changes can be merged into a single undo
	  // event
	  this.lastModTime = this.lastSelTime = 0;
	  this.lastOp = this.lastSelOp = null;
	  this.lastOrigin = this.lastSelOrigin = null;
	  // Used by the isClean() method
	  this.generation = this.maxGeneration = startGen || 1;
	}
	
	// Create a history change event from an updateDoc-style change
	// object.
	function historyChangeFromChange(doc, change) {
	  var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
	  attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
	  linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true);
	  return histChange
	}
	
	// Pop all selection events off the end of a history array. Stop at
	// a change event.
	function clearSelectionEvents(array) {
	  while (array.length) {
	    var last = lst(array);
	    if (last.ranges) { array.pop(); }
	    else { break }
	  }
	}
	
	// Find the top change event in the history. Pop off selection
	// events that are in the way.
	function lastChangeEvent(hist, force) {
	  if (force) {
	    clearSelectionEvents(hist.done);
	    return lst(hist.done)
	  } else if (hist.done.length && !lst(hist.done).ranges) {
	    return lst(hist.done)
	  } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
	    hist.done.pop();
	    return lst(hist.done)
	  }
	}
	
	// Register a change in the history. Merges changes that are within
	// a single operation, or are close together with an origin that
	// allows merging (starting with "+") into a single event.
	function addChangeToHistory(doc, change, selAfter, opId) {
	  var hist = doc.history;
	  hist.undone.length = 0;
	  var time = +new Date, cur;
	  var last;
	
	  if ((hist.lastOp == opId ||
	       hist.lastOrigin == change.origin && change.origin &&
	       ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
	        change.origin.charAt(0) == "*")) &&
	      (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
	    // Merge this change into the last event
	    last = lst(cur.changes);
	    if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
	      // Optimized case for simple insertion -- don't want to add
	      // new changesets for every character typed
	      last.to = changeEnd(change);
	    } else {
	      // Add new sub-event
	      cur.changes.push(historyChangeFromChange(doc, change));
	    }
	  } else {
	    // Can not be merged, start a new event.
	    var before = lst(hist.done);
	    if (!before || !before.ranges)
	      { pushSelectionToHistory(doc.sel, hist.done); }
	    cur = {changes: [historyChangeFromChange(doc, change)],
	           generation: hist.generation};
	    hist.done.push(cur);
	    while (hist.done.length > hist.undoDepth) {
	      hist.done.shift();
	      if (!hist.done[0].ranges) { hist.done.shift(); }
	    }
	  }
	  hist.done.push(selAfter);
	  hist.generation = ++hist.maxGeneration;
	  hist.lastModTime = hist.lastSelTime = time;
	  hist.lastOp = hist.lastSelOp = opId;
	  hist.lastOrigin = hist.lastSelOrigin = change.origin;
	
	  if (!last) { signal(doc, "historyAdded"); }
	}
	
	function selectionEventCanBeMerged(doc, origin, prev, sel) {
	  var ch = origin.charAt(0);
	  return ch == "*" ||
	    ch == "+" &&
	    prev.ranges.length == sel.ranges.length &&
	    prev.somethingSelected() == sel.somethingSelected() &&
	    new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500)
	}
	
	// Called whenever the selection changes, sets the new selection as
	// the pending selection in the history, and pushes the old pending
	// selection into the 'done' array when it was significantly
	// different (in number of selected ranges, emptiness, or time).
	function addSelectionToHistory(doc, sel, opId, options) {
	  var hist = doc.history, origin = options && options.origin;
	
	  // A new event is started when the previous origin does not match
	  // the current, or the origins don't allow matching. Origins
	  // starting with * are always merged, those starting with + are
	  // merged when similar and close together in time.
	  if (opId == hist.lastSelOp ||
	      (origin && hist.lastSelOrigin == origin &&
	       (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
	        selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
	    { hist.done[hist.done.length - 1] = sel; }
	  else
	    { pushSelectionToHistory(sel, hist.done); }
	
	  hist.lastSelTime = +new Date;
	  hist.lastSelOrigin = origin;
	  hist.lastSelOp = opId;
	  if (options && options.clearRedo !== false)
	    { clearSelectionEvents(hist.undone); }
	}
	
	function pushSelectionToHistory(sel, dest) {
	  var top = lst(dest);
	  if (!(top && top.ranges && top.equals(sel)))
	    { dest.push(sel); }
	}
	
	// Used to store marked span information in the history.
	function attachLocalSpans(doc, change, from, to) {
	  var existing = change["spans_" + doc.id], n = 0;
	  doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {
	    if (line.markedSpans)
	      { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; }
	    ++n;
	  });
	}
	
	// When un/re-doing restores text containing marked spans, those
	// that have been explicitly cleared should not be restored.
	function removeClearedSpans(spans) {
	  if (!spans) { return null }
	  var out;
	  for (var i = 0; i < spans.length; ++i) {
	    if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i); } }
	    else if (out) { out.push(spans[i]); }
	  }
	  return !out ? spans : out.length ? out : null
	}
	
	// Retrieve and filter the old marked spans stored in a change event.
	function getOldSpans(doc, change) {
	  var found = change["spans_" + doc.id];
	  if (!found) { return null }
	  var nw = [];
	  for (var i = 0; i < change.text.length; ++i)
	    { nw.push(removeClearedSpans(found[i])); }
	  return nw
	}
	
	// Used for un/re-doing changes from the history. Combines the
	// result of computing the existing spans with the set of spans that
	// existed in the history (so that deleting around a span and then
	// undoing brings back the span).
	function mergeOldSpans(doc, change) {
	  var old = getOldSpans(doc, change);
	  var stretched = stretchSpansOverChange(doc, change);
	  if (!old) { return stretched }
	  if (!stretched) { return old }
	
	  for (var i = 0; i < old.length; ++i) {
	    var oldCur = old[i], stretchCur = stretched[i];
	    if (oldCur && stretchCur) {
	      spans: for (var j = 0; j < stretchCur.length; ++j) {
	        var span = stretchCur[j];
	        for (var k = 0; k < oldCur.length; ++k)
	          { if (oldCur[k].marker == span.marker) { continue spans } }
	        oldCur.push(span);
	      }
	    } else if (stretchCur) {
	      old[i] = stretchCur;
	    }
	  }
	  return old
	}
	
	// Used both to provide a JSON-safe object in .getHistory, and, when
	// detaching a document, to split the history in two
	function copyHistoryArray(events, newGroup, instantiateSel) {
	  var copy = [];
	  for (var i = 0; i < events.length; ++i) {
	    var event = events[i];
	    if (event.ranges) {
	      copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
	      continue
	    }
	    var changes = event.changes, newChanges = [];
	    copy.push({changes: newChanges});
	    for (var j = 0; j < changes.length; ++j) {
	      var change = changes[j], m = (void 0);
	      newChanges.push({from: change.from, to: change.to, text: change.text});
	      if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) {
	        if (indexOf(newGroup, Number(m[1])) > -1) {
	          lst(newChanges)[prop] = change[prop];
	          delete change[prop];
	        }
	      } } }
	    }
	  }
	  return copy
	}
	
	// The 'scroll' parameter given to many of these indicated whether
	// the new cursor position should be scrolled into view after
	// modifying the selection.
	
	// If shift is held or the extend flag is set, extends a range to
	// include a given position (and optionally a second position).
	// Otherwise, simply returns the range between the given positions.
	// Used for cursor motion and such.
	function extendRange(range, head, other, extend) {
	  if (extend) {
	    var anchor = range.anchor;
	    if (other) {
	      var posBefore = cmp(head, anchor) < 0;
	      if (posBefore != (cmp(other, anchor) < 0)) {
	        anchor = head;
	        head = other;
	      } else if (posBefore != (cmp(head, other) < 0)) {
	        head = other;
	      }
	    }
	    return new Range(anchor, head)
	  } else {
	    return new Range(other || head, head)
	  }
	}
	
	// Extend the primary selection range, discard the rest.
	function extendSelection(doc, head, other, options, extend) {
	  if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend); }
	  setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options);
	}
	
	// Extend all selections (pos is an array of selections with length
	// equal the number of selections)
	function extendSelections(doc, heads, options) {
	  var out = [];
	  var extend = doc.cm && (doc.cm.display.shift || doc.extend);
	  for (var i = 0; i < doc.sel.ranges.length; i++)
	    { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); }
	  var newSel = normalizeSelection(out, doc.sel.primIndex);
	  setSelection(doc, newSel, options);
	}
	
	// Updates a single range in the selection.
	function replaceOneSelection(doc, i, range, options) {
	  var ranges = doc.sel.ranges.slice(0);
	  ranges[i] = range;
	  setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
	}
	
	// Reset the selection to a single range.
	function setSimpleSelection(doc, anchor, head, options) {
	  setSelection(doc, simpleSelection(anchor, head), options);
	}
	
	// Give beforeSelectionChange handlers a change to influence a
	// selection update.
	function filterSelectionChange(doc, sel, options) {
	  var obj = {
	    ranges: sel.ranges,
	    update: function(ranges) {
	      var this$1 = this;
	
	      this.ranges = [];
	      for (var i = 0; i < ranges.length; i++)
	        { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
	                                   clipPos(doc, ranges[i].head)); }
	    },
	    origin: options && options.origin
	  };
	  signal(doc, "beforeSelectionChange", doc, obj);
	  if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); }
	  if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) }
	  else { return sel }
	}
	
	function setSelectionReplaceHistory(doc, sel, options) {
	  var done = doc.history.done, last = lst(done);
	  if (last && last.ranges) {
	    done[done.length - 1] = sel;
	    setSelectionNoUndo(doc, sel, options);
	  } else {
	    setSelection(doc, sel, options);
	  }
	}
	
	// Set a new selection.
	function setSelection(doc, sel, options) {
	  setSelectionNoUndo(doc, sel, options);
	  addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
	}
	
	function setSelectionNoUndo(doc, sel, options) {
	  if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
	    { sel = filterSelectionChange(doc, sel, options); }
	
	  var bias = options && options.bias ||
	    (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
	  setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
	
	  if (!(options && options.scroll === false) && doc.cm)
	    { ensureCursorVisible(doc.cm); }
	}
	
	function setSelectionInner(doc, sel) {
	  if (sel.equals(doc.sel)) { return }
	
	  doc.sel = sel;
	
	  if (doc.cm) {
	    doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
	    signalCursorActivity(doc.cm);
	  }
	  signalLater(doc, "cursorActivity", doc);
	}
	
	// Verify that the selection does not partially select any atomic
	// marked ranges.
	function reCheckSelection(doc) {
	  setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false));
	}
	
	// Return a selection that does not partially select any atomic
	// ranges.
	function skipAtomicInSelection(doc, sel, bias, mayClear) {
	  var out;
	  for (var i = 0; i < sel.ranges.length; i++) {
	    var range = sel.ranges[i];
	    var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
	    var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
	    var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
	    if (out || newAnchor != range.anchor || newHead != range.head) {
	      if (!out) { out = sel.ranges.slice(0, i); }
	      out[i] = new Range(newAnchor, newHead);
	    }
	  }
	  return out ? normalizeSelection(out, sel.primIndex) : sel
	}
	
	function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
	  var line = getLine(doc, pos.line);
	  if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
	    var sp = line.markedSpans[i], m = sp.marker;
	    if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
	        (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
	      if (mayClear) {
	        signal(m, "beforeCursorEnter");
	        if (m.explicitlyCleared) {
	          if (!line.markedSpans) { break }
	          else {--i; continue}
	        }
	      }
	      if (!m.atomic) { continue }
	
	      if (oldPos) {
	        var near = m.find(dir < 0 ? 1 : -1), diff = (void 0);
	        if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft)
	          { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); }
	        if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
	          { return skipAtomicInner(doc, near, pos, dir, mayClear) }
	      }
	
	      var far = m.find(dir < 0 ? -1 : 1);
	      if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight)
	        { far = movePos(doc, far, dir, far.line == pos.line ? line : null); }
	      return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null
	    }
	  } }
	  return pos
	}
	
	// Ensure a given position is not inside an atomic range.
	function skipAtomic(doc, pos, oldPos, bias, mayClear) {
	  var dir = bias || 1;
	  var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
	      (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
	      skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
	      (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
	  if (!found) {
	    doc.cantEdit = true;
	    return Pos(doc.first, 0)
	  }
	  return found
	}
	
	function movePos(doc, pos, dir, line) {
	  if (dir < 0 && pos.ch == 0) {
	    if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) }
	    else { return null }
	  } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
	    if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) }
	    else { return null }
	  } else {
	    return new Pos(pos.line, pos.ch + dir)
	  }
	}
	
	function selectAll(cm) {
	  cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);
	}
	
	// UPDATING
	
	// Allow "beforeChange" event handlers to influence a change
	function filterChange(doc, change, update) {
	  var obj = {
	    canceled: false,
	    from: change.from,
	    to: change.to,
	    text: change.text,
	    origin: change.origin,
	    cancel: function () { return obj.canceled = true; }
	  };
	  if (update) { obj.update = function (from, to, text, origin) {
	    if (from) { obj.from = clipPos(doc, from); }
	    if (to) { obj.to = clipPos(doc, to); }
	    if (text) { obj.text = text; }
	    if (origin !== undefined) { obj.origin = origin; }
	  }; }
	  signal(doc, "beforeChange", doc, obj);
	  if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj); }
	
	  if (obj.canceled) { return null }
	  return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}
	}
	
	// Apply a change to a document, and add it to the document's
	// history, and propagating it to all linked documents.
	function makeChange(doc, change, ignoreReadOnly) {
	  if (doc.cm) {
	    if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) }
	    if (doc.cm.state.suppressEdits) { return }
	  }
	
	  if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
	    change = filterChange(doc, change, true);
	    if (!change) { return }
	  }
	
	  // Possibly split or suppress the update based on the presence
	  // of read-only spans in its range.
	  var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
	  if (split) {
	    for (var i = split.length - 1; i >= 0; --i)
	      { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); }
	  } else {
	    makeChangeInner(doc, change);
	  }
	}
	
	function makeChangeInner(doc, change) {
	  if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return }
	  var selAfter = computeSelAfterChange(doc, change);
	  addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
	
	  makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
	  var rebased = [];
	
	  linkedDocs(doc, function (doc, sharedHist) {
	    if (!sharedHist && indexOf(rebased, doc.history) == -1) {
	      rebaseHist(doc.history, change);
	      rebased.push(doc.history);
	    }
	    makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
	  });
	}
	
	// Revert a change stored in a document's history.
	function makeChangeFromHistory(doc, type, allowSelectionOnly) {
	  if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return }
	
	  var hist = doc.history, event, selAfter = doc.sel;
	  var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
	
	  // Verify that there is a useable event (so that ctrl-z won't
	  // needlessly clear selection events)
	  var i = 0;
	  for (; i < source.length; i++) {
	    event = source[i];
	    if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
	      { break }
	  }
	  if (i == source.length) { return }
	  hist.lastOrigin = hist.lastSelOrigin = null;
	
	  for (;;) {
	    event = source.pop();
	    if (event.ranges) {
	      pushSelectionToHistory(event, dest);
	      if (allowSelectionOnly && !event.equals(doc.sel)) {
	        setSelection(doc, event, {clearRedo: false});
	        return
	      }
	      selAfter = event;
	    }
	    else { break }
	  }
	
	  // Build up a reverse change object to add to the opposite history
	  // stack (redo when undoing, and vice versa).
	  var antiChanges = [];
	  pushSelectionToHistory(selAfter, dest);
	  dest.push({changes: antiChanges, generation: hist.generation});
	  hist.generation = event.generation || ++hist.maxGeneration;
	
	  var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
	
	  var loop = function ( i ) {
	    var change = event.changes[i];
	    change.origin = type;
	    if (filter && !filterChange(doc, change, false)) {
	      source.length = 0;
	      return {}
	    }
	
	    antiChanges.push(historyChangeFromChange(doc, change));
	
	    var after = i ? computeSelAfterChange(doc, change) : lst(source);
	    makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
	    if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); }
	    var rebased = [];
	
	    // Propagate to the linked documents
	    linkedDocs(doc, function (doc, sharedHist) {
	      if (!sharedHist && indexOf(rebased, doc.history) == -1) {
	        rebaseHist(doc.history, change);
	        rebased.push(doc.history);
	      }
	      makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
	    });
	  };
	
	  for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) {
	    var returned = loop( i$1 );
	
	    if ( returned ) return returned.v;
	  }
	}
	
	// Sub-views need their line numbers shifted when text is added
	// above or below them in the parent document.
	function shiftDoc(doc, distance) {
	  if (distance == 0) { return }
	  doc.first += distance;
	  doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range(
	    Pos(range.anchor.line + distance, range.anchor.ch),
	    Pos(range.head.line + distance, range.head.ch)
	  ); }), doc.sel.primIndex);
	  if (doc.cm) {
	    regChange(doc.cm, doc.first, doc.first - distance, distance);
	    for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
	      { regLineChange(doc.cm, l, "gutter"); }
	  }
	}
	
	// More lower-level change function, handling only a single document
	// (not linked ones).
	function makeChangeSingleDoc(doc, change, selAfter, spans) {
	  if (doc.cm && !doc.cm.curOp)
	    { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) }
	
	  if (change.to.line < doc.first) {
	    shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
	    return
	  }
	  if (change.from.line > doc.lastLine()) { return }
	
	  // Clip the change to the size of this doc
	  if (change.from.line < doc.first) {
	    var shift = change.text.length - 1 - (doc.first - change.from.line);
	    shiftDoc(doc, shift);
	    change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
	              text: [lst(change.text)], origin: change.origin};
	  }
	  var last = doc.lastLine();
	  if (change.to.line > last) {
	    change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
	              text: [change.text[0]], origin: change.origin};
	  }
	
	  change.removed = getBetween(doc, change.from, change.to);
	
	  if (!selAfter) { selAfter = computeSelAfterChange(doc, change); }
	  if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); }
	  else { updateDoc(doc, change, spans); }
	  setSelectionNoUndo(doc, selAfter, sel_dontScroll);
	}
	
	// Handle the interaction of a change to a document with the editor
	// that this document is part of.
	function makeChangeSingleDocInEditor(cm, change, spans) {
	  var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
	
	  var recomputeMaxLength = false, checkWidthStart = from.line;
	  if (!cm.options.lineWrapping) {
	    checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
	    doc.iter(checkWidthStart, to.line + 1, function (line) {
	      if (line == display.maxLine) {
	        recomputeMaxLength = true;
	        return true
	      }
	    });
	  }
	
	  if (doc.sel.contains(change.from, change.to) > -1)
	    { signalCursorActivity(cm); }
	
	  updateDoc(doc, change, spans, estimateHeight(cm));
	
	  if (!cm.options.lineWrapping) {
	    doc.iter(checkWidthStart, from.line + change.text.length, function (line) {
	      var len = lineLength(line);
	      if (len > display.maxLineLength) {
	        display.maxLine = line;
	        display.maxLineLength = len;
	        display.maxLineChanged = true;
	        recomputeMaxLength = false;
	      }
	    });
	    if (recomputeMaxLength) { cm.curOp.updateMaxLine = true; }
	  }
	
	  retreatFrontier(doc, from.line);
	  startWorker(cm, 400);
	
	  var lendiff = change.text.length - (to.line - from.line) - 1;
	  // Remember that these lines changed, for updating the display
	  if (change.full)
	    { regChange(cm); }
	  else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
	    { regLineChange(cm, from.line, "text"); }
	  else
	    { regChange(cm, from.line, to.line + 1, lendiff); }
	
	  var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
	  if (changeHandler || changesHandler) {
	    var obj = {
	      from: from, to: to,
	      text: change.text,
	      removed: change.removed,
	      origin: change.origin
	    };
	    if (changeHandler) { signalLater(cm, "change", cm, obj); }
	    if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); }
	  }
	  cm.display.selForContextMenu = null;
	}
	
	function replaceRange(doc, code, from, to, origin) {
	  if (!to) { to = from; }
	  if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
	  if (typeof code == "string") { code = doc.splitLines(code); }
	  makeChange(doc, {from: from, to: to, text: code, origin: origin});
	}
	
	// Rebasing/resetting history to deal with externally-sourced changes
	
	function rebaseHistSelSingle(pos, from, to, diff) {
	  if (to < pos.line) {
	    pos.line += diff;
	  } else if (from < pos.line) {
	    pos.line = from;
	    pos.ch = 0;
	  }
	}
	
	// Tries to rebase an array of history events given a change in the
	// document. If the change touches the same lines as the event, the
	// event, and everything 'behind' it, is discarded. If the change is
	// before the event, the event's positions are updated. Uses a
	// copy-on-write scheme for the positions, to avoid having to
	// reallocate them all on every rebase, but also avoid problems with
	// shared position objects being unsafely updated.
	function rebaseHistArray(array, from, to, diff) {
	  for (var i = 0; i < array.length; ++i) {
	    var sub = array[i], ok = true;
	    if (sub.ranges) {
	      if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
	      for (var j = 0; j < sub.ranges.length; j++) {
	        rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
	        rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
	      }
	      continue
	    }
	    for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) {
	      var cur = sub.changes[j$1];
	      if (to < cur.from.line) {
	        cur.from = Pos(cur.from.line + diff, cur.from.ch);
	        cur.to = Pos(cur.to.line + diff, cur.to.ch);
	      } else if (from <= cur.to.line) {
	        ok = false;
	        break
	      }
	    }
	    if (!ok) {
	      array.splice(0, i + 1);
	      i = 0;
	    }
	  }
	}
	
	function rebaseHist(hist, change) {
	  var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
	  rebaseHistArray(hist.done, from, to, diff);
	  rebaseHistArray(hist.undone, from, to, diff);
	}
	
	// Utility for applying a change to a line by handle or number,
	// returning the number and optionally registering the line as
	// changed.
	function changeLine(doc, handle, changeType, op) {
	  var no = handle, line = handle;
	  if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)); }
	  else { no = lineNo(handle); }
	  if (no == null) { return null }
	  if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType); }
	  return line
	}
	
	// The document is represented as a BTree consisting of leaves, with
	// chunk of lines in them, and branches, with up to ten leaves or
	// other branch nodes below them. The top node is always a branch
	// node, and is the document object itself (meaning it has
	// additional methods and properties).
	//
	// All nodes have parent links. The tree is used both to go from
	// line numbers to line objects, and to go from objects to numbers.
	// It also indexes by height, and is used to convert between height
	// and line object, and to find the total height of the document.
	//
	// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
	
	function LeafChunk(lines) {
	  var this$1 = this;
	
	  this.lines = lines;
	  this.parent = null;
	  var height = 0;
	  for (var i = 0; i < lines.length; ++i) {
	    lines[i].parent = this$1;
	    height += lines[i].height;
	  }
	  this.height = height;
	}
	
	LeafChunk.prototype = {
	  chunkSize: function chunkSize() { return this.lines.length },
	
	  // Remove the n lines at offset 'at'.
	  removeInner: function removeInner(at, n) {
	    var this$1 = this;
	
	    for (var i = at, e = at + n; i < e; ++i) {
	      var line = this$1.lines[i];
	      this$1.height -= line.height;
	      cleanUpLine(line);
	      signalLater(line, "delete");
	    }
	    this.lines.splice(at, n);
	  },
	
	  // Helper used to collapse a small branch into a single leaf.
	  collapse: function collapse(lines) {
	    lines.push.apply(lines, this.lines);
	  },
	
	  // Insert the given array of lines at offset 'at', count them as
	  // having the given height.
	  insertInner: function insertInner(at, lines, height) {
	    var this$1 = this;
	
	    this.height += height;
	    this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
	    for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1; }
	  },
	
	  // Used to iterate over a part of the tree.
	  iterN: function iterN(at, n, op) {
	    var this$1 = this;
	
	    for (var e = at + n; at < e; ++at)
	      { if (op(this$1.lines[at])) { return true } }
	  }
	};
	
	function BranchChunk(children) {
	  var this$1 = this;
	
	  this.children = children;
	  var size = 0, height = 0;
	  for (var i = 0; i < children.length; ++i) {
	    var ch = children[i];
	    size += ch.chunkSize(); height += ch.height;
	    ch.parent = this$1;
	  }
	  this.size = size;
	  this.height = height;
	  this.parent = null;
	}
	
	BranchChunk.prototype = {
	  chunkSize: function chunkSize() { return this.size },
	
	  removeInner: function removeInner(at, n) {
	    var this$1 = this;
	
	    this.size -= n;
	    for (var i = 0; i < this.children.length; ++i) {
	      var child = this$1.children[i], sz = child.chunkSize();
	      if (at < sz) {
	        var rm = Math.min(n, sz - at), oldHeight = child.height;
	        child.removeInner(at, rm);
	        this$1.height -= oldHeight - child.height;
	        if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null; }
	        if ((n -= rm) == 0) { break }
	        at = 0;
	      } else { at -= sz; }
	    }
	    // If the result is smaller than 25 lines, ensure that it is a
	    // single leaf node.
	    if (this.size - n < 25 &&
	        (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
	      var lines = [];
	      this.collapse(lines);
	      this.children = [new LeafChunk(lines)];
	      this.children[0].parent = this;
	    }
	  },
	
	  collapse: function collapse(lines) {
	    var this$1 = this;
	
	    for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines); }
	  },
	
	  insertInner: function insertInner(at, lines, height) {
	    var this$1 = this;
	
	    this.size += lines.length;
	    this.height += height;
	    for (var i = 0; i < this.children.length; ++i) {
	      var child = this$1.children[i], sz = child.chunkSize();
	      if (at <= sz) {
	        child.insertInner(at, lines, height);
	        if (child.lines && child.lines.length > 50) {
	          // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
	          // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
	          var remaining = child.lines.length % 25 + 25;
	          for (var pos = remaining; pos < child.lines.length;) {
	            var leaf = new LeafChunk(child.lines.slice(pos, pos += 25));
	            child.height -= leaf.height;
	            this$1.children.splice(++i, 0, leaf);
	            leaf.parent = this$1;
	          }
	          child.lines = child.lines.slice(0, remaining);
	          this$1.maybeSpill();
	        }
	        break
	      }
	      at -= sz;
	    }
	  },
	
	  // When a node has grown, check whether it should be split.
	  maybeSpill: function maybeSpill() {
	    if (this.children.length <= 10) { return }
	    var me = this;
	    do {
	      var spilled = me.children.splice(me.children.length - 5, 5);
	      var sibling = new BranchChunk(spilled);
	      if (!me.parent) { // Become the parent node
	        var copy = new BranchChunk(me.children);
	        copy.parent = me;
	        me.children = [copy, sibling];
	        me = copy;
	     } else {
	        me.size -= sibling.size;
	        me.height -= sibling.height;
	        var myIndex = indexOf(me.parent.children, me);
	        me.parent.children.splice(myIndex + 1, 0, sibling);
	      }
	      sibling.parent = me.parent;
	    } while (me.children.length > 10)
	    me.parent.maybeSpill();
	  },
	
	  iterN: function iterN(at, n, op) {
	    var this$1 = this;
	
	    for (var i = 0; i < this.children.length; ++i) {
	      var child = this$1.children[i], sz = child.chunkSize();
	      if (at < sz) {
	        var used = Math.min(n, sz - at);
	        if (child.iterN(at, used, op)) { return true }
	        if ((n -= used) == 0) { break }
	        at = 0;
	      } else { at -= sz; }
	    }
	  }
	};
	
	// Line widgets are block elements displayed above or below a line.
	
	var LineWidget = function(doc, node, options) {
	  var this$1 = this;
	
	  if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))
	    { this$1[opt] = options[opt]; } } }
	  this.doc = doc;
	  this.node = node;
	};
	
	LineWidget.prototype.clear = function () {
	    var this$1 = this;
	
	  var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
	  if (no == null || !ws) { return }
	  for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1); } }
	  if (!ws.length) { line.widgets = null; }
	  var height = widgetHeight(this);
	  updateLineHeight(line, Math.max(0, line.height - height));
	  if (cm) {
	    runInOp(cm, function () {
	      adjustScrollWhenAboveVisible(cm, line, -height);
	      regLineChange(cm, no, "widget");
	    });
	    signalLater(cm, "lineWidgetCleared", cm, this, no);
	  }
	};
	
	LineWidget.prototype.changed = function () {
	    var this$1 = this;
	
	  var oldH = this.height, cm = this.doc.cm, line = this.line;
	  this.height = null;
	  var diff = widgetHeight(this) - oldH;
	  if (!diff) { return }
	  updateLineHeight(line, line.height + diff);
	  if (cm) {
	    runInOp(cm, function () {
	      cm.curOp.forceUpdate = true;
	      adjustScrollWhenAboveVisible(cm, line, diff);
	      signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line));
	    });
	  }
	};
	eventMixin(LineWidget);
	
	function adjustScrollWhenAboveVisible(cm, line, diff) {
	  if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
	    { addToScrollTop(cm, diff); }
	}
	
	function addLineWidget(doc, handle, node, options) {
	  var widget = new LineWidget(doc, node, options);
	  var cm = doc.cm;
	  if (cm && widget.noHScroll) { cm.display.alignWidgets = true; }
	  changeLine(doc, handle, "widget", function (line) {
	    var widgets = line.widgets || (line.widgets = []);
	    if (widget.insertAt == null) { widgets.push(widget); }
	    else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); }
	    widget.line = line;
	    if (cm && !lineIsHidden(doc, line)) {
	      var aboveVisible = heightAtLine(line) < doc.scrollTop;
	      updateLineHeight(line, line.height + widgetHeight(widget));
	      if (aboveVisible) { addToScrollTop(cm, widget.height); }
	      cm.curOp.forceUpdate = true;
	    }
	    return true
	  });
	  signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle));
	  return widget
	}
	
	// TEXTMARKERS
	
	// Created with markText and setBookmark methods. A TextMarker is a
	// handle that can be used to clear or find a marked position in the
	// document. Line objects hold arrays (markedSpans) containing
	// {from, to, marker} object pointing to such marker objects, and
	// indicating that such a marker is present on that line. Multiple
	// lines may point to the same marker when it spans across lines.
	// The spans will have null for their from/to properties when the
	// marker continues beyond the start/end of the line. Markers have
	// links back to the lines they currently touch.
	
	// Collapsed markers have unique ids, in order to be able to order
	// them, which is needed for uniquely determining an outer marker
	// when they overlap (they may nest, but not partially overlap).
	var nextMarkerId = 0;
	
	var TextMarker = function(doc, type) {
	  this.lines = [];
	  this.type = type;
	  this.doc = doc;
	  this.id = ++nextMarkerId;
	};
	
	// Clear the marker.
	TextMarker.prototype.clear = function () {
	    var this$1 = this;
	
	  if (this.explicitlyCleared) { return }
	  var cm = this.doc.cm, withOp = cm && !cm.curOp;
	  if (withOp) { startOperation(cm); }
	  if (hasHandler(this, "clear")) {
	    var found = this.find();
	    if (found) { signalLater(this, "clear", found.from, found.to); }
	  }
	  var min = null, max = null;
	  for (var i = 0; i < this.lines.length; ++i) {
	    var line = this$1.lines[i];
	    var span = getMarkedSpanFor(line.markedSpans, this$1);
	    if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text"); }
	    else if (cm) {
	      if (span.to != null) { max = lineNo(line); }
	      if (span.from != null) { min = lineNo(line); }
	    }
	    line.markedSpans = removeMarkedSpan(line.markedSpans, span);
	    if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)
	      { updateLineHeight(line, textHeight(cm.display)); }
	  }
	  if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {
	    var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual);
	    if (len > cm.display.maxLineLength) {
	      cm.display.maxLine = visual;
	      cm.display.maxLineLength = len;
	      cm.display.maxLineChanged = true;
	    }
	  } }
	
	  if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1); }
	  this.lines.length = 0;
	  this.explicitlyCleared = true;
	  if (this.atomic && this.doc.cantEdit) {
	    this.doc.cantEdit = false;
	    if (cm) { reCheckSelection(cm.doc); }
	  }
	  if (cm) { signalLater(cm, "markerCleared", cm, this, min, max); }
	  if (withOp) { endOperation(cm); }
	  if (this.parent) { this.parent.clear(); }
	};
	
	// Find the position of the marker in the document. Returns a {from,
	// to} object by default. Side can be passed to get a specific side
	// -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
	// Pos objects returned contain a line object, rather than a line
	// number (used to prevent looking up the same line twice).
	TextMarker.prototype.find = function (side, lineObj) {
	    var this$1 = this;
	
	  if (side == null && this.type == "bookmark") { side = 1; }
	  var from, to;
	  for (var i = 0; i < this.lines.length; ++i) {
	    var line = this$1.lines[i];
	    var span = getMarkedSpanFor(line.markedSpans, this$1);
	    if (span.from != null) {
	      from = Pos(lineObj ? line : lineNo(line), span.from);
	      if (side == -1) { return from }
	    }
	    if (span.to != null) {
	      to = Pos(lineObj ? line : lineNo(line), span.to);
	      if (side == 1) { return to }
	    }
	  }
	  return from && {from: from, to: to}
	};
	
	// Signals that the marker's widget changed, and surrounding layout
	// should be recomputed.
	TextMarker.prototype.changed = function () {
	    var this$1 = this;
	
	  var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
	  if (!pos || !cm) { return }
	  runInOp(cm, function () {
	    var line = pos.line, lineN = lineNo(pos.line);
	    var view = findViewForLine(cm, lineN);
	    if (view) {
	      clearLineMeasurementCacheFor(view);
	      cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
	    }
	    cm.curOp.updateMaxLine = true;
	    if (!lineIsHidden(widget.doc, line) && widget.height != null) {
	      var oldHeight = widget.height;
	      widget.height = null;
	      var dHeight = widgetHeight(widget) - oldHeight;
	      if (dHeight)
	        { updateLineHeight(line, line.height + dHeight); }
	    }
	    signalLater(cm, "markerChanged", cm, this$1);
	  });
	};
	
	TextMarker.prototype.attachLine = function (line) {
	  if (!this.lines.length && this.doc.cm) {
	    var op = this.doc.cm.curOp;
	    if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
	      { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); }
	  }
	  this.lines.push(line);
	};
	
	TextMarker.prototype.detachLine = function (line) {
	  this.lines.splice(indexOf(this.lines, line), 1);
	  if (!this.lines.length && this.doc.cm) {
	    var op = this.doc.cm.curOp;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
	  }
	};
	eventMixin(TextMarker);
	
	// Create a marker, wire it up to the right lines, and
	function markText(doc, from, to, options, type) {
	  // Shared markers (across linked documents) are handled separately
	  // (markTextShared will call out to this again, once per
	  // document).
	  if (options && options.shared) { return markTextShared(doc, from, to, options, type) }
	  // Ensure we are in an operation.
	  if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) }
	
	  var marker = new TextMarker(doc, type), diff = cmp(from, to);
	  if (options) { copyObj(options, marker, false); }
	  // Don't connect empty markers unless clearWhenEmpty is false
	  if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
	    { return marker }
	  if (marker.replacedWith) {
	    // Showing up as a widget implies collapsed (widget replaces text)
	    marker.collapsed = true;
	    marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget");
	    if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); }
	    if (options.insertLeft) { marker.widgetNode.insertLeft = true; }
	  }
	  if (marker.collapsed) {
	    if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
	        from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
	      { throw new Error("Inserting collapsed marker partially overlapping an existing one") }
	    seeCollapsedSpans();
	  }
	
	  if (marker.addToHistory)
	    { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); }
	
	  var curLine = from.line, cm = doc.cm, updateMaxLine;
	  doc.iter(curLine, to.line + 1, function (line) {
	    if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
	      { updateMaxLine = true; }
	    if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); }
	    addMarkedSpan(line, new MarkedSpan(marker,
	                                       curLine == from.line ? from.ch : null,
	                                       curLine == to.line ? to.ch : null));
	    ++curLine;
	  });
	  // lineIsHidden depends on the presence of the spans, so needs a second pass
	  if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) {
	    if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); }
	  }); }
	
	  if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); }
	
	  if (marker.readOnly) {
	    seeReadOnlySpans();
	    if (doc.history.done.length || doc.history.undone.length)
	      { doc.clearHistory(); }
	  }
	  if (marker.collapsed) {
	    marker.id = ++nextMarkerId;
	    marker.atomic = true;
	  }
	  if (cm) {
	    // Sync editor state
	    if (updateMaxLine) { cm.curOp.updateMaxLine = true; }
	    if (marker.collapsed)
	      { regChange(cm, from.line, to.line + 1); }
	    else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
	      { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text"); } }
	    if (marker.atomic) { reCheckSelection(cm.doc); }
	    signalLater(cm, "markerAdded", cm, marker);
	  }
	  return marker
	}
	
	// SHARED TEXTMARKERS
	
	// A shared marker spans multiple linked documents. It is
	// implemented as a meta-marker-object controlling multiple normal
	// markers.
	var SharedTextMarker = function(markers, primary) {
	  var this$1 = this;
	
	  this.markers = markers;
	  this.primary = primary;
	  for (var i = 0; i < markers.length; ++i)
	    { markers[i].parent = this$1; }
	};
	
	SharedTextMarker.prototype.clear = function () {
	    var this$1 = this;
	
	  if (this.explicitlyCleared) { return }
	  this.explicitlyCleared = true;
	  for (var i = 0; i < this.markers.length; ++i)
	    { this$1.markers[i].clear(); }
	  signalLater(this, "clear");
	};
	
	SharedTextMarker.prototype.find = function (side, lineObj) {
	  return this.primary.find(side, lineObj)
	};
	eventMixin(SharedTextMarker);
	
	function markTextShared(doc, from, to, options, type) {
	  options = copyObj(options);
	  options.shared = false;
	  var markers = [markText(doc, from, to, options, type)], primary = markers[0];
	  var widget = options.widgetNode;
	  linkedDocs(doc, function (doc) {
	    if (widget) { options.widgetNode = widget.cloneNode(true); }
	    markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
	    for (var i = 0; i < doc.linked.length; ++i)
	      { if (doc.linked[i].isParent) { return } }
	    primary = lst(markers);
	  });
	  return new SharedTextMarker(markers, primary)
	}
	
	function findSharedMarkers(doc) {
	  return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; })
	}
	
	function copySharedMarkers(doc, markers) {
	  for (var i = 0; i < markers.length; i++) {
	    var marker = markers[i], pos = marker.find();
	    var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
	    if (cmp(mFrom, mTo)) {
	      var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
	      marker.markers.push(subMark);
	      subMark.parent = marker;
	    }
	  }
	}
	
	function detachSharedMarkers(markers) {
	  var loop = function ( i ) {
	    var marker = markers[i], linked = [marker.primary.doc];
	    linkedDocs(marker.primary.doc, function (d) { return linked.push(d); });
	    for (var j = 0; j < marker.markers.length; j++) {
	      var subMarker = marker.markers[j];
	      if (indexOf(linked, subMarker.doc) == -1) {
	        subMarker.parent = null;
	        marker.markers.splice(j--, 1);
	      }
	    }
	  };
	
	  for (var i = 0; i < markers.length; i++) loop( i );
	}
	
	var nextDocId = 0;
	var Doc = function(text, mode, firstLine, lineSep, direction) {
	  if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) }
	  if (firstLine == null) { firstLine = 0; }
	
	  BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
	  this.first = firstLine;
	  this.scrollTop = this.scrollLeft = 0;
	  this.cantEdit = false;
	  this.cleanGeneration = 1;
	  this.modeFrontier = this.highlightFrontier = firstLine;
	  var start = Pos(firstLine, 0);
	  this.sel = simpleSelection(start);
	  this.history = new History(null);
	  this.id = ++nextDocId;
	  this.modeOption = mode;
	  this.lineSep = lineSep;
	  this.direction = (direction == "rtl") ? "rtl" : "ltr";
	  this.extend = false;
	
	  if (typeof text == "string") { text = this.splitLines(text); }
	  updateDoc(this, {from: start, to: start, text: text});
	  setSelection(this, simpleSelection(start), sel_dontScroll);
	};
	
	Doc.prototype = createObj(BranchChunk.prototype, {
	  constructor: Doc,
	  // Iterate over the document. Supports two forms -- with only one
	  // argument, it calls that for each line in the document. With
	  // three, it iterates over the range given by the first two (with
	  // the second being non-inclusive).
	  iter: function(from, to, op) {
	    if (op) { this.iterN(from - this.first, to - from, op); }
	    else { this.iterN(this.first, this.first + this.size, from); }
	  },
	
	  // Non-public interface for adding and removing lines.
	  insert: function(at, lines) {
	    var height = 0;
	    for (var i = 0; i < lines.length; ++i) { height += lines[i].height; }
	    this.insertInner(at - this.first, lines, height);
	  },
	  remove: function(at, n) { this.removeInner(at - this.first, n); },
	
	  // From here, the methods are part of the public interface. Most
	  // are also available from CodeMirror (editor) instances.
	
	  getValue: function(lineSep) {
	    var lines = getLines(this, this.first, this.first + this.size);
	    if (lineSep === false) { return lines }
	    return lines.join(lineSep || this.lineSeparator())
	  },
	  setValue: docMethodOp(function(code) {
	    var top = Pos(this.first, 0), last = this.first + this.size - 1;
	    makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
	                      text: this.splitLines(code), origin: "setValue", full: true}, true);
	    if (this.cm) { scrollToCoords(this.cm, 0, 0); }
	    setSelection(this, simpleSelection(top), sel_dontScroll);
	  }),
	  replaceRange: function(code, from, to, origin) {
	    from = clipPos(this, from);
	    to = to ? clipPos(this, to) : from;
	    replaceRange(this, code, from, to, origin);
	  },
	  getRange: function(from, to, lineSep) {
	    var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
	    if (lineSep === false) { return lines }
	    return lines.join(lineSep || this.lineSeparator())
	  },
	
	  getLine: function(line) {var l = this.getLineHandle(line); return l && l.text},
	
	  getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }},
	  getLineNumber: function(line) {return lineNo(line)},
	
	  getLineHandleVisualStart: function(line) {
	    if (typeof line == "number") { line = getLine(this, line); }
	    return visualLine(line)
	  },
	
	  lineCount: function() {return this.size},
	  firstLine: function() {return this.first},
	  lastLine: function() {return this.first + this.size - 1},
	
	  clipPos: function(pos) {return clipPos(this, pos)},
	
	  getCursor: function(start) {
	    var range$$1 = this.sel.primary(), pos;
	    if (start == null || start == "head") { pos = range$$1.head; }
	    else if (start == "anchor") { pos = range$$1.anchor; }
	    else if (start == "end" || start == "to" || start === false) { pos = range$$1.to(); }
	    else { pos = range$$1.from(); }
	    return pos
	  },
	  listSelections: function() { return this.sel.ranges },
	  somethingSelected: function() {return this.sel.somethingSelected()},
	
	  setCursor: docMethodOp(function(line, ch, options) {
	    setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
	  }),
	  setSelection: docMethodOp(function(anchor, head, options) {
	    setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
	  }),
	  extendSelection: docMethodOp(function(head, other, options) {
	    extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
	  }),
	  extendSelections: docMethodOp(function(heads, options) {
	    extendSelections(this, clipPosArray(this, heads), options);
	  }),
	  extendSelectionsBy: docMethodOp(function(f, options) {
	    var heads = map(this.sel.ranges, f);
	    extendSelections(this, clipPosArray(this, heads), options);
	  }),
	  setSelections: docMethodOp(function(ranges, primary, options) {
	    var this$1 = this;
	
	    if (!ranges.length) { return }
	    var out = [];
	    for (var i = 0; i < ranges.length; i++)
	      { out[i] = new Range(clipPos(this$1, ranges[i].anchor),
	                         clipPos(this$1, ranges[i].head)); }
	    if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); }
	    setSelection(this, normalizeSelection(out, primary), options);
	  }),
	  addSelection: docMethodOp(function(anchor, head, options) {
	    var ranges = this.sel.ranges.slice(0);
	    ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
	    setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
	  }),
	
	  getSelection: function(lineSep) {
	    var this$1 = this;
	
	    var ranges = this.sel.ranges, lines;
	    for (var i = 0; i < ranges.length; i++) {
	      var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
	      lines = lines ? lines.concat(sel) : sel;
	    }
	    if (lineSep === false) { return lines }
	    else { return lines.join(lineSep || this.lineSeparator()) }
	  },
	  getSelections: function(lineSep) {
	    var this$1 = this;
	
	    var parts = [], ranges = this.sel.ranges;
	    for (var i = 0; i < ranges.length; i++) {
	      var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
	      if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()); }
	      parts[i] = sel;
	    }
	    return parts
	  },
	  replaceSelection: function(code, collapse, origin) {
	    var dup = [];
	    for (var i = 0; i < this.sel.ranges.length; i++)
	      { dup[i] = code; }
	    this.replaceSelections(dup, collapse, origin || "+input");
	  },
	  replaceSelections: docMethodOp(function(code, collapse, origin) {
	    var this$1 = this;
	
	    var changes = [], sel = this.sel;
	    for (var i = 0; i < sel.ranges.length; i++) {
	      var range$$1 = sel.ranges[i];
	      changes[i] = {from: range$$1.from(), to: range$$1.to(), text: this$1.splitLines(code[i]), origin: origin};
	    }
	    var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
	    for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)
	      { makeChange(this$1, changes[i$1]); }
	    if (newSel) { setSelectionReplaceHistory(this, newSel); }
	    else if (this.cm) { ensureCursorVisible(this.cm); }
	  }),
	  undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
	  redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
	  undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
	  redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
	
	  setExtending: function(val) {this.extend = val;},
	  getExtending: function() {return this.extend},
	
	  historySize: function() {
	    var hist = this.history, done = 0, undone = 0;
	    for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done; } }
	    for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } }
	    return {undo: done, redo: undone}
	  },
	  clearHistory: function() {this.history = new History(this.history.maxGeneration);},
	
	  markClean: function() {
	    this.cleanGeneration = this.changeGeneration(true);
	  },
	  changeGeneration: function(forceSplit) {
	    if (forceSplit)
	      { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; }
	    return this.history.generation
	  },
	  isClean: function (gen) {
	    return this.history.generation == (gen || this.cleanGeneration)
	  },
	
	  getHistory: function() {
	    return {done: copyHistoryArray(this.history.done),
	            undone: copyHistoryArray(this.history.undone)}
	  },
	  setHistory: function(histData) {
	    var hist = this.history = new History(this.history.maxGeneration);
	    hist.done = copyHistoryArray(histData.done.slice(0), null, true);
	    hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
	  },
	
	  setGutterMarker: docMethodOp(function(line, gutterID, value) {
	    return changeLine(this, line, "gutter", function (line) {
	      var markers = line.gutterMarkers || (line.gutterMarkers = {});
	      markers[gutterID] = value;
	      if (!value && isEmpty(markers)) { line.gutterMarkers = null; }
	      return true
	    })
	  }),
	
	  clearGutter: docMethodOp(function(gutterID) {
	    var this$1 = this;
	
	    this.iter(function (line) {
	      if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
	        changeLine(this$1, line, "gutter", function () {
	          line.gutterMarkers[gutterID] = null;
	          if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null; }
	          return true
	        });
	      }
	    });
	  }),
	
	  lineInfo: function(line) {
	    var n;
	    if (typeof line == "number") {
	      if (!isLine(this, line)) { return null }
	      n = line;
	      line = getLine(this, line);
	      if (!line) { return null }
	    } else {
	      n = lineNo(line);
	      if (n == null) { return null }
	    }
	    return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
	            textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
	            widgets: line.widgets}
	  },
	
	  addLineClass: docMethodOp(function(handle, where, cls) {
	    return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
	      var prop = where == "text" ? "textClass"
	               : where == "background" ? "bgClass"
	               : where == "gutter" ? "gutterClass" : "wrapClass";
	      if (!line[prop]) { line[prop] = cls; }
	      else if (classTest(cls).test(line[prop])) { return false }
	      else { line[prop] += " " + cls; }
	      return true
	    })
	  }),
	  removeLineClass: docMethodOp(function(handle, where, cls) {
	    return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
	      var prop = where == "text" ? "textClass"
	               : where == "background" ? "bgClass"
	               : where == "gutter" ? "gutterClass" : "wrapClass";
	      var cur = line[prop];
	      if (!cur) { return false }
	      else if (cls == null) { line[prop] = null; }
	      else {
	        var found = cur.match(classTest(cls));
	        if (!found) { return false }
	        var end = found.index + found[0].length;
	        line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
	      }
	      return true
	    })
	  }),
	
	  addLineWidget: docMethodOp(function(handle, node, options) {
	    return addLineWidget(this, handle, node, options)
	  }),
	  removeLineWidget: function(widget) { widget.clear(); },
	
	  markText: function(from, to, options) {
	    return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range")
	  },
	  setBookmark: function(pos, options) {
	    var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
	                    insertLeft: options && options.insertLeft,
	                    clearWhenEmpty: false, shared: options && options.shared,
	                    handleMouseEvents: options && options.handleMouseEvents};
	    pos = clipPos(this, pos);
	    return markText(this, pos, pos, realOpts, "bookmark")
	  },
	  findMarksAt: function(pos) {
	    pos = clipPos(this, pos);
	    var markers = [], spans = getLine(this, pos.line).markedSpans;
	    if (spans) { for (var i = 0; i < spans.length; ++i) {
	      var span = spans[i];
	      if ((span.from == null || span.from <= pos.ch) &&
	          (span.to == null || span.to >= pos.ch))
	        { markers.push(span.marker.parent || span.marker); }
	    } }
	    return markers
	  },
	  findMarks: function(from, to, filter) {
	    from = clipPos(this, from); to = clipPos(this, to);
	    var found = [], lineNo$$1 = from.line;
	    this.iter(from.line, to.line + 1, function (line) {
	      var spans = line.markedSpans;
	      if (spans) { for (var i = 0; i < spans.length; i++) {
	        var span = spans[i];
	        if (!(span.to != null && lineNo$$1 == from.line && from.ch >= span.to ||
	              span.from == null && lineNo$$1 != from.line ||
	              span.from != null && lineNo$$1 == to.line && span.from >= to.ch) &&
	            (!filter || filter(span.marker)))
	          { found.push(span.marker.parent || span.marker); }
	      } }
	      ++lineNo$$1;
	    });
	    return found
	  },
	  getAllMarks: function() {
	    var markers = [];
	    this.iter(function (line) {
	      var sps = line.markedSpans;
	      if (sps) { for (var i = 0; i < sps.length; ++i)
	        { if (sps[i].from != null) { markers.push(sps[i].marker); } } }
	    });
	    return markers
	  },
	
	  posFromIndex: function(off) {
	    var ch, lineNo$$1 = this.first, sepSize = this.lineSeparator().length;
	    this.iter(function (line) {
	      var sz = line.text.length + sepSize;
	      if (sz > off) { ch = off; return true }
	      off -= sz;
	      ++lineNo$$1;
	    });
	    return clipPos(this, Pos(lineNo$$1, ch))
	  },
	  indexFromPos: function (coords) {
	    coords = clipPos(this, coords);
	    var index = coords.ch;
	    if (coords.line < this.first || coords.ch < 0) { return 0 }
	    var sepSize = this.lineSeparator().length;
	    this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value
	      index += line.text.length + sepSize;
	    });
	    return index
	  },
	
	  copy: function(copyHistory) {
	    var doc = new Doc(getLines(this, this.first, this.first + this.size),
	                      this.modeOption, this.first, this.lineSep, this.direction);
	    doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
	    doc.sel = this.sel;
	    doc.extend = false;
	    if (copyHistory) {
	      doc.history.undoDepth = this.history.undoDepth;
	      doc.setHistory(this.getHistory());
	    }
	    return doc
	  },
	
	  linkedDoc: function(options) {
	    if (!options) { options = {}; }
	    var from = this.first, to = this.first + this.size;
	    if (options.from != null && options.from > from) { from = options.from; }
	    if (options.to != null && options.to < to) { to = options.to; }
	    var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction);
	    if (options.sharedHist) { copy.history = this.history
	    ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
	    copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
	    copySharedMarkers(copy, findSharedMarkers(this));
	    return copy
	  },
	  unlinkDoc: function(other) {
	    var this$1 = this;
	
	    if (other instanceof CodeMirror$1) { other = other.doc; }
	    if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {
	      var link = this$1.linked[i];
	      if (link.doc != other) { continue }
	      this$1.linked.splice(i, 1);
	      other.unlinkDoc(this$1);
	      detachSharedMarkers(findSharedMarkers(this$1));
	      break
	    } }
	    // If the histories were shared, split them again
	    if (other.history == this.history) {
	      var splitIds = [other.id];
	      linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true);
	      other.history = new History(null);
	      other.history.done = copyHistoryArray(this.history.done, splitIds);
	      other.history.undone = copyHistoryArray(this.history.undone, splitIds);
	    }
	  },
	  iterLinkedDocs: function(f) {linkedDocs(this, f);},
	
	  getMode: function() {return this.mode},
	  getEditor: function() {return this.cm},
	
	  splitLines: function(str) {
	    if (this.lineSep) { return str.split(this.lineSep) }
	    return splitLinesAuto(str)
	  },
	  lineSeparator: function() { return this.lineSep || "\n" },
	
	  setDirection: docMethodOp(function (dir) {
	    if (dir != "rtl") { dir = "ltr"; }
	    if (dir == this.direction) { return }
	    this.direction = dir;
	    this.iter(function (line) { return line.order = null; });
	    if (this.cm) { directionChanged(this.cm); }
	  })
	});
	
	// Public alias.
	Doc.prototype.eachLine = Doc.prototype.iter;
	
	// Kludge to work around strange IE behavior where it'll sometimes
	// re-fire a series of drag-related events right after the drop (#1551)
	var lastDrop = 0;
	
	function onDrop(e) {
	  var cm = this;
	  clearDragCursor(cm);
	  if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
	    { return }
	  e_preventDefault(e);
	  if (ie) { lastDrop = +new Date; }
	  var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
	  if (!pos || cm.isReadOnly()) { return }
	  // Might be a file drop, in which case we simply extract the text
	  // and insert it.
	  if (files && files.length && window.FileReader && window.File) {
	    var n = files.length, text = Array(n), read = 0;
	    var loadFile = function (file, i) {
	      if (cm.options.allowDropFileTypes &&
	          indexOf(cm.options.allowDropFileTypes, file.type) == -1)
	        { return }
	
	      var reader = new FileReader;
	      reader.onload = operation(cm, function () {
	        var content = reader.result;
	        if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = ""; }
	        text[i] = content;
	        if (++read == n) {
	          pos = clipPos(cm.doc, pos);
	          var change = {from: pos, to: pos,
	                        text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
	                        origin: "paste"};
	          makeChange(cm.doc, change);
	          setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
	        }
	      });
	      reader.readAsText(file);
	    };
	    for (var i = 0; i < n; ++i) { loadFile(files[i], i); }
	  } else { // Normal drop
	    // Don't do a replace if the drop happened inside of the selected text.
	    if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
	      cm.state.draggingText(e);
	      // Ensure the editor is re-focused
	      setTimeout(function () { return cm.display.input.focus(); }, 20);
	      return
	    }
	    try {
	      var text$1 = e.dataTransfer.getData("Text");
	      if (text$1) {
	        var selected;
	        if (cm.state.draggingText && !cm.state.draggingText.copy)
	          { selected = cm.listSelections(); }
	        setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
	        if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1)
	          { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag"); } }
	        cm.replaceSelection(text$1, "around", "paste");
	        cm.display.input.focus();
	      }
	    }
	    catch(e){}
	  }
	}
	
	function onDragStart(cm, e) {
	  if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }
	  if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return }
	
	  e.dataTransfer.setData("Text", cm.getSelection());
	  e.dataTransfer.effectAllowed = "copyMove";
	
	  // Use dummy image instead of default browsers image.
	  // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
	  if (e.dataTransfer.setDragImage && !safari) {
	    var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
	    img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
	    if (presto) {
	      img.width = img.height = 1;
	      cm.display.wrapper.appendChild(img);
	      // Force a relayout, or Opera won't use our image for some obscure reason
	      img._top = img.offsetTop;
	    }
	    e.dataTransfer.setDragImage(img, 0, 0);
	    if (presto) { img.parentNode.removeChild(img); }
	  }
	}
	
	function onDragOver(cm, e) {
	  var pos = posFromMouse(cm, e);
	  if (!pos) { return }
	  var frag = document.createDocumentFragment();
	  drawSelectionCursor(cm, pos, frag);
	  if (!cm.display.dragCursor) {
	    cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
	    cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
	  }
	  removeChildrenAndAdd(cm.display.dragCursor, frag);
	}
	
	function clearDragCursor(cm) {
	  if (cm.display.dragCursor) {
	    cm.display.lineSpace.removeChild(cm.display.dragCursor);
	    cm.display.dragCursor = null;
	  }
	}
	
	// These must be handled carefully, because naively registering a
	// handler for each editor will cause the editors to never be
	// garbage collected.
	
	function forEachCodeMirror(f) {
	  if (!document.getElementsByClassName) { return }
	  var byClass = document.getElementsByClassName("CodeMirror");
	  for (var i = 0; i < byClass.length; i++) {
	    var cm = byClass[i].CodeMirror;
	    if (cm) { f(cm); }
	  }
	}
	
	var globalsRegistered = false;
	function ensureGlobalHandlers() {
	  if (globalsRegistered) { return }
	  registerGlobalHandlers();
	  globalsRegistered = true;
	}
	function registerGlobalHandlers() {
	  // When the window resizes, we need to refresh active editors.
	  var resizeTimer;
	  on(window, "resize", function () {
	    if (resizeTimer == null) { resizeTimer = setTimeout(function () {
	      resizeTimer = null;
	      forEachCodeMirror(onResize);
	    }, 100); }
	  });
	  // When the window loses focus, we want to show the editor as blurred
	  on(window, "blur", function () { return forEachCodeMirror(onBlur); });
	}
	// Called when the window resizes
	function onResize(cm) {
	  var d = cm.display;
	  if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
	    { return }
	  // Might be a text scaling operation, clear size caches.
	  d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
	  d.scrollbarsClipped = false;
	  cm.setSize();
	}
	
	var keyNames = {
	  3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
	  19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
	  36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
	  46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
	  106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete",
	  173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
	  221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
	  63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
	};
	
	// Number keys
	for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i); }
	// Alphabetic keys
	for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1); }
	// Function keys
	for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2; }
	
	var keyMap = {};
	
	keyMap.basic = {
	  "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
	  "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
	  "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
	  "Tab": "defaultTab", "Shift-Tab": "indentAuto",
	  "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
	  "Esc": "singleSelection"
	};
	// Note that the save and find-related commands aren't defined by
	// default. User code or addons can define them. Unknown commands
	// are simply ignored.
	keyMap.pcDefault = {
	  "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
	  "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
	  "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
	  "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
	  "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
	  "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
	  "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
	  fallthrough: "basic"
	};
	// Very basic readline/emacs-style bindings, which are standard on Mac.
	keyMap.emacsy = {
	  "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
	  "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
	  "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
	  "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
	  "Ctrl-O": "openLine"
	};
	keyMap.macDefault = {
	  "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
	  "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
	  "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
	  "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
	  "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
	  "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
	  "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
	  fallthrough: ["basic", "emacsy"]
	};
	keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
	
	// KEYMAP DISPATCH
	
	function normalizeKeyName(name) {
	  var parts = name.split(/-(?!$)/);
	  name = parts[parts.length - 1];
	  var alt, ctrl, shift, cmd;
	  for (var i = 0; i < parts.length - 1; i++) {
	    var mod = parts[i];
	    if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true; }
	    else if (/^a(lt)?$/i.test(mod)) { alt = true; }
	    else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true; }
	    else if (/^s(hift)?$/i.test(mod)) { shift = true; }
	    else { throw new Error("Unrecognized modifier name: " + mod) }
	  }
	  if (alt) { name = "Alt-" + name; }
	  if (ctrl) { name = "Ctrl-" + name; }
	  if (cmd) { name = "Cmd-" + name; }
	  if (shift) { name = "Shift-" + name; }
	  return name
	}
	
	// This is a kludge to keep keymaps mostly working as raw objects
	// (backwards compatibility) while at the same time support features
	// like normalization and multi-stroke key bindings. It compiles a
	// new normalized keymap, and then updates the old object to reflect
	// this.
	function normalizeKeyMap(keymap) {
	  var copy = {};
	  for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) {
	    var value = keymap[keyname];
	    if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue }
	    if (value == "...") { delete keymap[keyname]; continue }
	
	    var keys = map(keyname.split(" "), normalizeKeyName);
	    for (var i = 0; i < keys.length; i++) {
	      var val = (void 0), name = (void 0);
	      if (i == keys.length - 1) {
	        name = keys.join(" ");
	        val = value;
	      } else {
	        name = keys.slice(0, i + 1).join(" ");
	        val = "...";
	      }
	      var prev = copy[name];
	      if (!prev) { copy[name] = val; }
	      else if (prev != val) { throw new Error("Inconsistent bindings for " + name) }
	    }
	    delete keymap[keyname];
	  } }
	  for (var prop in copy) { keymap[prop] = copy[prop]; }
	  return keymap
	}
	
	function lookupKey(key, map$$1, handle, context) {
	  map$$1 = getKeyMap(map$$1);
	  var found = map$$1.call ? map$$1.call(key, context) : map$$1[key];
	  if (found === false) { return "nothing" }
	  if (found === "...") { return "multi" }
	  if (found != null && handle(found)) { return "handled" }
	
	  if (map$$1.fallthrough) {
	    if (Object.prototype.toString.call(map$$1.fallthrough) != "[object Array]")
	      { return lookupKey(key, map$$1.fallthrough, handle, context) }
	    for (var i = 0; i < map$$1.fallthrough.length; i++) {
	      var result = lookupKey(key, map$$1.fallthrough[i], handle, context);
	      if (result) { return result }
	    }
	  }
	}
	
	// Modifier key presses don't count as 'real' key presses for the
	// purpose of keymap fallthrough.
	function isModifierKey(value) {
	  var name = typeof value == "string" ? value : keyNames[value.keyCode];
	  return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"
	}
	
	function addModifierNames(name, event, noShift) {
	  var base = name;
	  if (event.altKey && base != "Alt") { name = "Alt-" + name; }
	  if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name; }
	  if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name; }
	  if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; }
	  return name
	}
	
	// Look up the name of a key as indicated by an event object.
	function keyName(event, noShift) {
	  if (presto && event.keyCode == 34 && event["char"]) { return false }
	  var name = keyNames[event.keyCode];
	  if (name == null || event.altGraphKey) { return false }
	  return addModifierNames(name, event, noShift)
	}
	
	function getKeyMap(val) {
	  return typeof val == "string" ? keyMap[val] : val
	}
	
	// Helper for deleting text near the selection(s), used to implement
	// backspace, delete, and similar functionality.
	function deleteNearSelection(cm, compute) {
	  var ranges = cm.doc.sel.ranges, kill = [];
	  // Build up a set of ranges to kill first, merging overlapping
	  // ranges.
	  for (var i = 0; i < ranges.length; i++) {
	    var toKill = compute(ranges[i]);
	    while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
	      var replaced = kill.pop();
	      if (cmp(replaced.from, toKill.from) < 0) {
	        toKill.from = replaced.from;
	        break
	      }
	    }
	    kill.push(toKill);
	  }
	  // Next, remove those actual ranges.
	  runInOp(cm, function () {
	    for (var i = kill.length - 1; i >= 0; i--)
	      { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); }
	    ensureCursorVisible(cm);
	  });
	}
	
	// Commands are parameter-less actions that can be performed on an
	// editor, mostly used for keybindings.
	var commands = {
	  selectAll: selectAll,
	  singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); },
	  killLine: function (cm) { return deleteNearSelection(cm, function (range) {
	    if (range.empty()) {
	      var len = getLine(cm.doc, range.head.line).text.length;
	      if (range.head.ch == len && range.head.line < cm.lastLine())
	        { return {from: range.head, to: Pos(range.head.line + 1, 0)} }
	      else
	        { return {from: range.head, to: Pos(range.head.line, len)} }
	    } else {
	      return {from: range.from(), to: range.to()}
	    }
	  }); },
	  deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({
	    from: Pos(range.from().line, 0),
	    to: clipPos(cm.doc, Pos(range.to().line + 1, 0))
	  }); }); },
	  delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({
	    from: Pos(range.from().line, 0), to: range.from()
	  }); }); },
	  delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {
	    var top = cm.charCoords(range.head, "div").top + 5;
	    var leftPos = cm.coordsChar({left: 0, top: top}, "div");
	    return {from: leftPos, to: range.from()}
	  }); },
	  delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) {
	    var top = cm.charCoords(range.head, "div").top + 5;
	    var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
	    return {from: range.from(), to: rightPos }
	  }); },
	  undo: function (cm) { return cm.undo(); },
	  redo: function (cm) { return cm.redo(); },
	  undoSelection: function (cm) { return cm.undoSelection(); },
	  redoSelection: function (cm) { return cm.redoSelection(); },
	  goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); },
	  goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); },
	  goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); },
	    {origin: "+move", bias: 1}
	  ); },
	  goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); },
	    {origin: "+move", bias: 1}
	  ); },
	  goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); },
	    {origin: "+move", bias: -1}
	  ); },
	  goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
	    var top = cm.charCoords(range.head, "div").top + 5;
	    return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
	  }, sel_move); },
	  goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
	    var top = cm.charCoords(range.head, "div").top + 5;
	    return cm.coordsChar({left: 0, top: top}, "div")
	  }, sel_move); },
	  goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
	    var top = cm.charCoords(range.head, "div").top + 5;
	    var pos = cm.coordsChar({left: 0, top: top}, "div");
	    if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
	    return pos
	  }, sel_move); },
	  goLineUp: function (cm) { return cm.moveV(-1, "line"); },
	  goLineDown: function (cm) { return cm.moveV(1, "line"); },
	  goPageUp: function (cm) { return cm.moveV(-1, "page"); },
	  goPageDown: function (cm) { return cm.moveV(1, "page"); },
	  goCharLeft: function (cm) { return cm.moveH(-1, "char"); },
	  goCharRight: function (cm) { return cm.moveH(1, "char"); },
	  goColumnLeft: function (cm) { return cm.moveH(-1, "column"); },
	  goColumnRight: function (cm) { return cm.moveH(1, "column"); },
	  goWordLeft: function (cm) { return cm.moveH(-1, "word"); },
	  goGroupRight: function (cm) { return cm.moveH(1, "group"); },
	  goGroupLeft: function (cm) { return cm.moveH(-1, "group"); },
	  goWordRight: function (cm) { return cm.moveH(1, "word"); },
	  delCharBefore: function (cm) { return cm.deleteH(-1, "char"); },
	  delCharAfter: function (cm) { return cm.deleteH(1, "char"); },
	  delWordBefore: function (cm) { return cm.deleteH(-1, "word"); },
	  delWordAfter: function (cm) { return cm.deleteH(1, "word"); },
	  delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); },
	  delGroupAfter: function (cm) { return cm.deleteH(1, "group"); },
	  indentAuto: function (cm) { return cm.indentSelection("smart"); },
	  indentMore: function (cm) { return cm.indentSelection("add"); },
	  indentLess: function (cm) { return cm.indentSelection("subtract"); },
	  insertTab: function (cm) { return cm.replaceSelection("\t"); },
	  insertSoftTab: function (cm) {
	    var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
	    for (var i = 0; i < ranges.length; i++) {
	      var pos = ranges[i].from();
	      var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
	      spaces.push(spaceStr(tabSize - col % tabSize));
	    }
	    cm.replaceSelections(spaces);
	  },
	  defaultTab: function (cm) {
	    if (cm.somethingSelected()) { cm.indentSelection("add"); }
	    else { cm.execCommand("insertTab"); }
	  },
	  // Swap the two chars left and right of each selection's head.
	  // Move cursor behind the two swapped characters afterwards.
	  //
	  // Doesn't consider line feeds a character.
	  // Doesn't scan more than one line above to find a character.
	  // Doesn't do anything on an empty line.
	  // Doesn't do anything with non-empty selections.
	  transposeChars: function (cm) { return runInOp(cm, function () {
	    var ranges = cm.listSelections(), newSel = [];
	    for (var i = 0; i < ranges.length; i++) {
	      if (!ranges[i].empty()) { continue }
	      var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
	      if (line) {
	        if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1); }
	        if (cur.ch > 0) {
	          cur = new Pos(cur.line, cur.ch + 1);
	          cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
	                          Pos(cur.line, cur.ch - 2), cur, "+transpose");
	        } else if (cur.line > cm.doc.first) {
	          var prev = getLine(cm.doc, cur.line - 1).text;
	          if (prev) {
	            cur = new Pos(cur.line, 1);
	            cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
	                            prev.charAt(prev.length - 1),
	                            Pos(cur.line - 1, prev.length - 1), cur, "+transpose");
	          }
	        }
	      }
	      newSel.push(new Range(cur, cur));
	    }
	    cm.setSelections(newSel);
	  }); },
	  newlineAndIndent: function (cm) { return runInOp(cm, function () {
	    var sels = cm.listSelections();
	    for (var i = sels.length - 1; i >= 0; i--)
	      { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input"); }
	    sels = cm.listSelections();
	    for (var i$1 = 0; i$1 < sels.length; i$1++)
	      { cm.indentLine(sels[i$1].from().line, null, true); }
	    ensureCursorVisible(cm);
	  }); },
	  openLine: function (cm) { return cm.replaceSelection("\n", "start"); },
	  toggleOverwrite: function (cm) { return cm.toggleOverwrite(); }
	};
	
	
	function lineStart(cm, lineN) {
	  var line = getLine(cm.doc, lineN);
	  var visual = visualLine(line);
	  if (visual != line) { lineN = lineNo(visual); }
	  return endOfLine(true, cm, visual, lineN, 1)
	}
	function lineEnd(cm, lineN) {
	  var line = getLine(cm.doc, lineN);
	  var visual = visualLineEnd(line);
	  if (visual != line) { lineN = lineNo(visual); }
	  return endOfLine(true, cm, line, lineN, -1)
	}
	function lineStartSmart(cm, pos) {
	  var start = lineStart(cm, pos.line);
	  var line = getLine(cm.doc, start.line);
	  var order = getOrder(line, cm.doc.direction);
	  if (!order || order[0].level == 0) {
	    var firstNonWS = Math.max(0, line.text.search(/\S/));
	    var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
	    return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
	  }
	  return start
	}
	
	// Run a handler that was bound to a key.
	function doHandleBinding(cm, bound, dropShift) {
	  if (typeof bound == "string") {
	    bound = commands[bound];
	    if (!bound) { return false }
	  }
	  // Ensure previous input has been read, so that the handler sees a
	  // consistent view of the document
	  cm.display.input.ensurePolled();
	  var prevShift = cm.display.shift, done = false;
	  try {
	    if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
	    if (dropShift) { cm.display.shift = false; }
	    done = bound(cm) != Pass;
	  } finally {
	    cm.display.shift = prevShift;
	    cm.state.suppressEdits = false;
	  }
	  return done
	}
	
	function lookupKeyForEditor(cm, name, handle) {
	  for (var i = 0; i < cm.state.keyMaps.length; i++) {
	    var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
	    if (result) { return result }
	  }
	  return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
	    || lookupKey(name, cm.options.keyMap, handle, cm)
	}
	
	// Note that, despite the name, this function is also used to check
	// for bound mouse clicks.
	
	var stopSeq = new Delayed;
	function dispatchKey(cm, name, e, handle) {
	  var seq = cm.state.keySeq;
	  if (seq) {
	    if (isModifierKey(name)) { return "handled" }
	    stopSeq.set(50, function () {
	      if (cm.state.keySeq == seq) {
	        cm.state.keySeq = null;
	        cm.display.input.reset();
	      }
	    });
	    name = seq + " " + name;
	  }
	  var result = lookupKeyForEditor(cm, name, handle);
	
	  if (result == "multi")
	    { cm.state.keySeq = name; }
	  if (result == "handled")
	    { signalLater(cm, "keyHandled", cm, name, e); }
	
	  if (result == "handled" || result == "multi") {
	    e_preventDefault(e);
	    restartBlink(cm);
	  }
	
	  if (seq && !result && /\'$/.test(name)) {
	    e_preventDefault(e);
	    return true
	  }
	  return !!result
	}
	
	// Handle a key from the keydown event.
	function handleKeyBinding(cm, e) {
	  var name = keyName(e, true);
	  if (!name) { return false }
	
	  if (e.shiftKey && !cm.state.keySeq) {
	    // First try to resolve full name (including 'Shift-'). Failing
	    // that, see if there is a cursor-motion command (starting with
	    // 'go') bound to the keyname without 'Shift-'.
	    return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); })
	        || dispatchKey(cm, name, e, function (b) {
	             if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
	               { return doHandleBinding(cm, b) }
	           })
	  } else {
	    return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); })
	  }
	}
	
	// Handle a key from the keypress event
	function handleCharBinding(cm, e, ch) {
	  return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); })
	}
	
	var lastStoppedKey = null;
	function onKeyDown(e) {
	  var cm = this;
	  cm.curOp.focus = activeElt();
	  if (signalDOMEvent(cm, e)) { return }
	  // IE does strange things with escape.
	  if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; }
	  var code = e.keyCode;
	  cm.display.shift = code == 16 || e.shiftKey;
	  var handled = handleKeyBinding(cm, e);
	  if (presto) {
	    lastStoppedKey = handled ? code : null;
	    // Opera has no cut event... we try to at least catch the key combo
	    if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
	      { cm.replaceSelection("", null, "cut"); }
	  }
	
	  // Turn mouse into crosshair when Alt is held on Mac.
	  if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
	    { showCrossHair(cm); }
	}
	
	function showCrossHair(cm) {
	  var lineDiv = cm.display.lineDiv;
	  addClass(lineDiv, "CodeMirror-crosshair");
	
	  function up(e) {
	    if (e.keyCode == 18 || !e.altKey) {
	      rmClass(lineDiv, "CodeMirror-crosshair");
	      off(document, "keyup", up);
	      off(document, "mouseover", up);
	    }
	  }
	  on(document, "keyup", up);
	  on(document, "mouseover", up);
	}
	
	function onKeyUp(e) {
	  if (e.keyCode == 16) { this.doc.sel.shift = false; }
	  signalDOMEvent(this, e);
	}
	
	function onKeyPress(e) {
	  var cm = this;
	  if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
	  var keyCode = e.keyCode, charCode = e.charCode;
	  if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
	  if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return }
	  var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
	  // Some browsers fire keypress events for backspace
	  if (ch == "\x08") { return }
	  if (handleCharBinding(cm, e, ch)) { return }
	  cm.display.input.onKeyPress(e);
	}
	
	var DOUBLECLICK_DELAY = 400;
	
	var PastClick = function(time, pos, button) {
	  this.time = time;
	  this.pos = pos;
	  this.button = button;
	};
	
	PastClick.prototype.compare = function (time, pos, button) {
	  return this.time + DOUBLECLICK_DELAY > time &&
	    cmp(pos, this.pos) == 0 && button == this.button
	};
	
	var lastClick;
	var lastDoubleClick;
	function clickRepeat(pos, button) {
	  var now = +new Date;
	  if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) {
	    lastClick = lastDoubleClick = null;
	    return "triple"
	  } else if (lastClick && lastClick.compare(now, pos, button)) {
	    lastDoubleClick = new PastClick(now, pos, button);
	    lastClick = null;
	    return "double"
	  } else {
	    lastClick = new PastClick(now, pos, button);
	    lastDoubleClick = null;
	    return "single"
	  }
	}
	
	// A mouse down can be a single click, double click, triple click,
	// start of selection drag, start of text drag, new cursor
	// (ctrl-click), rectangle drag (alt-drag), or xwin
	// middle-click-paste. Or it might be a click on something we should
	// not interfere with, such as a scrollbar or widget.
	function onMouseDown(e) {
	  var cm = this, display = cm.display;
	  if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return }
	  display.input.ensurePolled();
	  display.shift = e.shiftKey;
	
	  if (eventInWidget(display, e)) {
	    if (!webkit) {
	      // Briefly turn off draggability, to allow widgets to do
	      // normal dragging things.
	      display.scroller.draggable = false;
	      setTimeout(function () { return display.scroller.draggable = true; }, 100);
	    }
	    return
	  }
	  if (clickInGutter(cm, e)) { return }
	  var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single";
	  window.focus();
	
	  // #3261: make sure, that we're not starting a second selection
	  if (button == 1 && cm.state.selectingText)
	    { cm.state.selectingText(e); }
	
	  if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return }
	
	  if (button == 1) {
	    if (pos) { leftButtonDown(cm, pos, repeat, e); }
	    else if (e_target(e) == display.scroller) { e_preventDefault(e); }
	  } else if (button == 2) {
	    if (pos) { extendSelection(cm.doc, pos); }
	    setTimeout(function () { return display.input.focus(); }, 20);
	  } else if (button == 3) {
	    if (captureRightClick) { onContextMenu(cm, e); }
	    else { delayBlurEvent(cm); }
	  }
	}
	
	function handleMappedButton(cm, button, pos, repeat, event) {
	  var name = "Click";
	  if (repeat == "double") { name = "Double" + name; }
	  else if (repeat == "triple") { name = "Triple" + name; }
	  name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name;
	
	  return dispatchKey(cm,  addModifierNames(name, event), event, function (bound) {
	    if (typeof bound == "string") { bound = commands[bound]; }
	    if (!bound) { return false }
	    var done = false;
	    try {
	      if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
	      done = bound(cm, pos) != Pass;
	    } finally {
	      cm.state.suppressEdits = false;
	    }
	    return done
	  })
	}
	
	function configureMouse(cm, repeat, event) {
	  var option = cm.getOption("configureMouse");
	  var value = option ? option(cm, repeat, event) : {};
	  if (value.unit == null) {
	    var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey;
	    value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line";
	  }
	  if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey; }
	  if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey; }
	  if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey); }
	  return value
	}
	
	function leftButtonDown(cm, pos, repeat, event) {
	  if (ie) { setTimeout(bind(ensureFocus, cm), 0); }
	  else { cm.curOp.focus = activeElt(); }
	
	  var behavior = configureMouse(cm, repeat, event);
	
	  var sel = cm.doc.sel, contained;
	  if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
	      repeat == "single" && (contained = sel.contains(pos)) > -1 &&
	      (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) &&
	      (cmp(contained.to(), pos) > 0 || pos.xRel < 0))
	    { leftButtonStartDrag(cm, event, pos, behavior); }
	  else
	    { leftButtonSelect(cm, event, pos, behavior); }
	}
	
	// Start a text drag. When it ends, see if any dragging actually
	// happen, and treat as a click if it didn't.
	function leftButtonStartDrag(cm, event, pos, behavior) {
	  var display = cm.display, moved = false;
	  var dragEnd = operation(cm, function (e) {
	    if (webkit) { display.scroller.draggable = false; }
	    cm.state.draggingText = false;
	    off(document, "mouseup", dragEnd);
	    off(document, "mousemove", mouseMove);
	    off(display.scroller, "dragstart", dragStart);
	    off(display.scroller, "drop", dragEnd);
	    if (!moved) {
	      e_preventDefault(e);
	      if (!behavior.addNew)
	        { extendSelection(cm.doc, pos, null, null, behavior.extend); }
	      // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
	      if (webkit || ie && ie_version == 9)
	        { setTimeout(function () {document.body.focus(); display.input.focus();}, 20); }
	      else
	        { display.input.focus(); }
	    }
	  });
	  var mouseMove = function(e2) {
	    moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10;
	  };
	  var dragStart = function () { return moved = true; };
	  // Let the drag handler handle this.
	  if (webkit) { display.scroller.draggable = true; }
	  cm.state.draggingText = dragEnd;
	  dragEnd.copy = !behavior.moveOnDrag;
	  // IE's approach to draggable
	  if (display.scroller.dragDrop) { display.scroller.dragDrop(); }
	  on(document, "mouseup", dragEnd);
	  on(document, "mousemove", mouseMove);
	  on(display.scroller, "dragstart", dragStart);
	  on(display.scroller, "drop", dragEnd);
	
	  delayBlurEvent(cm);
	  setTimeout(function () { return display.input.focus(); }, 20);
	}
	
	function rangeForUnit(cm, pos, unit) {
	  if (unit == "char") { return new Range(pos, pos) }
	  if (unit == "word") { return cm.findWordAt(pos) }
	  if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }
	  var result = unit(cm, pos);
	  return new Range(result.from, result.to)
	}
	
	// Normal selection, as opposed to text dragging.
	function leftButtonSelect(cm, event, start, behavior) {
	  var display = cm.display, doc = cm.doc;
	  e_preventDefault(event);
	
	  var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
	  if (behavior.addNew && !behavior.extend) {
	    ourIndex = doc.sel.contains(start);
	    if (ourIndex > -1)
	      { ourRange = ranges[ourIndex]; }
	    else
	      { ourRange = new Range(start, start); }
	  } else {
	    ourRange = doc.sel.primary();
	    ourIndex = doc.sel.primIndex;
	  }
	
	  if (behavior.unit == "rectangle") {
	    if (!behavior.addNew) { ourRange = new Range(start, start); }
	    start = posFromMouse(cm, event, true, true);
	    ourIndex = -1;
	  } else {
	    var range$$1 = rangeForUnit(cm, start, behavior.unit);
	    if (behavior.extend)
	      { ourRange = extendRange(ourRange, range$$1.anchor, range$$1.head, behavior.extend); }
	    else
	      { ourRange = range$$1; }
	  }
	
	  if (!behavior.addNew) {
	    ourIndex = 0;
	    setSelection(doc, new Selection([ourRange], 0), sel_mouse);
	    startSel = doc.sel;
	  } else if (ourIndex == -1) {
	    ourIndex = ranges.length;
	    setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
	                 {scroll: false, origin: "*mouse"});
	  } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) {
	    setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
	                 {scroll: false, origin: "*mouse"});
	    startSel = doc.sel;
	  } else {
	    replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
	  }
	
	  var lastPos = start;
	  function extendTo(pos) {
	    if (cmp(lastPos, pos) == 0) { return }
	    lastPos = pos;
	
	    if (behavior.unit == "rectangle") {
	      var ranges = [], tabSize = cm.options.tabSize;
	      var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
	      var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
	      var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
	      for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
	           line <= end; line++) {
	        var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
	        if (left == right)
	          { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); }
	        else if (text.length > leftPos)
	          { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); }
	      }
	      if (!ranges.length) { ranges.push(new Range(start, start)); }
	      setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
	                   {origin: "*mouse", scroll: false});
	      cm.scrollIntoView(pos);
	    } else {
	      var oldRange = ourRange;
	      var range$$1 = rangeForUnit(cm, pos, behavior.unit);
	      var anchor = oldRange.anchor, head;
	      if (cmp(range$$1.anchor, anchor) > 0) {
	        head = range$$1.head;
	        anchor = minPos(oldRange.from(), range$$1.anchor);
	      } else {
	        head = range$$1.anchor;
	        anchor = maxPos(oldRange.to(), range$$1.head);
	      }
	      var ranges$1 = startSel.ranges.slice(0);
	      ranges$1[ourIndex] = new Range(clipPos(doc, anchor), head);
	      setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse);
	    }
	  }
	
	  var editorSize = display.wrapper.getBoundingClientRect();
	  // Used to ensure timeout re-tries don't fire when another extend
	  // happened in the meantime (clearTimeout isn't reliable -- at
	  // least on Chrome, the timeouts still happen even when cleared,
	  // if the clear happens after their scheduled firing time).
	  var counter = 0;
	
	  function extend(e) {
	    var curCount = ++counter;
	    var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle");
	    if (!cur) { return }
	    if (cmp(cur, lastPos) != 0) {
	      cm.curOp.focus = activeElt();
	      extendTo(cur);
	      var visible = visibleLines(display, doc);
	      if (cur.line >= visible.to || cur.line < visible.from)
	        { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); }
	    } else {
	      var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
	      if (outside) { setTimeout(operation(cm, function () {
	        if (counter != curCount) { return }
	        display.scroller.scrollTop += outside;
	        extend(e);
	      }), 50); }
	    }
	  }
	
	  function done(e) {
	    cm.state.selectingText = false;
	    counter = Infinity;
	    e_preventDefault(e);
	    display.input.focus();
	    off(document, "mousemove", move);
	    off(document, "mouseup", up);
	    doc.history.lastSelOrigin = null;
	  }
	
	  var move = operation(cm, function (e) {
	    if (!e_button(e)) { done(e); }
	    else { extend(e); }
	  });
	  var up = operation(cm, done);
	  cm.state.selectingText = up;
	  on(document, "mousemove", move);
	  on(document, "mouseup", up);
	}
	
	
	// Determines whether an event happened in the gutter, and fires the
	// handlers for the corresponding event.
	function gutterEvent(cm, e, type, prevent) {
	  var mX, mY;
	  try { mX = e.clientX; mY = e.clientY; }
	  catch(e) { return false }
	  if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
	  if (prevent) { e_preventDefault(e); }
	
	  var display = cm.display;
	  var lineBox = display.lineDiv.getBoundingClientRect();
	
	  if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) }
	  mY -= lineBox.top - display.viewOffset;
	
	  for (var i = 0; i < cm.options.gutters.length; ++i) {
	    var g = display.gutters.childNodes[i];
	    if (g && g.getBoundingClientRect().right >= mX) {
	      var line = lineAtHeight(cm.doc, mY);
	      var gutter = cm.options.gutters[i];
	      signal(cm, type, cm, line, gutter, e);
	      return e_defaultPrevented(e)
	    }
	  }
	}
	
	function clickInGutter(cm, e) {
	  return gutterEvent(cm, e, "gutterClick", true)
	}
	
	// CONTEXT MENU HANDLING
	
	// To make the context menu work, we need to briefly unhide the
	// textarea (making it as unobtrusive as possible) to let the
	// right-click take effect on it.
	function onContextMenu(cm, e) {
	  if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return }
	  if (signalDOMEvent(cm, e, "contextmenu")) { return }
	  cm.display.input.onContextMenu(e);
	}
	
	function contextMenuInGutter(cm, e) {
	  if (!hasHandler(cm, "gutterContextMenu")) { return false }
	  return gutterEvent(cm, e, "gutterContextMenu", false)
	}
	
	function themeChanged(cm) {
	  cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
	    cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
	  clearCaches(cm);
	}
	
	var Init = {toString: function(){return "CodeMirror.Init"}};
	
	var defaults = {};
	var optionHandlers = {};
	
	function defineOptions(CodeMirror) {
	  var optionHandlers = CodeMirror.optionHandlers;
	
	  function option(name, deflt, handle, notOnInit) {
	    CodeMirror.defaults[name] = deflt;
	    if (handle) { optionHandlers[name] =
	      notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old); }} : handle; }
	  }
	
	  CodeMirror.defineOption = option;
	
	  // Passed to option handlers when there is no old value.
	  CodeMirror.Init = Init;
	
	  // These two are, on init, called from the constructor because they
	  // have to be initialized before the editor can start at all.
	  option("value", "", function (cm, val) { return cm.setValue(val); }, true);
	  option("mode", null, function (cm, val) {
	    cm.doc.modeOption = val;
	    loadMode(cm);
	  }, true);
	
	  option("indentUnit", 2, loadMode, true);
	  option("indentWithTabs", false);
	  option("smartIndent", true);
	  option("tabSize", 4, function (cm) {
	    resetModeState(cm);
	    clearCaches(cm);
	    regChange(cm);
	  }, true);
	  option("lineSeparator", null, function (cm, val) {
	    cm.doc.lineSep = val;
	    if (!val) { return }
	    var newBreaks = [], lineNo = cm.doc.first;
	    cm.doc.iter(function (line) {
	      for (var pos = 0;;) {
	        var found = line.text.indexOf(val, pos);
	        if (found == -1) { break }
	        pos = found + val.length;
	        newBreaks.push(Pos(lineNo, found));
	      }
	      lineNo++;
	    });
	    for (var i = newBreaks.length - 1; i >= 0; i--)
	      { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); }
	  });
	  option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) {
	    cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
	    if (old != Init) { cm.refresh(); }
	  });
	  option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true);
	  option("electricChars", true);
	  option("inputStyle", mobile ? "contenteditable" : "textarea", function () {
	    throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME
	  }, true);
	  option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true);
	  option("rtlMoveVisually", !windows);
	  option("wholeLineUpdateBefore", true);
	
	  option("theme", "default", function (cm) {
	    themeChanged(cm);
	    guttersChanged(cm);
	  }, true);
	  option("keyMap", "default", function (cm, val, old) {
	    var next = getKeyMap(val);
	    var prev = old != Init && getKeyMap(old);
	    if (prev && prev.detach) { prev.detach(cm, next); }
	    if (next.attach) { next.attach(cm, prev || null); }
	  });
	  option("extraKeys", null);
	  option("configureMouse", null);
	
	  option("lineWrapping", false, wrappingChanged, true);
	  option("gutters", [], function (cm) {
	    setGuttersForLineNumbers(cm.options);
	    guttersChanged(cm);
	  }, true);
	  option("fixedGutter", true, function (cm, val) {
	    cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
	    cm.refresh();
	  }, true);
	  option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true);
	  option("scrollbarStyle", "native", function (cm) {
	    initScrollbars(cm);
	    updateScrollbars(cm);
	    cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
	    cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
	  }, true);
	  option("lineNumbers", false, function (cm) {
	    setGuttersForLineNumbers(cm.options);
	    guttersChanged(cm);
	  }, true);
	  option("firstLineNumber", 1, guttersChanged, true);
	  option("lineNumberFormatter", function (integer) { return integer; }, guttersChanged, true);
	  option("showCursorWhenSelecting", false, updateSelection, true);
	
	  option("resetSelectionOnContextMenu", true);
	  option("lineWiseCopyCut", true);
	  option("pasteLinesPerSelection", true);
	
	  option("readOnly", false, function (cm, val) {
	    if (val == "nocursor") {
	      onBlur(cm);
	      cm.display.input.blur();
	    }
	    cm.display.input.readOnlyChanged(val);
	  });
	  option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true);
	  option("dragDrop", true, dragDropChanged);
	  option("allowDropFileTypes", null);
	
	  option("cursorBlinkRate", 530);
	  option("cursorScrollMargin", 0);
	  option("cursorHeight", 1, updateSelection, true);
	  option("singleCursorHeightPerLine", true, updateSelection, true);
	  option("workTime", 100);
	  option("workDelay", 100);
	  option("flattenSpans", true, resetModeState, true);
	  option("addModeClass", false, resetModeState, true);
	  option("pollInterval", 100);
	  option("undoDepth", 200, function (cm, val) { return cm.doc.history.undoDepth = val; });
	  option("historyEventDelay", 1250);
	  option("viewportMargin", 10, function (cm) { return cm.refresh(); }, true);
	  option("maxHighlightLength", 10000, resetModeState, true);
	  option("moveInputWithCursor", true, function (cm, val) {
	    if (!val) { cm.display.input.resetPosition(); }
	  });
	
	  option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; });
	  option("autofocus", null);
	  option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true);
	}
	
	function guttersChanged(cm) {
	  updateGutters(cm);
	  regChange(cm);
	  alignHorizontally(cm);
	}
	
	function dragDropChanged(cm, value, old) {
	  var wasOn = old && old != Init;
	  if (!value != !wasOn) {
	    var funcs = cm.display.dragFunctions;
	    var toggle = value ? on : off;
	    toggle(cm.display.scroller, "dragstart", funcs.start);
	    toggle(cm.display.scroller, "dragenter", funcs.enter);
	    toggle(cm.display.scroller, "dragover", funcs.over);
	    toggle(cm.display.scroller, "dragleave", funcs.leave);
	    toggle(cm.display.scroller, "drop", funcs.drop);
	  }
	}
	
	function wrappingChanged(cm) {
	  if (cm.options.lineWrapping) {
	    addClass(cm.display.wrapper, "CodeMirror-wrap");
	    cm.display.sizer.style.minWidth = "";
	    cm.display.sizerWidth = null;
	  } else {
	    rmClass(cm.display.wrapper, "CodeMirror-wrap");
	    findMaxLine(cm);
	  }
	  estimateLineHeights(cm);
	  regChange(cm);
	  clearCaches(cm);
	  setTimeout(function () { return updateScrollbars(cm); }, 100);
	}
	
	// A CodeMirror instance represents an editor. This is the object
	// that user code is usually dealing with.
	
	function CodeMirror$1(place, options) {
	  var this$1 = this;
	
	  if (!(this instanceof CodeMirror$1)) { return new CodeMirror$1(place, options) }
	
	  this.options = options = options ? copyObj(options) : {};
	  // Determine effective options based on given values and defaults.
	  copyObj(defaults, options, false);
	  setGuttersForLineNumbers(options);
	
	  var doc = options.value;
	  if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction); }
	  this.doc = doc;
	
	  var input = new CodeMirror$1.inputStyles[options.inputStyle](this);
	  var display = this.display = new Display(place, doc, input);
	  display.wrapper.CodeMirror = this;
	  updateGutters(this);
	  themeChanged(this);
	  if (options.lineWrapping)
	    { this.display.wrapper.className += " CodeMirror-wrap"; }
	  initScrollbars(this);
	
	  this.state = {
	    keyMaps: [],  // stores maps added by addKeyMap
	    overlays: [], // highlighting overlays, as added by addOverlay
	    modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
	    overwrite: false,
	    delayingBlurEvent: false,
	    focused: false,
	    suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
	    pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
	    selectingText: false,
	    draggingText: false,
	    highlight: new Delayed(), // stores highlight worker timeout
	    keySeq: null,  // Unfinished key sequence
	    specialChars: null
	  };
	
	  if (options.autofocus && !mobile) { display.input.focus(); }
	
	  // Override magic textarea content restore that IE sometimes does
	  // on our hidden textarea on reload
	  if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20); }
	
	  registerEventHandlers(this);
	  ensureGlobalHandlers();
	
	  startOperation(this);
	  this.curOp.forceUpdate = true;
	  attachDoc(this, doc);
	
	  if ((options.autofocus && !mobile) || this.hasFocus())
	    { setTimeout(bind(onFocus, this), 20); }
	  else
	    { onBlur(this); }
	
	  for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt))
	    { optionHandlers[opt](this$1, options[opt], Init); } }
	  maybeUpdateLineNumberWidth(this);
	  if (options.finishInit) { options.finishInit(this); }
	  for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1); }
	  endOperation(this);
	  // Suppress optimizelegibility in Webkit, since it breaks text
	  // measuring on line wrapping boundaries.
	  if (webkit && options.lineWrapping &&
	      getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
	    { display.lineDiv.style.textRendering = "auto"; }
	}
	
	// The default configuration options.
	CodeMirror$1.defaults = defaults;
	// Functions to run when options are changed.
	CodeMirror$1.optionHandlers = optionHandlers;
	
	// Attach the necessary event handlers when initializing the editor
	function registerEventHandlers(cm) {
	  var d = cm.display;
	  on(d.scroller, "mousedown", operation(cm, onMouseDown));
	  // Older IE's will not fire a second mousedown for a double click
	  if (ie && ie_version < 11)
	    { on(d.scroller, "dblclick", operation(cm, function (e) {
	      if (signalDOMEvent(cm, e)) { return }
	      var pos = posFromMouse(cm, e);
	      if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return }
	      e_preventDefault(e);
	      var word = cm.findWordAt(pos);
	      extendSelection(cm.doc, word.anchor, word.head);
	    })); }
	  else
	    { on(d.scroller, "dblclick", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }); }
	  // Some browsers fire contextmenu *after* opening the menu, at
	  // which point we can't mess with it anymore. Context menu is
	  // handled in onMouseDown for these browsers.
	  if (!captureRightClick) { on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); }); }
	
	  // Used to suppress mouse event handling when a touch happens
	  var touchFinished, prevTouch = {end: 0};
	  function finishTouch() {
	    if (d.activeTouch) {
	      touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000);
	      prevTouch = d.activeTouch;
	      prevTouch.end = +new Date;
	    }
	  }
	  function isMouseLikeTouchEvent(e) {
	    if (e.touches.length != 1) { return false }
	    var touch = e.touches[0];
	    return touch.radiusX <= 1 && touch.radiusY <= 1
	  }
	  function farAway(touch, other) {
	    if (other.left == null) { return true }
	    var dx = other.left - touch.left, dy = other.top - touch.top;
	    return dx * dx + dy * dy > 20 * 20
	  }
	  on(d.scroller, "touchstart", function (e) {
	    if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) {
	      d.input.ensurePolled();
	      clearTimeout(touchFinished);
	      var now = +new Date;
	      d.activeTouch = {start: now, moved: false,
	                       prev: now - prevTouch.end <= 300 ? prevTouch : null};
	      if (e.touches.length == 1) {
	        d.activeTouch.left = e.touches[0].pageX;
	        d.activeTouch.top = e.touches[0].pageY;
	      }
	    }
	  });
	  on(d.scroller, "touchmove", function () {
	    if (d.activeTouch) { d.activeTouch.moved = true; }
	  });
	  on(d.scroller, "touchend", function (e) {
	    var touch = d.activeTouch;
	    if (touch && !eventInWidget(d, e) && touch.left != null &&
	        !touch.moved && new Date - touch.start < 300) {
	      var pos = cm.coordsChar(d.activeTouch, "page"), range;
	      if (!touch.prev || farAway(touch, touch.prev)) // Single tap
	        { range = new Range(pos, pos); }
	      else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap
	        { range = cm.findWordAt(pos); }
	      else // Triple tap
	        { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); }
	      cm.setSelection(range.anchor, range.head);
	      cm.focus();
	      e_preventDefault(e);
	    }
	    finishTouch();
	  });
	  on(d.scroller, "touchcancel", finishTouch);
	
	  // Sync scrolling between fake scrollbars and real scrollable
	  // area, ensure viewport is updated when scrolling.
	  on(d.scroller, "scroll", function () {
	    if (d.scroller.clientHeight) {
	      updateScrollTop(cm, d.scroller.scrollTop);
	      setScrollLeft(cm, d.scroller.scrollLeft, true);
	      signal(cm, "scroll", cm);
	    }
	  });
	
	  // Listen to wheel events in order to try and update the viewport on time.
	  on(d.scroller, "mousewheel", function (e) { return onScrollWheel(cm, e); });
	  on(d.scroller, "DOMMouseScroll", function (e) { return onScrollWheel(cm, e); });
	
	  // Prevent wrapper from ever scrolling
	  on(d.wrapper, "scroll", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
	
	  d.dragFunctions = {
	    enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e); }},
	    over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }},
	    start: function (e) { return onDragStart(cm, e); },
	    drop: operation(cm, onDrop),
	    leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); }}
	  };
	
	  var inp = d.input.getField();
	  on(inp, "keyup", function (e) { return onKeyUp.call(cm, e); });
	  on(inp, "keydown", operation(cm, onKeyDown));
	  on(inp, "keypress", operation(cm, onKeyPress));
	  on(inp, "focus", function (e) { return onFocus(cm, e); });
	  on(inp, "blur", function (e) { return onBlur(cm, e); });
	}
	
	var initHooks = [];
	CodeMirror$1.defineInitHook = function (f) { return initHooks.push(f); };
	
	// Indent the given line. The how parameter can be "smart",
	// "add"/null, "subtract", or "prev". When aggressive is false
	// (typically set to true for forced single-line indents), empty
	// lines are not indented, and places where the mode returns Pass
	// are left alone.
	function indentLine(cm, n, how, aggressive) {
	  var doc = cm.doc, state;
	  if (how == null) { how = "add"; }
	  if (how == "smart") {
	    // Fall back to "prev" when the mode doesn't have an indentation
	    // method.
	    if (!doc.mode.indent) { how = "prev"; }
	    else { state = getContextBefore(cm, n).state; }
	  }
	
	  var tabSize = cm.options.tabSize;
	  var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
	  if (line.stateAfter) { line.stateAfter = null; }
	  var curSpaceString = line.text.match(/^\s*/)[0], indentation;
	  if (!aggressive && !/\S/.test(line.text)) {
	    indentation = 0;
	    how = "not";
	  } else if (how == "smart") {
	    indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
	    if (indentation == Pass || indentation > 150) {
	      if (!aggressive) { return }
	      how = "prev";
	    }
	  }
	  if (how == "prev") {
	    if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize); }
	    else { indentation = 0; }
	  } else if (how == "add") {
	    indentation = curSpace + cm.options.indentUnit;
	  } else if (how == "subtract") {
	    indentation = curSpace - cm.options.indentUnit;
	  } else if (typeof how == "number") {
	    indentation = curSpace + how;
	  }
	  indentation = Math.max(0, indentation);
	
	  var indentString = "", pos = 0;
	  if (cm.options.indentWithTabs)
	    { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} }
	  if (pos < indentation) { indentString += spaceStr(indentation - pos); }
	
	  if (indentString != curSpaceString) {
	    replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
	    line.stateAfter = null;
	    return true
	  } else {
	    // Ensure that, if the cursor was in the whitespace at the start
	    // of the line, it is moved to the end of that space.
	    for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) {
	      var range = doc.sel.ranges[i$1];
	      if (range.head.line == n && range.head.ch < curSpaceString.length) {
	        var pos$1 = Pos(n, curSpaceString.length);
	        replaceOneSelection(doc, i$1, new Range(pos$1, pos$1));
	        break
	      }
	    }
	  }
	}
	
	// This will be set to a {lineWise: bool, text: [string]} object, so
	// that, when pasting, we know what kind of selections the copied
	// text was made out of.
	var lastCopied = null;
	
	function setLastCopied(newLastCopied) {
	  lastCopied = newLastCopied;
	}
	
	function applyTextInput(cm, inserted, deleted, sel, origin) {
	  var doc = cm.doc;
	  cm.display.shift = false;
	  if (!sel) { sel = doc.sel; }
	
	  var paste = cm.state.pasteIncoming || origin == "paste";
	  var textLines = splitLinesAuto(inserted), multiPaste = null;
	  // When pasing N lines into N selections, insert one line per selection
	  if (paste && sel.ranges.length > 1) {
	    if (lastCopied && lastCopied.text.join("\n") == inserted) {
	      if (sel.ranges.length % lastCopied.text.length == 0) {
	        multiPaste = [];
	        for (var i = 0; i < lastCopied.text.length; i++)
	          { multiPaste.push(doc.splitLines(lastCopied.text[i])); }
	      }
	    } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) {
	      multiPaste = map(textLines, function (l) { return [l]; });
	    }
	  }
	
	  var updateInput;
	  // Normal behavior is to insert the new text into every selection
	  for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) {
	    var range$$1 = sel.ranges[i$1];
	    var from = range$$1.from(), to = range$$1.to();
	    if (range$$1.empty()) {
	      if (deleted && deleted > 0) // Handle deletion
	        { from = Pos(from.line, from.ch - deleted); }
	      else if (cm.state.overwrite && !paste) // Handle overwrite
	        { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); }
	      else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
	        { from = to = Pos(from.line, 0); }
	    }
	    updateInput = cm.curOp.updateInput;
	    var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,
	                       origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
	    makeChange(cm.doc, changeEvent);
	    signalLater(cm, "inputRead", cm, changeEvent);
	  }
	  if (inserted && !paste)
	    { triggerElectric(cm, inserted); }
	
	  ensureCursorVisible(cm);
	  cm.curOp.updateInput = updateInput;
	  cm.curOp.typing = true;
	  cm.state.pasteIncoming = cm.state.cutIncoming = false;
	}
	
	function handlePaste(e, cm) {
	  var pasted = e.clipboardData && e.clipboardData.getData("Text");
	  if (pasted) {
	    e.preventDefault();
	    if (!cm.isReadOnly() && !cm.options.disableInput)
	      { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }); }
	    return true
	  }
	}
	
	function triggerElectric(cm, inserted) {
	  // When an 'electric' character is inserted, immediately trigger a reindent
	  if (!cm.options.electricChars || !cm.options.smartIndent) { return }
	  var sel = cm.doc.sel;
	
	  for (var i = sel.ranges.length - 1; i >= 0; i--) {
	    var range$$1 = sel.ranges[i];
	    if (range$$1.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range$$1.head.line)) { continue }
	    var mode = cm.getModeAt(range$$1.head);
	    var indented = false;
	    if (mode.electricChars) {
	      for (var j = 0; j < mode.electricChars.length; j++)
	        { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
	          indented = indentLine(cm, range$$1.head.line, "smart");
	          break
	        } }
	    } else if (mode.electricInput) {
	      if (mode.electricInput.test(getLine(cm.doc, range$$1.head.line).text.slice(0, range$$1.head.ch)))
	        { indented = indentLine(cm, range$$1.head.line, "smart"); }
	    }
	    if (indented) { signalLater(cm, "electricInput", cm, range$$1.head.line); }
	  }
	}
	
	function copyableRanges(cm) {
	  var text = [], ranges = [];
	  for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
	    var line = cm.doc.sel.ranges[i].head.line;
	    var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
	    ranges.push(lineRange);
	    text.push(cm.getRange(lineRange.anchor, lineRange.head));
	  }
	  return {text: text, ranges: ranges}
	}
	
	function disableBrowserMagic(field, spellcheck) {
	  field.setAttribute("autocorrect", "off");
	  field.setAttribute("autocapitalize", "off");
	  field.setAttribute("spellcheck", !!spellcheck);
	}
	
	function hiddenTextarea() {
	  var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none");
	  var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
	  // The textarea is kept positioned near the cursor to prevent the
	  // fact that it'll be scrolled into view on input from scrolling
	  // our fake cursor out of view. On webkit, when wrap=off, paste is
	  // very slow. So make the area wide instead.
	  if (webkit) { te.style.width = "1000px"; }
	  else { te.setAttribute("wrap", "off"); }
	  // If border: 0; -- iOS fails to open keyboard (issue #1287)
	  if (ios) { te.style.border = "1px solid black"; }
	  disableBrowserMagic(te);
	  return div
	}
	
	// The publicly visible API. Note that methodOp(f) means
	// 'wrap f in an operation, performed on its `this` parameter'.
	
	// This is not the complete set of editor methods. Most of the
	// methods defined on the Doc type are also injected into
	// CodeMirror.prototype, for backwards compatibility and
	// convenience.
	
	var addEditorMethods = function(CodeMirror) {
	  var optionHandlers = CodeMirror.optionHandlers;
	
	  var helpers = CodeMirror.helpers = {};
	
	  CodeMirror.prototype = {
	    constructor: CodeMirror,
	    focus: function(){window.focus(); this.display.input.focus();},
	
	    setOption: function(option, value) {
	      var options = this.options, old = options[option];
	      if (options[option] == value && option != "mode") { return }
	      options[option] = value;
	      if (optionHandlers.hasOwnProperty(option))
	        { operation(this, optionHandlers[option])(this, value, old); }
	      signal(this, "optionChange", this, option);
	    },
	
	    getOption: function(option) {return this.options[option]},
	    getDoc: function() {return this.doc},
	
	    addKeyMap: function(map$$1, bottom) {
	      this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map$$1));
	    },
	    removeKeyMap: function(map$$1) {
	      var maps = this.state.keyMaps;
	      for (var i = 0; i < maps.length; ++i)
	        { if (maps[i] == map$$1 || maps[i].name == map$$1) {
	          maps.splice(i, 1);
	          return true
	        } }
	    },
	
	    addOverlay: methodOp(function(spec, options) {
	      var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
	      if (mode.startState) { throw new Error("Overlays may not be stateful.") }
	      insertSorted(this.state.overlays,
	                   {mode: mode, modeSpec: spec, opaque: options && options.opaque,
	                    priority: (options && options.priority) || 0},
	                   function (overlay) { return overlay.priority; });
	      this.state.modeGen++;
	      regChange(this);
	    }),
	    removeOverlay: methodOp(function(spec) {
	      var this$1 = this;
	
	      var overlays = this.state.overlays;
	      for (var i = 0; i < overlays.length; ++i) {
	        var cur = overlays[i].modeSpec;
	        if (cur == spec || typeof spec == "string" && cur.name == spec) {
	          overlays.splice(i, 1);
	          this$1.state.modeGen++;
	          regChange(this$1);
	          return
	        }
	      }
	    }),
	
	    indentLine: methodOp(function(n, dir, aggressive) {
	      if (typeof dir != "string" && typeof dir != "number") {
	        if (dir == null) { dir = this.options.smartIndent ? "smart" : "prev"; }
	        else { dir = dir ? "add" : "subtract"; }
	      }
	      if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive); }
	    }),
	    indentSelection: methodOp(function(how) {
	      var this$1 = this;
	
	      var ranges = this.doc.sel.ranges, end = -1;
	      for (var i = 0; i < ranges.length; i++) {
	        var range$$1 = ranges[i];
	        if (!range$$1.empty()) {
	          var from = range$$1.from(), to = range$$1.to();
	          var start = Math.max(end, from.line);
	          end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
	          for (var j = start; j < end; ++j)
	            { indentLine(this$1, j, how); }
	          var newRanges = this$1.doc.sel.ranges;
	          if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
	            { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); }
	        } else if (range$$1.head.line > end) {
	          indentLine(this$1, range$$1.head.line, how, true);
	          end = range$$1.head.line;
	          if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1); }
	        }
	      }
	    }),
	
	    // Fetch the parser token for a given character. Useful for hacks
	    // that want to inspect the mode state (say, for completion).
	    getTokenAt: function(pos, precise) {
	      return takeToken(this, pos, precise)
	    },
	
	    getLineTokens: function(line, precise) {
	      return takeToken(this, Pos(line), precise, true)
	    },
	
	    getTokenTypeAt: function(pos) {
	      pos = clipPos(this.doc, pos);
	      var styles = getLineStyles(this, getLine(this.doc, pos.line));
	      var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
	      var type;
	      if (ch == 0) { type = styles[2]; }
	      else { for (;;) {
	        var mid = (before + after) >> 1;
	        if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid; }
	        else if (styles[mid * 2 + 1] < ch) { before = mid + 1; }
	        else { type = styles[mid * 2 + 2]; break }
	      } }
	      var cut = type ? type.indexOf("overlay ") : -1;
	      return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1)
	    },
	
	    getModeAt: function(pos) {
	      var mode = this.doc.mode;
	      if (!mode.innerMode) { return mode }
	      return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode
	    },
	
	    getHelper: function(pos, type) {
	      return this.getHelpers(pos, type)[0]
	    },
	
	    getHelpers: function(pos, type) {
	      var this$1 = this;
	
	      var found = [];
	      if (!helpers.hasOwnProperty(type)) { return found }
	      var help = helpers[type], mode = this.getModeAt(pos);
	      if (typeof mode[type] == "string") {
	        if (help[mode[type]]) { found.push(help[mode[type]]); }
	      } else if (mode[type]) {
	        for (var i = 0; i < mode[type].length; i++) {
	          var val = help[mode[type][i]];
	          if (val) { found.push(val); }
	        }
	      } else if (mode.helperType && help[mode.helperType]) {
	        found.push(help[mode.helperType]);
	      } else if (help[mode.name]) {
	        found.push(help[mode.name]);
	      }
	      for (var i$1 = 0; i$1 < help._global.length; i$1++) {
	        var cur = help._global[i$1];
	        if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1)
	          { found.push(cur.val); }
	      }
	      return found
	    },
	
	    getStateAfter: function(line, precise) {
	      var doc = this.doc;
	      line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
	      return getContextBefore(this, line + 1, precise).state
	    },
	
	    cursorCoords: function(start, mode) {
	      var pos, range$$1 = this.doc.sel.primary();
	      if (start == null) { pos = range$$1.head; }
	      else if (typeof start == "object") { pos = clipPos(this.doc, start); }
	      else { pos = start ? range$$1.from() : range$$1.to(); }
	      return cursorCoords(this, pos, mode || "page")
	    },
	
	    charCoords: function(pos, mode) {
	      return charCoords(this, clipPos(this.doc, pos), mode || "page")
	    },
	
	    coordsChar: function(coords, mode) {
	      coords = fromCoordSystem(this, coords, mode || "page");
	      return coordsChar(this, coords.left, coords.top)
	    },
	
	    lineAtHeight: function(height, mode) {
	      height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
	      return lineAtHeight(this.doc, height + this.display.viewOffset)
	    },
	    heightAtLine: function(line, mode, includeWidgets) {
	      var end = false, lineObj;
	      if (typeof line == "number") {
	        var last = this.doc.first + this.doc.size - 1;
	        if (line < this.doc.first) { line = this.doc.first; }
	        else if (line > last) { line = last; end = true; }
	        lineObj = getLine(this.doc, line);
	      } else {
	        lineObj = line;
	      }
	      return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top +
	        (end ? this.doc.height - heightAtLine(lineObj) : 0)
	    },
	
	    defaultTextHeight: function() { return textHeight(this.display) },
	    defaultCharWidth: function() { return charWidth(this.display) },
	
	    getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}},
	
	    addWidget: function(pos, node, scroll, vert, horiz) {
	      var display = this.display;
	      pos = cursorCoords(this, clipPos(this.doc, pos));
	      var top = pos.bottom, left = pos.left;
	      node.style.position = "absolute";
	      node.setAttribute("cm-ignore-events", "true");
	      this.display.input.setUneditable(node);
	      display.sizer.appendChild(node);
	      if (vert == "over") {
	        top = pos.top;
	      } else if (vert == "above" || vert == "near") {
	        var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
	        hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
	        // Default to positioning above (if specified and possible); otherwise default to positioning below
	        if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
	          { top = pos.top - node.offsetHeight; }
	        else if (pos.bottom + node.offsetHeight <= vspace)
	          { top = pos.bottom; }
	        if (left + node.offsetWidth > hspace)
	          { left = hspace - node.offsetWidth; }
	      }
	      node.style.top = top + "px";
	      node.style.left = node.style.right = "";
	      if (horiz == "right") {
	        left = display.sizer.clientWidth - node.offsetWidth;
	        node.style.right = "0px";
	      } else {
	        if (horiz == "left") { left = 0; }
	        else if (horiz == "middle") { left = (display.sizer.clientWidth - node.offsetWidth) / 2; }
	        node.style.left = left + "px";
	      }
	      if (scroll)
	        { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}); }
	    },
	
	    triggerOnKeyDown: methodOp(onKeyDown),
	    triggerOnKeyPress: methodOp(onKeyPress),
	    triggerOnKeyUp: onKeyUp,
	    triggerOnMouseDown: methodOp(onMouseDown),
	
	    execCommand: function(cmd) {
	      if (commands.hasOwnProperty(cmd))
	        { return commands[cmd].call(null, this) }
	    },
	
	    triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
	
	    findPosH: function(from, amount, unit, visually) {
	      var this$1 = this;
	
	      var dir = 1;
	      if (amount < 0) { dir = -1; amount = -amount; }
	      var cur = clipPos(this.doc, from);
	      for (var i = 0; i < amount; ++i) {
	        cur = findPosH(this$1.doc, cur, dir, unit, visually);
	        if (cur.hitSide) { break }
	      }
	      return cur
	    },
	
	    moveH: methodOp(function(dir, unit) {
	      var this$1 = this;
	
	      this.extendSelectionsBy(function (range$$1) {
	        if (this$1.display.shift || this$1.doc.extend || range$$1.empty())
	          { return findPosH(this$1.doc, range$$1.head, dir, unit, this$1.options.rtlMoveVisually) }
	        else
	          { return dir < 0 ? range$$1.from() : range$$1.to() }
	      }, sel_move);
	    }),
	
	    deleteH: methodOp(function(dir, unit) {
	      var sel = this.doc.sel, doc = this.doc;
	      if (sel.somethingSelected())
	        { doc.replaceSelection("", null, "+delete"); }
	      else
	        { deleteNearSelection(this, function (range$$1) {
	          var other = findPosH(doc, range$$1.head, dir, unit, false);
	          return dir < 0 ? {from: other, to: range$$1.head} : {from: range$$1.head, to: other}
	        }); }
	    }),
	
	    findPosV: function(from, amount, unit, goalColumn) {
	      var this$1 = this;
	
	      var dir = 1, x = goalColumn;
	      if (amount < 0) { dir = -1; amount = -amount; }
	      var cur = clipPos(this.doc, from);
	      for (var i = 0; i < amount; ++i) {
	        var coords = cursorCoords(this$1, cur, "div");
	        if (x == null) { x = coords.left; }
	        else { coords.left = x; }
	        cur = findPosV(this$1, coords, dir, unit);
	        if (cur.hitSide) { break }
	      }
	      return cur
	    },
	
	    moveV: methodOp(function(dir, unit) {
	      var this$1 = this;
	
	      var doc = this.doc, goals = [];
	      var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected();
	      doc.extendSelectionsBy(function (range$$1) {
	        if (collapse)
	          { return dir < 0 ? range$$1.from() : range$$1.to() }
	        var headPos = cursorCoords(this$1, range$$1.head, "div");
	        if (range$$1.goalColumn != null) { headPos.left = range$$1.goalColumn; }
	        goals.push(headPos.left);
	        var pos = findPosV(this$1, headPos, dir, unit);
	        if (unit == "page" && range$$1 == doc.sel.primary())
	          { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top); }
	        return pos
	      }, sel_move);
	      if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++)
	        { doc.sel.ranges[i].goalColumn = goals[i]; } }
	    }),
	
	    // Find the word at the given position (as returned by coordsChar).
	    findWordAt: function(pos) {
	      var doc = this.doc, line = getLine(doc, pos.line).text;
	      var start = pos.ch, end = pos.ch;
	      if (line) {
	        var helper = this.getHelper(pos, "wordChars");
	        if ((pos.sticky == "before" || end == line.length) && start) { --start; } else { ++end; }
	        var startChar = line.charAt(start);
	        var check = isWordChar(startChar, helper)
	          ? function (ch) { return isWordChar(ch, helper); }
	          : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); }
	          : function (ch) { return (!/\s/.test(ch) && !isWordChar(ch)); };
	        while (start > 0 && check(line.charAt(start - 1))) { --start; }
	        while (end < line.length && check(line.charAt(end))) { ++end; }
	      }
	      return new Range(Pos(pos.line, start), Pos(pos.line, end))
	    },
	
	    toggleOverwrite: function(value) {
	      if (value != null && value == this.state.overwrite) { return }
	      if (this.state.overwrite = !this.state.overwrite)
	        { addClass(this.display.cursorDiv, "CodeMirror-overwrite"); }
	      else
	        { rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); }
	
	      signal(this, "overwriteToggle", this, this.state.overwrite);
	    },
	    hasFocus: function() { return this.display.input.getField() == activeElt() },
	    isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) },
	
	    scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y); }),
	    getScrollInfo: function() {
	      var scroller = this.display.scroller;
	      return {left: scroller.scrollLeft, top: scroller.scrollTop,
	              height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
	              width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
	              clientHeight: displayHeight(this), clientWidth: displayWidth(this)}
	    },
	
	    scrollIntoView: methodOp(function(range$$1, margin) {
	      if (range$$1 == null) {
	        range$$1 = {from: this.doc.sel.primary().head, to: null};
	        if (margin == null) { margin = this.options.cursorScrollMargin; }
	      } else if (typeof range$$1 == "number") {
	        range$$1 = {from: Pos(range$$1, 0), to: null};
	      } else if (range$$1.from == null) {
	        range$$1 = {from: range$$1, to: null};
	      }
	      if (!range$$1.to) { range$$1.to = range$$1.from; }
	      range$$1.margin = margin || 0;
	
	      if (range$$1.from.line != null) {
	        scrollToRange(this, range$$1);
	      } else {
	        scrollToCoordsRange(this, range$$1.from, range$$1.to, range$$1.margin);
	      }
	    }),
	
	    setSize: methodOp(function(width, height) {
	      var this$1 = this;
	
	      var interpret = function (val) { return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; };
	      if (width != null) { this.display.wrapper.style.width = interpret(width); }
	      if (height != null) { this.display.wrapper.style.height = interpret(height); }
	      if (this.options.lineWrapping) { clearLineMeasurementCache(this); }
	      var lineNo$$1 = this.display.viewFrom;
	      this.doc.iter(lineNo$$1, this.display.viewTo, function (line) {
	        if (line.widgets) { for (var i = 0; i < line.widgets.length; i++)
	          { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo$$1, "widget"); break } } }
	        ++lineNo$$1;
	      });
	      this.curOp.forceUpdate = true;
	      signal(this, "refresh", this);
	    }),
	
	    operation: function(f){return runInOp(this, f)},
	
	    refresh: methodOp(function() {
	      var oldHeight = this.display.cachedTextHeight;
	      regChange(this);
	      this.curOp.forceUpdate = true;
	      clearCaches(this);
	      scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop);
	      updateGutterSpace(this);
	      if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
	        { estimateLineHeights(this); }
	      signal(this, "refresh", this);
	    }),
	
	    swapDoc: methodOp(function(doc) {
	      var old = this.doc;
	      old.cm = null;
	      attachDoc(this, doc);
	      clearCaches(this);
	      this.display.input.reset();
	      scrollToCoords(this, doc.scrollLeft, doc.scrollTop);
	      this.curOp.forceScroll = true;
	      signalLater(this, "swapDoc", this, old);
	      return old
	    }),
	
	    getInputField: function(){return this.display.input.getField()},
	    getWrapperElement: function(){return this.display.wrapper},
	    getScrollerElement: function(){return this.display.scroller},
	    getGutterElement: function(){return this.display.gutters}
	  };
	  eventMixin(CodeMirror);
	
	  CodeMirror.registerHelper = function(type, name, value) {
	    if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []}; }
	    helpers[type][name] = value;
	  };
	  CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
	    CodeMirror.registerHelper(type, name, value);
	    helpers[type]._global.push({pred: predicate, val: value});
	  };
	};
	
	// Used for horizontal relative motion. Dir is -1 or 1 (left or
	// right), unit can be "char", "column" (like char, but doesn't
	// cross line boundaries), "word" (across next word), or "group" (to
	// the start of next group of word or non-word-non-whitespace
	// chars). The visually param controls whether, in right-to-left
	// text, direction 1 means to move towards the next index in the
	// string, or towards the character to the right of the current
	// position. The resulting position will have a hitSide=true
	// property if it reached the end of the document.
	function findPosH(doc, pos, dir, unit, visually) {
	  var oldPos = pos;
	  var origDir = dir;
	  var lineObj = getLine(doc, pos.line);
	  function findNextLine() {
	    var l = pos.line + dir;
	    if (l < doc.first || l >= doc.first + doc.size) { return false }
	    pos = new Pos(l, pos.ch, pos.sticky);
	    return lineObj = getLine(doc, l)
	  }
	  function moveOnce(boundToLine) {
	    var next;
	    if (visually) {
	      next = moveVisually(doc.cm, lineObj, pos, dir);
	    } else {
	      next = moveLogically(lineObj, pos, dir);
	    }
	    if (next == null) {
	      if (!boundToLine && findNextLine())
	        { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir); }
	      else
	        { return false }
	    } else {
	      pos = next;
	    }
	    return true
	  }
	
	  if (unit == "char") {
	    moveOnce();
	  } else if (unit == "column") {
	    moveOnce(true);
	  } else if (unit == "word" || unit == "group") {
	    var sawType = null, group = unit == "group";
	    var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
	    for (var first = true;; first = false) {
	      if (dir < 0 && !moveOnce(!first)) { break }
	      var cur = lineObj.text.charAt(pos.ch) || "\n";
	      var type = isWordChar(cur, helper) ? "w"
	        : group && cur == "\n" ? "n"
	        : !group || /\s/.test(cur) ? null
	        : "p";
	      if (group && !first && !type) { type = "s"; }
	      if (sawType && sawType != type) {
	        if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after";}
	        break
	      }
	
	      if (type) { sawType = type; }
	      if (dir > 0 && !moveOnce(!first)) { break }
	    }
	  }
	  var result = skipAtomic(doc, pos, oldPos, origDir, true);
	  if (equalCursorPos(oldPos, result)) { result.hitSide = true; }
	  return result
	}
	
	// For relative vertical movement. Dir may be -1 or 1. Unit can be
	// "page" or "line". The resulting position will have a hitSide=true
	// property if it reached the end of the document.
	function findPosV(cm, pos, dir, unit) {
	  var doc = cm.doc, x = pos.left, y;
	  if (unit == "page") {
	    var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
	    var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3);
	    y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount;
	
	  } else if (unit == "line") {
	    y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
	  }
	  var target;
	  for (;;) {
	    target = coordsChar(cm, x, y);
	    if (!target.outside) { break }
	    if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break }
	    y += dir * 5;
	  }
	  return target
	}
	
	// CONTENTEDITABLE INPUT STYLE
	
	var ContentEditableInput = function(cm) {
	  this.cm = cm;
	  this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
	  this.polling = new Delayed();
	  this.composing = null;
	  this.gracePeriod = false;
	  this.readDOMTimeout = null;
	};
	
	ContentEditableInput.prototype.init = function (display) {
	    var this$1 = this;
	
	  var input = this, cm = input.cm;
	  var div = input.div = display.lineDiv;
	  disableBrowserMagic(div, cm.options.spellcheck);
	
	  on(div, "paste", function (e) {
	    if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
	    // IE doesn't fire input events, so we schedule a read for the pasted content in this way
	    if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); }
	  });
	
	  on(div, "compositionstart", function (e) {
	    this$1.composing = {data: e.data, done: false};
	  });
	  on(div, "compositionupdate", function (e) {
	    if (!this$1.composing) { this$1.composing = {data: e.data, done: false}; }
	  });
	  on(div, "compositionend", function (e) {
	    if (this$1.composing) {
	      if (e.data != this$1.composing.data) { this$1.readFromDOMSoon(); }
	      this$1.composing.done = true;
	    }
	  });
	
	  on(div, "touchstart", function () { return input.forceCompositionEnd(); });
	
	  on(div, "input", function () {
	    if (!this$1.composing) { this$1.readFromDOMSoon(); }
	  });
	
	  function onCopyCut(e) {
	    if (signalDOMEvent(cm, e)) { return }
	    if (cm.somethingSelected()) {
	      setLastCopied({lineWise: false, text: cm.getSelections()});
	      if (e.type == "cut") { cm.replaceSelection("", null, "cut"); }
	    } else if (!cm.options.lineWiseCopyCut) {
	      return
	    } else {
	      var ranges = copyableRanges(cm);
	      setLastCopied({lineWise: true, text: ranges.text});
	      if (e.type == "cut") {
	        cm.operation(function () {
	          cm.setSelections(ranges.ranges, 0, sel_dontScroll);
	          cm.replaceSelection("", null, "cut");
	        });
	      }
	    }
	    if (e.clipboardData) {
	      e.clipboardData.clearData();
	      var content = lastCopied.text.join("\n");
	      // iOS exposes the clipboard API, but seems to discard content inserted into it
	      e.clipboardData.setData("Text", content);
	      if (e.clipboardData.getData("Text") == content) {
	        e.preventDefault();
	        return
	      }
	    }
	    // Old-fashioned briefly-focus-a-textarea hack
	    var kludge = hiddenTextarea(), te = kludge.firstChild;
	    cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
	    te.value = lastCopied.text.join("\n");
	    var hadFocus = document.activeElement;
	    selectInput(te);
	    setTimeout(function () {
	      cm.display.lineSpace.removeChild(kludge);
	      hadFocus.focus();
	      if (hadFocus == div) { input.showPrimarySelection(); }
	    }, 50);
	  }
	  on(div, "copy", onCopyCut);
	  on(div, "cut", onCopyCut);
	};
	
	ContentEditableInput.prototype.prepareSelection = function () {
	  var result = prepareSelection(this.cm, false);
	  result.focus = this.cm.state.focused;
	  return result
	};
	
	ContentEditableInput.prototype.showSelection = function (info, takeFocus) {
	  if (!info || !this.cm.display.view.length) { return }
	  if (info.focus || takeFocus) { this.showPrimarySelection(); }
	  this.showMultipleSelections(info);
	};
	
	ContentEditableInput.prototype.showPrimarySelection = function () {
	  var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary();
	  var from = prim.from(), to = prim.to();
	
	  if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {
	    sel.removeAllRanges();
	    return
	  }
	
	  var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
	  var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset);
	  if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
	      cmp(minPos(curAnchor, curFocus), from) == 0 &&
	      cmp(maxPos(curAnchor, curFocus), to) == 0)
	    { return }
	
	  var view = cm.display.view;
	  var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) ||
	      {node: view[0].measure.map[2], offset: 0};
	  var end = to.line < cm.display.viewTo && posToDOM(cm, to);
	  if (!end) {
	    var measure = view[view.length - 1].measure;
	    var map$$1 = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
	    end = {node: map$$1[map$$1.length - 1], offset: map$$1[map$$1.length - 2] - map$$1[map$$1.length - 3]};
	  }
	
	  if (!start || !end) {
	    sel.removeAllRanges();
	    return
	  }
	
	  var old = sel.rangeCount && sel.getRangeAt(0), rng;
	  try { rng = range(start.node, start.offset, end.offset, end.node); }
	  catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
	  if (rng) {
	    if (!gecko && cm.state.focused) {
	      sel.collapse(start.node, start.offset);
	      if (!rng.collapsed) {
	        sel.removeAllRanges();
	        sel.addRange(rng);
	      }
	    } else {
	      sel.removeAllRanges();
	      sel.addRange(rng);
	    }
	    if (old && sel.anchorNode == null) { sel.addRange(old); }
	    else if (gecko) { this.startGracePeriod(); }
	  }
	  this.rememberSelection();
	};
	
	ContentEditableInput.prototype.startGracePeriod = function () {
	    var this$1 = this;
	
	  clearTimeout(this.gracePeriod);
	  this.gracePeriod = setTimeout(function () {
	    this$1.gracePeriod = false;
	    if (this$1.selectionChanged())
	      { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }); }
	  }, 20);
	};
	
	ContentEditableInput.prototype.showMultipleSelections = function (info) {
	  removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
	  removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
	};
	
	ContentEditableInput.prototype.rememberSelection = function () {
	  var sel = window.getSelection();
	  this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
	  this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
	};
	
	ContentEditableInput.prototype.selectionInEditor = function () {
	  var sel = window.getSelection();
	  if (!sel.rangeCount) { return false }
	  var node = sel.getRangeAt(0).commonAncestorContainer;
	  return contains(this.div, node)
	};
	
	ContentEditableInput.prototype.focus = function () {
	  if (this.cm.options.readOnly != "nocursor") {
	    if (!this.selectionInEditor())
	      { this.showSelection(this.prepareSelection(), true); }
	    this.div.focus();
	  }
	};
	ContentEditableInput.prototype.blur = function () { this.div.blur(); };
	ContentEditableInput.prototype.getField = function () { return this.div };
	
	ContentEditableInput.prototype.supportsTouch = function () { return true };
	
	ContentEditableInput.prototype.receivedFocus = function () {
	  var input = this;
	  if (this.selectionInEditor())
	    { this.pollSelection(); }
	  else
	    { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }); }
	
	  function poll() {
	    if (input.cm.state.focused) {
	      input.pollSelection();
	      input.polling.set(input.cm.options.pollInterval, poll);
	    }
	  }
	  this.polling.set(this.cm.options.pollInterval, poll);
	};
	
	ContentEditableInput.prototype.selectionChanged = function () {
	  var sel = window.getSelection();
	  return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
	    sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset
	};
	
	ContentEditableInput.prototype.pollSelection = function () {
	  if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return }
	  var sel = window.getSelection(), cm = this.cm;
	  // On Android Chrome (version 56, at least), backspacing into an
	  // uneditable block element will put the cursor in that element,
	  // and then, because it's not editable, hide the virtual keyboard.
	  // Because Android doesn't allow us to actually detect backspace
	  // presses in a sane way, this code checks for when that happens
	  // and simulates a backspace press in this case.
	  if (android && chrome && this.cm.options.gutters.length && isInGutter(sel.anchorNode)) {
	    this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs});
	    this.blur();
	    this.focus();
	    return
	  }
	  if (this.composing) { return }
	  this.rememberSelection();
	  var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
	  var head = domToPos(cm, sel.focusNode, sel.focusOffset);
	  if (anchor && head) { runInOp(cm, function () {
	    setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
	    if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true; }
	  }); }
	};
	
	ContentEditableInput.prototype.pollContent = function () {
	  if (this.readDOMTimeout != null) {
	    clearTimeout(this.readDOMTimeout);
	    this.readDOMTimeout = null;
	  }
	
	  var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
	  var from = sel.from(), to = sel.to();
	  if (from.ch == 0 && from.line > cm.firstLine())
	    { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length); }
	  if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine())
	    { to = Pos(to.line + 1, 0); }
	  if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false }
	
	  var fromIndex, fromLine, fromNode;
	  if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
	    fromLine = lineNo(display.view[0].line);
	    fromNode = display.view[0].node;
	  } else {
	    fromLine = lineNo(display.view[fromIndex].line);
	    fromNode = display.view[fromIndex - 1].node.nextSibling;
	  }
	  var toIndex = findViewIndex(cm, to.line);
	  var toLine, toNode;
	  if (toIndex == display.view.length - 1) {
	    toLine = display.viewTo - 1;
	    toNode = display.lineDiv.lastChild;
	  } else {
	    toLine = lineNo(display.view[toIndex + 1].line) - 1;
	    toNode = display.view[toIndex + 1].node.previousSibling;
	  }
	
	  if (!fromNode) { return false }
	  var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
	  var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
	  while (newText.length > 1 && oldText.length > 1) {
	    if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
	    else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
	    else { break }
	  }
	
	  var cutFront = 0, cutEnd = 0;
	  var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
	  while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
	    { ++cutFront; }
	  var newBot = lst(newText), oldBot = lst(oldText);
	  var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
	                           oldBot.length - (oldText.length == 1 ? cutFront : 0));
	  while (cutEnd < maxCutEnd &&
	         newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
	    { ++cutEnd; }
	  // Try to move start of change to start of selection if ambiguous
	  if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) {
	    while (cutFront && cutFront > from.ch &&
	           newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) {
	      cutFront--;
	      cutEnd++;
	    }
	  }
	
	  newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, "");
	  newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, "");
	
	  var chFrom = Pos(fromLine, cutFront);
	  var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
	  if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
	    replaceRange(cm.doc, newText, chFrom, chTo, "+input");
	    return true
	  }
	};
	
	ContentEditableInput.prototype.ensurePolled = function () {
	  this.forceCompositionEnd();
	};
	ContentEditableInput.prototype.reset = function () {
	  this.forceCompositionEnd();
	};
	ContentEditableInput.prototype.forceCompositionEnd = function () {
	  if (!this.composing) { return }
	  clearTimeout(this.readDOMTimeout);
	  this.composing = null;
	  this.updateFromDOM();
	  this.div.blur();
	  this.div.focus();
	};
	ContentEditableInput.prototype.readFromDOMSoon = function () {
	    var this$1 = this;
	
	  if (this.readDOMTimeout != null) { return }
	  this.readDOMTimeout = setTimeout(function () {
	    this$1.readDOMTimeout = null;
	    if (this$1.composing) {
	      if (this$1.composing.done) { this$1.composing = null; }
	      else { return }
	    }
	    this$1.updateFromDOM();
	  }, 80);
	};
	
	ContentEditableInput.prototype.updateFromDOM = function () {
	    var this$1 = this;
	
	  if (this.cm.isReadOnly() || !this.pollContent())
	    { runInOp(this.cm, function () { return regChange(this$1.cm); }); }
	};
	
	ContentEditableInput.prototype.setUneditable = function (node) {
	  node.contentEditable = "false";
	};
	
	ContentEditableInput.prototype.onKeyPress = function (e) {
	  if (e.charCode == 0) { return }
	  e.preventDefault();
	  if (!this.cm.isReadOnly())
	    { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); }
	};
	
	ContentEditableInput.prototype.readOnlyChanged = function (val) {
	  this.div.contentEditable = String(val != "nocursor");
	};
	
	ContentEditableInput.prototype.onContextMenu = function () {};
	ContentEditableInput.prototype.resetPosition = function () {};
	
	ContentEditableInput.prototype.needsContentAttribute = true;
	
	function posToDOM(cm, pos) {
	  var view = findViewForLine(cm, pos.line);
	  if (!view || view.hidden) { return null }
	  var line = getLine(cm.doc, pos.line);
	  var info = mapFromLineView(view, line, pos.line);
	
	  var order = getOrder(line, cm.doc.direction), side = "left";
	  if (order) {
	    var partPos = getBidiPartAt(order, pos.ch);
	    side = partPos % 2 ? "right" : "left";
	  }
	  var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
	  result.offset = result.collapse == "right" ? result.end : result.start;
	  return result
	}
	
	function isInGutter(node) {
	  for (var scan = node; scan; scan = scan.parentNode)
	    { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } }
	  return false
	}
	
	function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
	
	function domTextBetween(cm, from, to, fromLine, toLine) {
	  var text = "", closing = false, lineSep = cm.doc.lineSeparator();
	  function recognizeMarker(id) { return function (marker) { return marker.id == id; } }
	  function close() {
	    if (closing) {
	      text += lineSep;
	      closing = false;
	    }
	  }
	  function addText(str) {
	    if (str) {
	      close();
	      text += str;
	    }
	  }
	  function walk(node) {
	    if (node.nodeType == 1) {
	      var cmText = node.getAttribute("cm-text");
	      if (cmText != null) {
	        addText(cmText || node.textContent.replace(/\u200b/g, ""));
	        return
	      }
	      var markerID = node.getAttribute("cm-marker"), range$$1;
	      if (markerID) {
	        var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
	        if (found.length && (range$$1 = found[0].find()))
	          { addText(getBetween(cm.doc, range$$1.from, range$$1.to).join(lineSep)); }
	        return
	      }
	      if (node.getAttribute("contenteditable") == "false") { return }
	      var isBlock = /^(pre|div|p)$/i.test(node.nodeName);
	      if (isBlock) { close(); }
	      for (var i = 0; i < node.childNodes.length; i++)
	        { walk(node.childNodes[i]); }
	      if (isBlock) { closing = true; }
	    } else if (node.nodeType == 3) {
	      addText(node.nodeValue);
	    }
	  }
	  for (;;) {
	    walk(from);
	    if (from == to) { break }
	    from = from.nextSibling;
	  }
	  return text
	}
	
	function domToPos(cm, node, offset) {
	  var lineNode;
	  if (node == cm.display.lineDiv) {
	    lineNode = cm.display.lineDiv.childNodes[offset];
	    if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) }
	    node = null; offset = 0;
	  } else {
	    for (lineNode = node;; lineNode = lineNode.parentNode) {
	      if (!lineNode || lineNode == cm.display.lineDiv) { return null }
	      if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break }
	    }
	  }
	  for (var i = 0; i < cm.display.view.length; i++) {
	    var lineView = cm.display.view[i];
	    if (lineView.node == lineNode)
	      { return locateNodeInLineView(lineView, node, offset) }
	  }
	}
	
	function locateNodeInLineView(lineView, node, offset) {
	  var wrapper = lineView.text.firstChild, bad = false;
	  if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) }
	  if (node == wrapper) {
	    bad = true;
	    node = wrapper.childNodes[offset];
	    offset = 0;
	    if (!node) {
	      var line = lineView.rest ? lst(lineView.rest) : lineView.line;
	      return badPos(Pos(lineNo(line), line.text.length), bad)
	    }
	  }
	
	  var textNode = node.nodeType == 3 ? node : null, topNode = node;
	  if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
	    textNode = node.firstChild;
	    if (offset) { offset = textNode.nodeValue.length; }
	  }
	  while (topNode.parentNode != wrapper) { topNode = topNode.parentNode; }
	  var measure = lineView.measure, maps = measure.maps;
	
	  function find(textNode, topNode, offset) {
	    for (var i = -1; i < (maps ? maps.length : 0); i++) {
	      var map$$1 = i < 0 ? measure.map : maps[i];
	      for (var j = 0; j < map$$1.length; j += 3) {
	        var curNode = map$$1[j + 2];
	        if (curNode == textNode || curNode == topNode) {
	          var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
	          var ch = map$$1[j] + offset;
	          if (offset < 0 || curNode != textNode) { ch = map$$1[j + (offset ? 1 : 0)]; }
	          return Pos(line, ch)
	        }
	      }
	    }
	  }
	  var found = find(textNode, topNode, offset);
	  if (found) { return badPos(found, bad) }
	
	  // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
	  for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
	    found = find(after, after.firstChild, 0);
	    if (found)
	      { return badPos(Pos(found.line, found.ch - dist), bad) }
	    else
	      { dist += after.textContent.length; }
	  }
	  for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) {
	    found = find(before, before.firstChild, -1);
	    if (found)
	      { return badPos(Pos(found.line, found.ch + dist$1), bad) }
	    else
	      { dist$1 += before.textContent.length; }
	  }
	}
	
	// TEXTAREA INPUT STYLE
	
	var TextareaInput = function(cm) {
	  this.cm = cm;
	  // See input.poll and input.reset
	  this.prevInput = "";
	
	  // Flag that indicates whether we expect input to appear real soon
	  // now (after some event like 'keypress' or 'input') and are
	  // polling intensively.
	  this.pollingFast = false;
	  // Self-resetting timeout for the poller
	  this.polling = new Delayed();
	  // Tracks when input.reset has punted to just putting a short
	  // string into the textarea instead of the full selection.
	  this.inaccurateSelection = false;
	  // Used to work around IE issue with selection being forgotten when focus moves away from textarea
	  this.hasSelection = false;
	  this.composing = null;
	};
	
	TextareaInput.prototype.init = function (display) {
	    var this$1 = this;
	
	  var input = this, cm = this.cm;
	
	  // Wraps and hides input textarea
	  var div = this.wrapper = hiddenTextarea();
	  // The semihidden textarea that is focused when the editor is
	  // focused, and receives input.
	  var te = this.textarea = div.firstChild;
	  display.wrapper.insertBefore(div, display.wrapper.firstChild);
	
	  // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
	  if (ios) { te.style.width = "0px"; }
	
	  on(te, "input", function () {
	    if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null; }
	    input.poll();
	  });
	
	  on(te, "paste", function (e) {
	    if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
	
	    cm.state.pasteIncoming = true;
	    input.fastPoll();
	  });
	
	  function prepareCopyCut(e) {
	    if (signalDOMEvent(cm, e)) { return }
	    if (cm.somethingSelected()) {
	      setLastCopied({lineWise: false, text: cm.getSelections()});
	      if (input.inaccurateSelection) {
	        input.prevInput = "";
	        input.inaccurateSelection = false;
	        te.value = lastCopied.text.join("\n");
	        selectInput(te);
	      }
	    } else if (!cm.options.lineWiseCopyCut) {
	      return
	    } else {
	      var ranges = copyableRanges(cm);
	      setLastCopied({lineWise: true, text: ranges.text});
	      if (e.type == "cut") {
	        cm.setSelections(ranges.ranges, null, sel_dontScroll);
	      } else {
	        input.prevInput = "";
	        te.value = ranges.text.join("\n");
	        selectInput(te);
	      }
	    }
	    if (e.type == "cut") { cm.state.cutIncoming = true; }
	  }
	  on(te, "cut", prepareCopyCut);
	  on(te, "copy", prepareCopyCut);
	
	  on(display.scroller, "paste", function (e) {
	    if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return }
	    cm.state.pasteIncoming = true;
	    input.focus();
	  });
	
	  // Prevent normal selection in the editor (we handle our own)
	  on(display.lineSpace, "selectstart", function (e) {
	    if (!eventInWidget(display, e)) { e_preventDefault(e); }
	  });
	
	  on(te, "compositionstart", function () {
	    var start = cm.getCursor("from");
	    if (input.composing) { input.composing.range.clear(); }
	    input.composing = {
	      start: start,
	      range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
	    };
	  });
	  on(te, "compositionend", function () {
	    if (input.composing) {
	      input.poll();
	      input.composing.range.clear();
	      input.composing = null;
	    }
	  });
	};
	
	TextareaInput.prototype.prepareSelection = function () {
	  // Redraw the selection and/or cursor
	  var cm = this.cm, display = cm.display, doc = cm.doc;
	  var result = prepareSelection(cm);
	
	  // Move the hidden textarea near the cursor to prevent scrolling artifacts
	  if (cm.options.moveInputWithCursor) {
	    var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
	    var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
	    result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
	                                        headPos.top + lineOff.top - wrapOff.top));
	    result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
	                                         headPos.left + lineOff.left - wrapOff.left));
	  }
	
	  return result
	};
	
	TextareaInput.prototype.showSelection = function (drawn) {
	  var cm = this.cm, display = cm.display;
	  removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
	  removeChildrenAndAdd(display.selectionDiv, drawn.selection);
	  if (drawn.teTop != null) {
	    this.wrapper.style.top = drawn.teTop + "px";
	    this.wrapper.style.left = drawn.teLeft + "px";
	  }
	};
	
	// Reset the input to correspond to the selection (or to be empty,
	// when not typing and nothing is selected)
	TextareaInput.prototype.reset = function (typing) {
	  if (this.contextMenuPending || this.composing) { return }
	  var minimal, selected, cm = this.cm, doc = cm.doc;
	  if (cm.somethingSelected()) {
	    this.prevInput = "";
	    var range$$1 = doc.sel.primary();
	    minimal = hasCopyEvent &&
	      (range$$1.to().line - range$$1.from().line > 100 || (selected = cm.getSelection()).length > 1000);
	    var content = minimal ? "-" : selected || cm.getSelection();
	    this.textarea.value = content;
	    if (cm.state.focused) { selectInput(this.textarea); }
	    if (ie && ie_version >= 9) { this.hasSelection = content; }
	  } else if (!typing) {
	    this.prevInput = this.textarea.value = "";
	    if (ie && ie_version >= 9) { this.hasSelection = null; }
	  }
	  this.inaccurateSelection = minimal;
	};
	
	TextareaInput.prototype.getField = function () { return this.textarea };
	
	TextareaInput.prototype.supportsTouch = function () { return false };
	
	TextareaInput.prototype.focus = function () {
	  if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
	    try { this.textarea.focus(); }
	    catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
	  }
	};
	
	TextareaInput.prototype.blur = function () { this.textarea.blur(); };
	
	TextareaInput.prototype.resetPosition = function () {
	  this.wrapper.style.top = this.wrapper.style.left = 0;
	};
	
	TextareaInput.prototype.receivedFocus = function () { this.slowPoll(); };
	
	// Poll for input changes, using the normal rate of polling. This
	// runs as long as the editor is focused.
	TextareaInput.prototype.slowPoll = function () {
	    var this$1 = this;
	
	  if (this.pollingFast) { return }
	  this.polling.set(this.cm.options.pollInterval, function () {
	    this$1.poll();
	    if (this$1.cm.state.focused) { this$1.slowPoll(); }
	  });
	};
	
	// When an event has just come in that is likely to add or change
	// something in the input textarea, we poll faster, to ensure that
	// the change appears on the screen quickly.
	TextareaInput.prototype.fastPoll = function () {
	  var missed = false, input = this;
	  input.pollingFast = true;
	  function p() {
	    var changed = input.poll();
	    if (!changed && !missed) {missed = true; input.polling.set(60, p);}
	    else {input.pollingFast = false; input.slowPoll();}
	  }
	  input.polling.set(20, p);
	};
	
	// Read input from the textarea, and update the document to match.
	// When something is selected, it is present in the textarea, and
	// selected (unless it is huge, in which case a placeholder is
	// used). When nothing is selected, the cursor sits after previously
	// seen text (can be empty), which is stored in prevInput (we must
	// not reset the textarea when typing, because that breaks IME).
	TextareaInput.prototype.poll = function () {
	    var this$1 = this;
	
	  var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
	  // Since this is called a *lot*, try to bail out as cheaply as
	  // possible when it is clear that nothing happened. hasSelection
	  // will be the case when there is a lot of text in the textarea,
	  // in which case reading its value would be expensive.
	  if (this.contextMenuPending || !cm.state.focused ||
	      (hasSelection(input) && !prevInput && !this.composing) ||
	      cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
	    { return false }
	
	  var text = input.value;
	  // If nothing changed, bail.
	  if (text == prevInput && !cm.somethingSelected()) { return false }
	  // Work around nonsensical selection resetting in IE9/10, and
	  // inexplicable appearance of private area unicode characters on
	  // some key combos in Mac (#2689).
	  if (ie && ie_version >= 9 && this.hasSelection === text ||
	      mac && /[\uf700-\uf7ff]/.test(text)) {
	    cm.display.input.reset();
	    return false
	  }
	
	  if (cm.doc.sel == cm.display.selForContextMenu) {
	    var first = text.charCodeAt(0);
	    if (first == 0x200b && !prevInput) { prevInput = "\u200b"; }
	    if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") }
	  }
	  // Find the part of the input that is actually new
	  var same = 0, l = Math.min(prevInput.length, text.length);
	  while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same; }
	
	  runInOp(cm, function () {
	    applyTextInput(cm, text.slice(same), prevInput.length - same,
	                   null, this$1.composing ? "*compose" : null);
	
	    // Don't leave long text in the textarea, since it makes further polling slow
	    if (text.length > 1000 || text.indexOf("\n") > -1) { input.value = this$1.prevInput = ""; }
	    else { this$1.prevInput = text; }
	
	    if (this$1.composing) {
	      this$1.composing.range.clear();
	      this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor("to"),
	                                         {className: "CodeMirror-composing"});
	    }
	  });
	  return true
	};
	
	TextareaInput.prototype.ensurePolled = function () {
	  if (this.pollingFast && this.poll()) { this.pollingFast = false; }
	};
	
	TextareaInput.prototype.onKeyPress = function () {
	  if (ie && ie_version >= 9) { this.hasSelection = null; }
	  this.fastPoll();
	};
	
	TextareaInput.prototype.onContextMenu = function (e) {
	  var input = this, cm = input.cm, display = cm.display, te = input.textarea;
	  var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
	  if (!pos || presto) { return } // Opera is difficult.
	
	  // Reset the current text selection only if the click is done outside of the selection
	  // and 'resetSelectionOnContextMenu' option is true.
	  var reset = cm.options.resetSelectionOnContextMenu;
	  if (reset && cm.doc.sel.contains(pos) == -1)
	    { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); }
	
	  var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText;
	  input.wrapper.style.cssText = "position: absolute";
	  var wrapperBox = input.wrapper.getBoundingClientRect();
	  te.style.cssText = "position: absolute; width: 30px; height: 30px;\n      top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n      z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n      outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
	  var oldScrollY;
	  if (webkit) { oldScrollY = window.scrollY; } // Work around Chrome issue (#2712)
	  display.input.focus();
	  if (webkit) { window.scrollTo(null, oldScrollY); }
	  display.input.reset();
	  // Adds "Select all" to context menu in FF
	  if (!cm.somethingSelected()) { te.value = input.prevInput = " "; }
	  input.contextMenuPending = true;
	  display.selForContextMenu = cm.doc.sel;
	  clearTimeout(display.detectingSelectAll);
	
	  // Select-all will be greyed out if there's nothing to select, so
	  // this adds a zero-width space so that we can later check whether
	  // it got selected.
	  function prepareSelectAllHack() {
	    if (te.selectionStart != null) {
	      var selected = cm.somethingSelected();
	      var extval = "\u200b" + (selected ? te.value : "");
	      te.value = "\u21da"; // Used to catch context-menu undo
	      te.value = extval;
	      input.prevInput = selected ? "" : "\u200b";
	      te.selectionStart = 1; te.selectionEnd = extval.length;
	      // Re-set this, in case some other handler touched the
	      // selection in the meantime.
	      display.selForContextMenu = cm.doc.sel;
	    }
	  }
	  function rehide() {
	    input.contextMenuPending = false;
	    input.wrapper.style.cssText = oldWrapperCSS;
	    te.style.cssText = oldCSS;
	    if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); }
	
	    // Try to detect the user choosing select-all
	    if (te.selectionStart != null) {
	      if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack(); }
	      var i = 0, poll = function () {
	        if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
	            te.selectionEnd > 0 && input.prevInput == "\u200b") {
	          operation(cm, selectAll)(cm);
	        } else if (i++ < 10) {
	          display.detectingSelectAll = setTimeout(poll, 500);
	        } else {
	          display.selForContextMenu = null;
	          display.input.reset();
	        }
	      };
	      display.detectingSelectAll = setTimeout(poll, 200);
	    }
	  }
	
	  if (ie && ie_version >= 9) { prepareSelectAllHack(); }
	  if (captureRightClick) {
	    e_stop(e);
	    var mouseup = function () {
	      off(window, "mouseup", mouseup);
	      setTimeout(rehide, 20);
	    };
	    on(window, "mouseup", mouseup);
	  } else {
	    setTimeout(rehide, 50);
	  }
	};
	
	TextareaInput.prototype.readOnlyChanged = function (val) {
	  if (!val) { this.reset(); }
	  this.textarea.disabled = val == "nocursor";
	};
	
	TextareaInput.prototype.setUneditable = function () {};
	
	TextareaInput.prototype.needsContentAttribute = false;
	
	function fromTextArea(textarea, options) {
	  options = options ? copyObj(options) : {};
	  options.value = textarea.value;
	  if (!options.tabindex && textarea.tabIndex)
	    { options.tabindex = textarea.tabIndex; }
	  if (!options.placeholder && textarea.placeholder)
	    { options.placeholder = textarea.placeholder; }
	  // Set autofocus to true if this textarea is focused, or if it has
	  // autofocus and no other element is focused.
	  if (options.autofocus == null) {
	    var hasFocus = activeElt();
	    options.autofocus = hasFocus == textarea ||
	      textarea.getAttribute("autofocus") != null && hasFocus == document.body;
	  }
	
	  function save() {textarea.value = cm.getValue();}
	
	  var realSubmit;
	  if (textarea.form) {
	    on(textarea.form, "submit", save);
	    // Deplorable hack to make the submit method do the right thing.
	    if (!options.leaveSubmitMethodAlone) {
	      var form = textarea.form;
	      realSubmit = form.submit;
	      try {
	        var wrappedSubmit = form.submit = function () {
	          save();
	          form.submit = realSubmit;
	          form.submit();
	          form.submit = wrappedSubmit;
	        };
	      } catch(e) {}
	    }
	  }
	
	  options.finishInit = function (cm) {
	    cm.save = save;
	    cm.getTextArea = function () { return textarea; };
	    cm.toTextArea = function () {
	      cm.toTextArea = isNaN; // Prevent this from being ran twice
	      save();
	      textarea.parentNode.removeChild(cm.getWrapperElement());
	      textarea.style.display = "";
	      if (textarea.form) {
	        off(textarea.form, "submit", save);
	        if (typeof textarea.form.submit == "function")
	          { textarea.form.submit = realSubmit; }
	      }
	    };
	  };
	
	  textarea.style.display = "none";
	  var cm = CodeMirror$1(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); },
	    options);
	  return cm
	}
	
	function addLegacyProps(CodeMirror) {
	  CodeMirror.off = off;
	  CodeMirror.on = on;
	  CodeMirror.wheelEventPixels = wheelEventPixels;
	  CodeMirror.Doc = Doc;
	  CodeMirror.splitLines = splitLinesAuto;
	  CodeMirror.countColumn = countColumn;
	  CodeMirror.findColumn = findColumn;
	  CodeMirror.isWordChar = isWordCharBasic;
	  CodeMirror.Pass = Pass;
	  CodeMirror.signal = signal;
	  CodeMirror.Line = Line;
	  CodeMirror.changeEnd = changeEnd;
	  CodeMirror.scrollbarModel = scrollbarModel;
	  CodeMirror.Pos = Pos;
	  CodeMirror.cmpPos = cmp;
	  CodeMirror.modes = modes;
	  CodeMirror.mimeModes = mimeModes;
	  CodeMirror.resolveMode = resolveMode;
	  CodeMirror.getMode = getMode;
	  CodeMirror.modeExtensions = modeExtensions;
	  CodeMirror.extendMode = extendMode;
	  CodeMirror.copyState = copyState;
	  CodeMirror.startState = startState;
	  CodeMirror.innerMode = innerMode;
	  CodeMirror.commands = commands;
	  CodeMirror.keyMap = keyMap;
	  CodeMirror.keyName = keyName;
	  CodeMirror.isModifierKey = isModifierKey;
	  CodeMirror.lookupKey = lookupKey;
	  CodeMirror.normalizeKeyMap = normalizeKeyMap;
	  CodeMirror.StringStream = StringStream;
	  CodeMirror.SharedTextMarker = SharedTextMarker;
	  CodeMirror.TextMarker = TextMarker;
	  CodeMirror.LineWidget = LineWidget;
	  CodeMirror.e_preventDefault = e_preventDefault;
	  CodeMirror.e_stopPropagation = e_stopPropagation;
	  CodeMirror.e_stop = e_stop;
	  CodeMirror.addClass = addClass;
	  CodeMirror.contains = contains;
	  CodeMirror.rmClass = rmClass;
	  CodeMirror.keyNames = keyNames;
	}
	
	// EDITOR CONSTRUCTOR
	
	defineOptions(CodeMirror$1);
	
	addEditorMethods(CodeMirror$1);
	
	// Set up methods on CodeMirror's prototype to redirect to the editor's document.
	var dontDelegate = "iter insert remove copy getEditor constructor".split(" ");
	for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
	  { CodeMirror$1.prototype[prop] = (function(method) {
	    return function() {return method.apply(this.doc, arguments)}
	  })(Doc.prototype[prop]); } }
	
	eventMixin(Doc);
	
	// INPUT HANDLING
	
	CodeMirror$1.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
	
	// MODE DEFINITION AND QUERYING
	
	// Extra arguments are stored as the mode's dependencies, which is
	// used by (legacy) mechanisms like loadmode.js to automatically
	// load a mode. (Preferred mechanism is the require/define calls.)
	CodeMirror$1.defineMode = function(name/*, mode, …*/) {
	  if (!CodeMirror$1.defaults.mode && name != "null") { CodeMirror$1.defaults.mode = name; }
	  defineMode.apply(this, arguments);
	};
	
	CodeMirror$1.defineMIME = defineMIME;
	
	// Minimal default mode.
	CodeMirror$1.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); });
	CodeMirror$1.defineMIME("text/plain", "null");
	
	// EXTENSIONS
	
	CodeMirror$1.defineExtension = function (name, func) {
	  CodeMirror$1.prototype[name] = func;
	};
	CodeMirror$1.defineDocExtension = function (name, func) {
	  Doc.prototype[name] = func;
	};
	
	CodeMirror$1.fromTextArea = fromTextArea;
	
	addLegacyProps(CodeMirror$1);
	
	CodeMirror$1.version = "5.27.2";
	
	return CodeMirror$1;
	
	})));
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/lib/codemirror.js **/


/** START DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/mode.js **/
jupyter.define('@jupyterlab/codemirror@0.3.1/lib/mode.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var CodeMirror = __jupyter_require__('codemirror@^5.24.2/lib/codemirror.js');
	__jupyter_require__('codemirror@^5.24.2/mode/meta.js');
	__jupyter_require__('codemirror@^5.24.2/addon/runmode/runmode.js');
	__jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/codemirror-ipython.js');
	__jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/codemirror-ipythongfm.js');
	// Bundle other common modes
	__jupyter_require__('codemirror@^5.24.2/mode/javascript/javascript.js');
	__jupyter_require__('codemirror@^5.24.2/mode/css/css.js');
	__jupyter_require__('codemirror@^5.24.2/mode/julia/julia.js');
	__jupyter_require__('codemirror@^5.24.2/mode/r/r.js');
	__jupyter_require__('codemirror@^5.24.2/mode/markdown/markdown.js');
	/**
	 * Running a CodeMirror mode outside of an editor.
	 */
	function runMode(code, mode, el) {
	    CodeMirror.runMode(code, mode, el);
	}
	exports.runMode = runMode;
	/**
	 * Find a mode name by extension.
	 */
	function findModeByExtension(ext) {
	    var mode = CodeMirror.findModeByExtension(ext);
	    return mode && mode.mode;
	}
	exports.findModeByExtension = findModeByExtension;
	/**
	 * Load a codemirror mode by file name.
	 */
	function loadModeByFileName(editor, filename) {
	    loadInfo(editor, CodeMirror.findModeByFileName(filename));
	}
	exports.loadModeByFileName = loadModeByFileName;
	/**
	 * Load a codemirror mode by mime type.
	 */
	function loadModeByMIME(editor, mimetype) {
	    loadInfo(editor, CodeMirror.findModeByMIME(mimetype));
	}
	exports.loadModeByMIME = loadModeByMIME;
	/**
	 * Load a codemirror mode by mode name.
	 */
	function loadModeByName(editor, mode) {
	    loadInfo(editor, CodeMirror.findModeByName(mode));
	}
	exports.loadModeByName = loadModeByName;
	/**
	 * Find a codemirror mode by name or CodeMirror spec.
	 */
	function findMode(mode) {
	    var modename = (typeof mode === 'string') ? mode :
	        mode.mode || mode.name;
	    var mimetype = (typeof mode !== 'string') ? mode.mime : '';
	    return (CodeMirror.findModeByName(modename) ||
	        CodeMirror.findModeByMIME(mimetype) ||
	        CodeMirror.modes['null']);
	}
	exports.findMode = findMode;
	/**
	 * Require a codemirror mode by name or Codemirror spec.
	 */
	function requireMode(mode) {
	    var info = findMode(mode);
	    // Simplest, cheapest check by mode name.
	    if (CodeMirror.modes.hasOwnProperty(info.mode)) {
	        return Promise.resolve(info);
	    }
	    // Fetch the mode asynchronously.
	    return new Promise(function (resolve, reject) {
	        __jupyter_require__.ensure('labextension/nglview-js-widgets/1.1.bundle.js', function(__jupyter_require__) { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__jupyter_require__('codemirror@^5.24.2/mode')("./" + info.mode + "/" + info.mode + ".js")]; (function () {
	            resolve(info);
	        }.apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__));});
	    });
	}
	exports.requireMode = requireMode;
	/**
	 * Load a CodeMirror mode based on a mode spec.
	 */
	function loadInfo(editor, info) {
	    if (!info) {
	        editor.setOption('mode', 'null');
	        return;
	    }
	    requireMode(info).then(function () {
	        editor.setOption('mode', info.mime);
	    });
	}
	
})
/** END DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/mode.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/meta.js **/
jupyter.define('codemirror@5.27.2/mode/meta.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  "use strict";
	
	  CodeMirror.modeInfo = [
	    {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
	    {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]},
	    {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]},
	    {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
	    {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]},
	    {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
	    {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
	    {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
	    {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
	    {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]},
	    {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
	    {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]},
	    {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
	    {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
	    {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
	    {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
	    {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
	    {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]},
	    {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
	    {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
	    {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
	    {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]},
	    {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]},
	    {name: "Django", mime: "text/x-django", mode: "django"},
	    {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/},
	    {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]},
	    {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
	    {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"},
	    {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
	    {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]},
	    {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
	    {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
	    {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
	    {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
	    {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
	    {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
	    {name: "FCL", mime: "text/x-fcl", mode: "fcl"},
	    {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
	    {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]},
	    {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
	    {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
	    {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
	    {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i},
	    {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
	    {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/},
	    {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
	    {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
	    {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]},
	    {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
	    {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
	    {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
	    {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]},
	    {name: "HTTP", mime: "message/http", mode: "http"},
	    {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]},
	    {name: "Pug", mime: "text/x-pug", mode: "pug", ext: ["jade", "pug"], alias: ["jade"]},
	    {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
	    {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]},
	    {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
	     mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
	    {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
	    {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
	    {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]},
	    {name: "Jinja2", mime: "null", mode: "jinja2"},
	    {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
	    {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
	    {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
	    {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
	    {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
	    {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
	    {name: "mIRC", mime: "text/mirc", mode: "mirc"},
	    {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
	    {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]},
	    {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
	    {name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]},
	    {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
	    {name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]},
	    {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
	    {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
	    {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
	    {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
	    {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]},
	    {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
	    {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
	    {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]},
	    {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
	    {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
	    {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
	    {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]},
	    {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
	    {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
	    {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
	    {name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]},
	    {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]},
	    {name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]},
	    {name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/},
	    {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
	    {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
	    {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r", "R"], alias: ["rscript"]},
	    {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]},
	    {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"},
	    {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]},
	    {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]},
	    {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
	    {name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]},
	    {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
	    {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
	    {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
	    {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
	    {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
	    {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
	    {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
	    {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
	    {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
	    {name: "Solr", mime: "text/x-solr", mode: "solr"},
	    {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
	    {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
	    {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
	    {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
	    {name: "SQLite", mime: "text/x-sqlite", mode: "sql"},
	    {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
	    {name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]},
	    {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
	    {name: "sTeX", mime: "text/x-stex", mode: "stex"},
	    {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]},
	    {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]},
	    {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
	    {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]},
	    {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
	    {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
	    {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
	    {name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
	    {name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
	    {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]},
	    {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
	    {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
	    {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
	    {name: "TypeScript-JSX", mime: "text/typescript-jsx", mode: "jsx", ext: ["tsx"], alias: ["tsx"]},
	    {name: "Twig", mime: "text/x-twig", mode: "twig"},
	    {name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]},
	    {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
	    {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
	    {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
	    {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
	    {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
	    {name: "Vue.js Component", mimes: ["script/x-vue", "text/x-vue"], mode: "vue", ext: ["vue"]},
	    {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd", "svg"], alias: ["rss", "wsdl", "xsd"]},
	    {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
	    {name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]},
	    {name: "YAML", mimes: ["text/x-yaml", "text/yaml"], mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
	    {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
	    {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},
	    {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]},
	    {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]}
	  ];
	  // Ensure all modes have a mime property for backwards compatibility
	  for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
	    var info = CodeMirror.modeInfo[i];
	    if (info.mimes) info.mime = info.mimes[0];
	  }
	
	  CodeMirror.findModeByMIME = function(mime) {
	    mime = mime.toLowerCase();
	    for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
	      var info = CodeMirror.modeInfo[i];
	      if (info.mime == mime) return info;
	      if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
	        if (info.mimes[j] == mime) return info;
	    }
	    if (/\+xml$/.test(mime)) return CodeMirror.findModeByMIME("application/xml")
	    if (/\+json$/.test(mime)) return CodeMirror.findModeByMIME("application/json")
	  };
	
	  CodeMirror.findModeByExtension = function(ext) {
	    for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
	      var info = CodeMirror.modeInfo[i];
	      if (info.ext) for (var j = 0; j < info.ext.length; j++)
	        if (info.ext[j] == ext) return info;
	    }
	  };
	
	  CodeMirror.findModeByFileName = function(filename) {
	    for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
	      var info = CodeMirror.modeInfo[i];
	      if (info.file && info.file.test(filename)) return info;
	    }
	    var dot = filename.lastIndexOf(".");
	    var ext = dot > -1 && filename.substring(dot + 1, filename.length);
	    if (ext) return CodeMirror.findModeByExtension(ext);
	  };
	
	  CodeMirror.findModeByName = function(name) {
	    name = name.toLowerCase();
	    for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
	      var info = CodeMirror.modeInfo[i];
	      if (info.name.toLowerCase() == name) return info;
	      if (info.alias) for (var j = 0; j < info.alias.length; j++)
	        if (info.alias[j].toLowerCase() == name) return info;
	    }
	  };
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/meta.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/runmode/runmode.js **/
jupyter.define('codemirror@5.27.2/addon/runmode/runmode.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	CodeMirror.runMode = function(string, modespec, callback, options) {
	  var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
	  var ie = /MSIE \d/.test(navigator.userAgent);
	  var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
	
	  if (callback.appendChild) {
	    var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
	    var node = callback, col = 0;
	    node.innerHTML = "";
	    callback = function(text, style) {
	      if (text == "\n") {
	        // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
	        // Emitting a carriage return makes everything ok.
	        node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
	        col = 0;
	        return;
	      }
	      var content = "";
	      // replace tabs
	      for (var pos = 0;;) {
	        var idx = text.indexOf("\t", pos);
	        if (idx == -1) {
	          content += text.slice(pos);
	          col += text.length - pos;
	          break;
	        } else {
	          col += idx - pos;
	          content += text.slice(pos, idx);
	          var size = tabSize - col % tabSize;
	          col += size;
	          for (var i = 0; i < size; ++i) content += " ";
	          pos = idx + 1;
	        }
	      }
	
	      if (style) {
	        var sp = node.appendChild(document.createElement("span"));
	        sp.className = "cm-" + style.replace(/ +/g, " cm-");
	        sp.appendChild(document.createTextNode(content));
	      } else {
	        node.appendChild(document.createTextNode(content));
	      }
	    };
	  }
	
	  var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
	  for (var i = 0, e = lines.length; i < e; ++i) {
	    if (i) callback("\n");
	    var stream = new CodeMirror.StringStream(lines[i]);
	    if (!stream.string && mode.blankLine) mode.blankLine(state);
	    while (!stream.eol()) {
	      var style = mode.token(stream, state);
	      callback(stream.current(), style, i, stream.start, state);
	      stream.start = stream.pos;
	    }
	  }
	};
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/runmode/runmode.js **/


/** START DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/codemirror-ipython.js **/
jupyter.define('@jupyterlab/codemirror@0.3.1/lib/codemirror-ipython.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var CodeMirror = __jupyter_require__('codemirror@^5.24.2/lib/codemirror.js');
	__jupyter_require__('codemirror@^5.24.2/mode/meta.js');
	__jupyter_require__('codemirror@^5.24.2/mode/python/python.js');
	/**
	 * Define an IPython codemirror mode.
	 *
	 * It is a slightly altered Python Mode with a `?` operator.
	 */
	CodeMirror.defineMode('ipython', function (config, modeOptions) {
	    var pythonConf = {};
	    for (var prop in modeOptions) {
	        if (modeOptions.hasOwnProperty(prop)) {
	            pythonConf[prop] = modeOptions[prop];
	        }
	    }
	    pythonConf.name = 'python';
	    pythonConf.singleOperators = new RegExp('^[\\+\\-\\*/%&|@\\^~<>!\\?]');
	    pythonConf.identifiers = new RegExp('^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*');
	    return CodeMirror.getMode(config, pythonConf);
	}, 'python');
	CodeMirror.defineMIME('text/x-ipython', 'ipython');
	CodeMirror.modeInfo.push({
	    ext: [],
	    mime: 'text/x-ipython',
	    mode: 'ipython',
	    name: 'ipython'
	});
	
})
/** END DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/codemirror-ipython.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/python/python.js **/
jupyter.define('codemirror@5.27.2/mode/python/python.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  "use strict";
	
	  function wordRegexp(words) {
	    return new RegExp("^((" + words.join(")|(") + "))\\b");
	  }
	
	  var wordOperators = wordRegexp(["and", "or", "not", "is"]);
	  var commonKeywords = ["as", "assert", "break", "class", "continue",
	                        "def", "del", "elif", "else", "except", "finally",
	                        "for", "from", "global", "if", "import",
	                        "lambda", "pass", "raise", "return",
	                        "try", "while", "with", "yield", "in"];
	  var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callable", "chr",
	                        "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
	                        "enumerate", "eval", "filter", "float", "format", "frozenset",
	                        "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
	                        "input", "int", "isinstance", "issubclass", "iter", "len",
	                        "list", "locals", "map", "max", "memoryview", "min", "next",
	                        "object", "oct", "open", "ord", "pow", "property", "range",
	                        "repr", "reversed", "round", "set", "setattr", "slice",
	                        "sorted", "staticmethod", "str", "sum", "super", "tuple",
	                        "type", "vars", "zip", "__import__", "NotImplemented",
	                        "Ellipsis", "__debug__"];
	  CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonBuiltins));
	
	  function top(state) {
	    return state.scopes[state.scopes.length - 1];
	  }
	
	  CodeMirror.defineMode("python", function(conf, parserConf) {
	    var ERRORCLASS = "error";
	
	    var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
	    var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/|\*\*)/;
	    var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/;
	    var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/;
	
	    var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
	
	    var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
	    if (parserConf.extra_keywords != undefined)
	      myKeywords = myKeywords.concat(parserConf.extra_keywords);
	
	    if (parserConf.extra_builtins != undefined)
	      myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
	
	    var py3 = !(parserConf.version && Number(parserConf.version) < 3)
	    if (py3) {
	      // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
	      var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
	      var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
	      myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
	      myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
	      var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i");
	    } else {
	      var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
	      var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
	      myKeywords = myKeywords.concat(["exec", "print"]);
	      myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
	                                      "file", "intern", "long", "raw_input", "reduce", "reload",
	                                      "unichr", "unicode", "xrange", "False", "True", "None"]);
	      var stringPrefixes = new RegExp("^(([rubf]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
	    }
	    var keywords = wordRegexp(myKeywords);
	    var builtins = wordRegexp(myBuiltins);
	
	    // tokenizers
	    function tokenBase(stream, state) {
	      if (stream.sol()) state.indent = stream.indentation()
	      // Handle scope changes
	      if (stream.sol() && top(state).type == "py") {
	        var scopeOffset = top(state).offset;
	        if (stream.eatSpace()) {
	          var lineOffset = stream.indentation();
	          if (lineOffset > scopeOffset)
	            pushPyScope(state);
	          else if (lineOffset < scopeOffset && dedent(stream, state) && stream.peek() != "#")
	            state.errorToken = true;
	          return null;
	        } else {
	          var style = tokenBaseInner(stream, state);
	          if (scopeOffset > 0 && dedent(stream, state))
	            style += " " + ERRORCLASS;
	          return style;
	        }
	      }
	      return tokenBaseInner(stream, state);
	    }
	
	    function tokenBaseInner(stream, state) {
	      if (stream.eatSpace()) return null;
	
	      var ch = stream.peek();
	
	      // Handle Comments
	      if (ch == "#") {
	        stream.skipToEnd();
	        return "comment";
	      }
	
	      // Handle Number Literals
	      if (stream.match(/^[0-9\.]/, false)) {
	        var floatLiteral = false;
	        // Floats
	        if (stream.match(/^[\d_]*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; }
	        if (stream.match(/^[\d_]+\.\d*/)) { floatLiteral = true; }
	        if (stream.match(/^\.\d+/)) { floatLiteral = true; }
	        if (floatLiteral) {
	          // Float literals may be "imaginary"
	          stream.eat(/J/i);
	          return "number";
	        }
	        // Integers
	        var intLiteral = false;
	        // Hex
	        if (stream.match(/^0x[0-9a-f_]+/i)) intLiteral = true;
	        // Binary
	        if (stream.match(/^0b[01_]+/i)) intLiteral = true;
	        // Octal
	        if (stream.match(/^0o[0-7_]+/i)) intLiteral = true;
	        // Decimal
	        if (stream.match(/^[1-9][\d_]*(e[\+\-]?[\d_]+)?/)) {
	          // Decimal literals may be "imaginary"
	          stream.eat(/J/i);
	          // TODO - Can you have imaginary longs?
	          intLiteral = true;
	        }
	        // Zero by itself with no other piece of number.
	        if (stream.match(/^0(?![\dx])/i)) intLiteral = true;
	        if (intLiteral) {
	          // Integer literals may be "long"
	          stream.eat(/L/i);
	          return "number";
	        }
	      }
	
	      // Handle Strings
	      if (stream.match(stringPrefixes)) {
	        state.tokenize = tokenStringFactory(stream.current());
	        return state.tokenize(stream, state);
	      }
	
	      // Handle operators and Delimiters
	      if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
	        return "punctuation";
	
	      if (stream.match(doubleOperators) || stream.match(singleOperators))
	        return "operator";
	
	      if (stream.match(singleDelimiters))
	        return "punctuation";
	
	      if (state.lastToken == "." && stream.match(identifiers))
	        return "property";
	
	      if (stream.match(keywords) || stream.match(wordOperators))
	        return "keyword";
	
	      if (stream.match(builtins))
	        return "builtin";
	
	      if (stream.match(/^(self|cls)\b/))
	        return "variable-2";
	
	      if (stream.match(identifiers)) {
	        if (state.lastToken == "def" || state.lastToken == "class")
	          return "def";
	        return "variable";
	      }
	
	      // Handle non-detected items
	      stream.next();
	      return ERRORCLASS;
	    }
	
	    function tokenStringFactory(delimiter) {
	      while ("rubf".indexOf(delimiter.charAt(0).toLowerCase()) >= 0)
	        delimiter = delimiter.substr(1);
	
	      var singleline = delimiter.length == 1;
	      var OUTCLASS = "string";
	
	      function tokenString(stream, state) {
	        while (!stream.eol()) {
	          stream.eatWhile(/[^'"\\]/);
	          if (stream.eat("\\")) {
	            stream.next();
	            if (singleline && stream.eol())
	              return OUTCLASS;
	          } else if (stream.match(delimiter)) {
	            state.tokenize = tokenBase;
	            return OUTCLASS;
	          } else {
	            stream.eat(/['"]/);
	          }
	        }
	        if (singleline) {
	          if (parserConf.singleLineStringErrors)
	            return ERRORCLASS;
	          else
	            state.tokenize = tokenBase;
	        }
	        return OUTCLASS;
	      }
	      tokenString.isString = true;
	      return tokenString;
	    }
	
	    function pushPyScope(state) {
	      while (top(state).type != "py") state.scopes.pop()
	      state.scopes.push({offset: top(state).offset + conf.indentUnit,
	                         type: "py",
	                         align: null})
	    }
	
	    function pushBracketScope(stream, state, type) {
	      var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1
	      state.scopes.push({offset: state.indent + hangingIndent,
	                         type: type,
	                         align: align})
	    }
	
	    function dedent(stream, state) {
	      var indented = stream.indentation();
	      while (state.scopes.length > 1 && top(state).offset > indented) {
	        if (top(state).type != "py") return true;
	        state.scopes.pop();
	      }
	      return top(state).offset != indented;
	    }
	
	    function tokenLexer(stream, state) {
	      if (stream.sol()) state.beginningOfLine = true;
	
	      var style = state.tokenize(stream, state);
	      var current = stream.current();
	
	      // Handle decorators
	      if (state.beginningOfLine && current == "@")
	        return stream.match(identifiers, false) ? "meta" : py3 ? "operator" : ERRORCLASS;
	
	      if (/\S/.test(current)) state.beginningOfLine = false;
	
	      if ((style == "variable" || style == "builtin")
	          && state.lastToken == "meta")
	        style = "meta";
	
	      // Handle scope changes.
	      if (current == "pass" || current == "return")
	        state.dedent += 1;
	
	      if (current == "lambda") state.lambda = true;
	      if (current == ":" && !state.lambda && top(state).type == "py")
	        pushPyScope(state);
	
	      var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
	      if (delimiter_index != -1)
	        pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
	
	      delimiter_index = "])}".indexOf(current);
	      if (delimiter_index != -1) {
	        if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
	        else return ERRORCLASS;
	      }
	      if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
	        if (state.scopes.length > 1) state.scopes.pop();
	        state.dedent -= 1;
	      }
	
	      return style;
	    }
	
	    var external = {
	      startState: function(basecolumn) {
	        return {
	          tokenize: tokenBase,
	          scopes: [{offset: basecolumn || 0, type: "py", align: null}],
	          indent: basecolumn || 0,
	          lastToken: null,
	          lambda: false,
	          dedent: 0
	        };
	      },
	
	      token: function(stream, state) {
	        var addErr = state.errorToken;
	        if (addErr) state.errorToken = false;
	        var style = tokenLexer(stream, state);
	
	        if (style && style != "comment")
	          state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
	        if (style == "punctuation") style = null;
	
	        if (stream.eol() && state.lambda)
	          state.lambda = false;
	        return addErr ? style + " " + ERRORCLASS : style;
	      },
	
	      indent: function(state, textAfter) {
	        if (state.tokenize != tokenBase)
	          return state.tokenize.isString ? CodeMirror.Pass : 0;
	
	        var scope = top(state), closing = scope.type == textAfter.charAt(0)
	        if (scope.align != null)
	          return scope.align - (closing ? 1 : 0)
	        else
	          return scope.offset - (closing ? hangingIndent : 0)
	      },
	
	      electricInput: /^\s*[\}\]\)]$/,
	      closeBrackets: {triples: "'\""},
	      lineComment: "#",
	      fold: "indent"
	    };
	    return external;
	  });
	
	  CodeMirror.defineMIME("text/x-python", "python");
	
	  var words = function(str) { return str.split(" "); };
	
	  CodeMirror.defineMIME("text/x-cython", {
	    name: "python",
	    extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+
	                          "extern gil include nogil property public "+
	                          "readonly struct union DEF IF ELIF ELSE")
	  });
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/python/python.js **/


/** START DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/codemirror-ipythongfm.js **/
jupyter.define('@jupyterlab/codemirror@0.3.1/lib/codemirror-ipythongfm.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var CodeMirror = __jupyter_require__('codemirror@^5.24.2/lib/codemirror.js');
	__jupyter_require__('codemirror@^5.24.2/mode/stex/stex.js');
	__jupyter_require__('codemirror@^5.24.2/mode/gfm/gfm.js');
	__jupyter_require__('codemirror@^5.24.2/addon/mode/multiplex.js');
	/**
	 * Define an IPython GFM (GitHub Flavored Markdown) mode.
	 *
	 * Is just a slightly altered GFM Mode with support for latex.
	 * Latex support was supported by Codemirror GFM as of
	 *   https://github.com/codemirror/CodeMirror/pull/567
	 *  But was later removed in
	 *   https://github.com/codemirror/CodeMirror/commit/d9c9f1b1ffe984aee41307f3e927f80d1f23590c
	 */
	CodeMirror.defineMode('ipythongfm', function (config, modeOptions) {
	    var gfmMode = CodeMirror.getMode(config, 'gfm');
	    var texMode = CodeMirror.getMode(config, 'stex');
	    return CodeMirror.multiplexingMode(gfmMode, {
	        open: '$', close: '$',
	        mode: texMode,
	        delimStyle: 'delimit'
	    }, {
	        // not sure this works as $$ is interpreted at (opening $, closing $, as defined just above)
	        open: '$$', close: '$$',
	        mode: texMode,
	        delimStyle: 'delimit'
	    }, {
	        open: '\\(', close: '\\)',
	        mode: texMode,
	        delimStyle: 'delimit'
	    }, {
	        open: '\\[', close: '\\]',
	        mode: texMode,
	        delimStyle: 'delimit'
	    }
	    // .. more multiplexed styles can follow here
	    );
	}, 'gfm');
	CodeMirror.defineMIME('text/x-ipythongfm', 'ipythongfm');
	CodeMirror.modeInfo.push({
	    ext: [],
	    mime: 'text/x-ipythongfm',
	    mode: 'ipythongfm',
	    name: 'ipythongfm'
	});
	
})
/** END DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/codemirror-ipythongfm.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/stex/stex.js **/
jupyter.define('codemirror@5.27.2/mode/stex/stex.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	/*
	 * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
	 * Licence: MIT
	 */
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  "use strict";
	
	  CodeMirror.defineMode("stex", function() {
	    "use strict";
	
	    function pushCommand(state, command) {
	      state.cmdState.push(command);
	    }
	
	    function peekCommand(state) {
	      if (state.cmdState.length > 0) {
	        return state.cmdState[state.cmdState.length - 1];
	      } else {
	        return null;
	      }
	    }
	
	    function popCommand(state) {
	      var plug = state.cmdState.pop();
	      if (plug) {
	        plug.closeBracket();
	      }
	    }
	
	    // returns the non-default plugin closest to the end of the list
	    function getMostPowerful(state) {
	      var context = state.cmdState;
	      for (var i = context.length - 1; i >= 0; i--) {
	        var plug = context[i];
	        if (plug.name == "DEFAULT") {
	          continue;
	        }
	        return plug;
	      }
	      return { styleIdentifier: function() { return null; } };
	    }
	
	    function addPluginPattern(pluginName, cmdStyle, styles) {
	      return function () {
	        this.name = pluginName;
	        this.bracketNo = 0;
	        this.style = cmdStyle;
	        this.styles = styles;
	        this.argument = null;   // \begin and \end have arguments that follow. These are stored in the plugin
	
	        this.styleIdentifier = function() {
	          return this.styles[this.bracketNo - 1] || null;
	        };
	        this.openBracket = function() {
	          this.bracketNo++;
	          return "bracket";
	        };
	        this.closeBracket = function() {};
	      };
	    }
	
	    var plugins = {};
	
	    plugins["importmodule"] = addPluginPattern("importmodule", "tag", ["string", "builtin"]);
	    plugins["documentclass"] = addPluginPattern("documentclass", "tag", ["", "atom"]);
	    plugins["usepackage"] = addPluginPattern("usepackage", "tag", ["atom"]);
	    plugins["begin"] = addPluginPattern("begin", "tag", ["atom"]);
	    plugins["end"] = addPluginPattern("end", "tag", ["atom"]);
	
	    plugins["DEFAULT"] = function () {
	      this.name = "DEFAULT";
	      this.style = "tag";
	
	      this.styleIdentifier = this.openBracket = this.closeBracket = function() {};
	    };
	
	    function setState(state, f) {
	      state.f = f;
	    }
	
	    // called when in a normal (no environment) context
	    function normal(source, state) {
	      var plug;
	      // Do we look like '\command' ?  If so, attempt to apply the plugin 'command'
	      if (source.match(/^\\[a-zA-Z@]+/)) {
	        var cmdName = source.current().slice(1);
	        plug = plugins[cmdName] || plugins["DEFAULT"];
	        plug = new plug();
	        pushCommand(state, plug);
	        setState(state, beginParams);
	        return plug.style;
	      }
	
	      // escape characters
	      if (source.match(/^\\[$&%#{}_]/)) {
	        return "tag";
	      }
	
	      // white space control characters
	      if (source.match(/^\\[,;!\/\\]/)) {
	        return "tag";
	      }
	
	      // find if we're starting various math modes
	      if (source.match("\\[")) {
	        setState(state, function(source, state){ return inMathMode(source, state, "\\]"); });
	        return "keyword";
	      }
	      if (source.match("$$")) {
	        setState(state, function(source, state){ return inMathMode(source, state, "$$"); });
	        return "keyword";
	      }
	      if (source.match("$")) {
	        setState(state, function(source, state){ return inMathMode(source, state, "$"); });
	        return "keyword";
	      }
	
	      var ch = source.next();
	      if (ch == "%") {
	        source.skipToEnd();
	        return "comment";
	      } else if (ch == '}' || ch == ']') {
	        plug = peekCommand(state);
	        if (plug) {
	          plug.closeBracket(ch);
	          setState(state, beginParams);
	        } else {
	          return "error";
	        }
	        return "bracket";
	      } else if (ch == '{' || ch == '[') {
	        plug = plugins["DEFAULT"];
	        plug = new plug();
	        pushCommand(state, plug);
	        return "bracket";
	      } else if (/\d/.test(ch)) {
	        source.eatWhile(/[\w.%]/);
	        return "atom";
	      } else {
	        source.eatWhile(/[\w\-_]/);
	        plug = getMostPowerful(state);
	        if (plug.name == 'begin') {
	          plug.argument = source.current();
	        }
	        return plug.styleIdentifier();
	      }
	    }
	
	    function inMathMode(source, state, endModeSeq) {
	      if (source.eatSpace()) {
	        return null;
	      }
	      if (source.match(endModeSeq)) {
	        setState(state, normal);
	        return "keyword";
	      }
	      if (source.match(/^\\[a-zA-Z@]+/)) {
	        return "tag";
	      }
	      if (source.match(/^[a-zA-Z]+/)) {
	        return "variable-2";
	      }
	      // escape characters
	      if (source.match(/^\\[$&%#{}_]/)) {
	        return "tag";
	      }
	      // white space control characters
	      if (source.match(/^\\[,;!\/]/)) {
	        return "tag";
	      }
	      // special math-mode characters
	      if (source.match(/^[\^_&]/)) {
	        return "tag";
	      }
	      // non-special characters
	      if (source.match(/^[+\-<>|=,\/@!*:;'"`~#?]/)) {
	        return null;
	      }
	      if (source.match(/^(\d+\.\d*|\d*\.\d+|\d+)/)) {
	        return "number";
	      }
	      var ch = source.next();
	      if (ch == "{" || ch == "}" || ch == "[" || ch == "]" || ch == "(" || ch == ")") {
	        return "bracket";
	      }
	
	      if (ch == "%") {
	        source.skipToEnd();
	        return "comment";
	      }
	      return "error";
	    }
	
	    function beginParams(source, state) {
	      var ch = source.peek(), lastPlug;
	      if (ch == '{' || ch == '[') {
	        lastPlug = peekCommand(state);
	        lastPlug.openBracket(ch);
	        source.eat(ch);
	        setState(state, normal);
	        return "bracket";
	      }
	      if (/[ \t\r]/.test(ch)) {
	        source.eat(ch);
	        return null;
	      }
	      setState(state, normal);
	      popCommand(state);
	
	      return normal(source, state);
	    }
	
	    return {
	      startState: function() {
	        return {
	          cmdState: [],
	          f: normal
	        };
	      },
	      copyState: function(s) {
	        return {
	          cmdState: s.cmdState.slice(),
	          f: s.f
	        };
	      },
	      token: function(stream, state) {
	        return state.f(stream, state);
	      },
	      blankLine: function(state) {
	        state.f = normal;
	        state.cmdState.length = 0;
	      },
	      lineComment: "%"
	    };
	  });
	
	  CodeMirror.defineMIME("text/x-stex", "stex");
	  CodeMirror.defineMIME("text/x-latex", "stex");
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/stex/stex.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/gfm/gfm.js **/
jupyter.define('codemirror@5.27.2/mode/gfm/gfm.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'), __jupyter_require__('codemirror@5.27.2/mode/markdown/markdown.js'), __jupyter_require__('codemirror@5.27.2/addon/mode/overlay.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i
	
	CodeMirror.defineMode("gfm", function(config, modeConfig) {
	  var codeDepth = 0;
	  function blankLine(state) {
	    state.code = false;
	    return null;
	  }
	  var gfmOverlay = {
	    startState: function() {
	      return {
	        code: false,
	        codeBlock: false,
	        ateSpace: false
	      };
	    },
	    copyState: function(s) {
	      return {
	        code: s.code,
	        codeBlock: s.codeBlock,
	        ateSpace: s.ateSpace
	      };
	    },
	    token: function(stream, state) {
	      state.combineTokens = null;
	
	      // Hack to prevent formatting override inside code blocks (block and inline)
	      if (state.codeBlock) {
	        if (stream.match(/^```+/)) {
	          state.codeBlock = false;
	          return null;
	        }
	        stream.skipToEnd();
	        return null;
	      }
	      if (stream.sol()) {
	        state.code = false;
	      }
	      if (stream.sol() && stream.match(/^```+/)) {
	        stream.skipToEnd();
	        state.codeBlock = true;
	        return null;
	      }
	      // If this block is changed, it may need to be updated in Markdown mode
	      if (stream.peek() === '`') {
	        stream.next();
	        var before = stream.pos;
	        stream.eatWhile('`');
	        var difference = 1 + stream.pos - before;
	        if (!state.code) {
	          codeDepth = difference;
	          state.code = true;
	        } else {
	          if (difference === codeDepth) { // Must be exact
	            state.code = false;
	          }
	        }
	        return null;
	      } else if (state.code) {
	        stream.next();
	        return null;
	      }
	      // Check if space. If so, links can be formatted later on
	      if (stream.eatSpace()) {
	        state.ateSpace = true;
	        return null;
	      }
	      if (stream.sol() || state.ateSpace) {
	        state.ateSpace = false;
	        if (modeConfig.gitHubSpice !== false) {
	          if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
	            // User/Project@SHA
	            // User@SHA
	            // SHA
	            state.combineTokens = true;
	            return "link";
	          } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
	            // User/Project#Num
	            // User#Num
	            // #Num
	            state.combineTokens = true;
	            return "link";
	          }
	        }
	      }
	      if (stream.match(urlRE) &&
	          stream.string.slice(stream.start - 2, stream.start) != "](" &&
	          (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) {
	        // URLs
	        // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
	        // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
	        // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL
	        state.combineTokens = true;
	        return "link";
	      }
	      stream.next();
	      return null;
	    },
	    blankLine: blankLine
	  };
	
	  var markdownConfig = {
	    taskLists: true,
	    fencedCodeBlocks: '```',
	    strikethrough: true
	  };
	  for (var attr in modeConfig) {
	    markdownConfig[attr] = modeConfig[attr];
	  }
	  markdownConfig.name = "markdown";
	  return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay);
	
	}, "markdown");
	
	  CodeMirror.defineMIME("text/x-gfm", "gfm");
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/gfm/gfm.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/markdown/markdown.js **/
jupyter.define('codemirror@5.27.2/mode/markdown/markdown.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'), __jupyter_require__('codemirror@5.27.2/mode/xml/xml.js'), __jupyter_require__('codemirror@5.27.2/mode/meta.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
	
	  var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
	  var htmlModeMissing = htmlMode.name == "null"
	
	  function getMode(name) {
	    if (CodeMirror.findModeByName) {
	      var found = CodeMirror.findModeByName(name);
	      if (found) name = found.mime || found.mimes[0];
	    }
	    var mode = CodeMirror.getMode(cmCfg, name);
	    return mode.name == "null" ? null : mode;
	  }
	
	  // Should characters that affect highlighting be highlighted separate?
	  // Does not include characters that will be output (such as `1.` and `-` for lists)
	  if (modeCfg.highlightFormatting === undefined)
	    modeCfg.highlightFormatting = false;
	
	  // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
	  // Excess `>` will emit `error` token.
	  if (modeCfg.maxBlockquoteDepth === undefined)
	    modeCfg.maxBlockquoteDepth = 0;
	
	  // Use `fencedCodeBlocks` to configure fenced code blocks. false to
	  // disable, string to specify a precise regexp that the fence should
	  // match, and true to allow three or more backticks or tildes (as
	  // per CommonMark).
	
	  // Turn on task lists? ("- [ ] " and "- [x] ")
	  if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
	
	  // Turn on strikethrough syntax
	  if (modeCfg.strikethrough === undefined)
	    modeCfg.strikethrough = false;
	
	  // Allow token types to be overridden by user-provided token types.
	  if (modeCfg.tokenTypeOverrides === undefined)
	    modeCfg.tokenTypeOverrides = {};
	
	  var tokenTypes = {
	    header: "header",
	    code: "comment",
	    quote: "quote",
	    list1: "variable-2",
	    list2: "variable-3",
	    list3: "keyword",
	    hr: "hr",
	    image: "image",
	    imageAltText: "image-alt-text",
	    imageMarker: "image-marker",
	    formatting: "formatting",
	    linkInline: "link",
	    linkEmail: "link",
	    linkText: "link",
	    linkHref: "string",
	    em: "em",
	    strong: "strong",
	    strikethrough: "strikethrough"
	  };
	
	  for (var tokenType in tokenTypes) {
	    if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
	      tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
	    }
	  }
	
	  var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
	  ,   listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
	  ,   taskListRE = /^\[(x| )\](?=\s)/ // Must follow listRE
	  ,   atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
	  ,   setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
	  ,   textRE = /^[^#!\[\]*_\\<>` "'(~]+/
	  ,   fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
	                                ")[ \\t]*([\\w+#\-]*)")
	  ,   punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~—]/
	
	  function switchInline(stream, state, f) {
	    state.f = state.inline = f;
	    return f(stream, state);
	  }
	
	  function switchBlock(stream, state, f) {
	    state.f = state.block = f;
	    return f(stream, state);
	  }
	
	  function lineIsEmpty(line) {
	    return !line || !/\S/.test(line.string)
	  }
	
	  // Blocks
	
	  function blankLine(state) {
	    // Reset linkTitle state
	    state.linkTitle = false;
	    // Reset EM state
	    state.em = false;
	    // Reset STRONG state
	    state.strong = false;
	    // Reset strikethrough state
	    state.strikethrough = false;
	    // Reset state.quote
	    state.quote = 0;
	    // Reset state.indentedCode
	    state.indentedCode = false;
	    if (state.f == htmlBlock) {
	      state.f = inlineNormal;
	      state.block = blockNormal;
	    }
	    // Reset state.trailingSpace
	    state.trailingSpace = 0;
	    state.trailingSpaceNewLine = false;
	    // Mark this line as blank
	    state.prevLine = state.thisLine
	    state.thisLine = null
	    return null;
	  }
	
	  function blockNormal(stream, state) {
	    var sol = stream.sol();
	
	    var prevLineIsList = state.list !== false,
	        prevLineIsIndentedCode = state.indentedCode;
	
	    state.indentedCode = false;
	
	    if (prevLineIsList) {
	      if (state.indentationDiff >= 0) { // Continued list
	        if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
	          state.indentation -= state.indentationDiff;
	        }
	        state.list = null;
	      } else if (state.indentation > 0) {
	        state.list = null;
	      } else { // No longer a list
	        state.list = false;
	      }
	    }
	
	    var match = null;
	    if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || lineIsEmpty(state.prevLine))) {
	      stream.skipToEnd();
	      state.indentation -= 4;
	      state.indentedCode = true;
	      return tokenTypes.code;
	    } else if (stream.eatSpace()) {
	      return null;
	    } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
	      state.header = match[1].length;
	      if (modeCfg.highlightFormatting) state.formatting = "header";
	      state.f = state.inline;
	      return getType(state);
	    } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
	               !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
	      state.header = match[0].charAt(0) == '=' ? 1 : 2;
	      if (modeCfg.highlightFormatting) state.formatting = "header";
	      state.f = state.inline;
	      return getType(state);
	    } else if (stream.eat('>')) {
	      state.quote = sol ? 1 : state.quote + 1;
	      if (modeCfg.highlightFormatting) state.formatting = "quote";
	      stream.eatSpace();
	      return getType(state);
	    } else if (stream.peek() === '[') {
	      return switchInline(stream, state, footnoteLink);
	    } else if (stream.match(hrRE, true)) {
	      state.hr = true;
	      return tokenTypes.hr;
	    } else if (match = stream.match(listRE)) {
	      var listType = match[1] ? "ol" : "ul";
	      state.indentation = stream.column() + stream.current().length;
	      state.list = true;
	
	      // While this list item's marker's indentation
	      // is less than the deepest list item's content's indentation,
	      // pop the deepest list item indentation off the stack.
	      while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
	        state.listStack.pop();
	      }
	
	      // Add this list item's content's indentation to the stack
	      state.listStack.push(state.indentation);
	
	      if (modeCfg.taskLists && stream.match(taskListRE, false)) {
	        state.taskList = true;
	      }
	      state.f = state.inline;
	      if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
	      return getType(state);
	    } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
	      state.fencedChars = match[1]
	      // try switching mode
	      state.localMode = getMode(match[2]);
	      if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
	      state.f = state.block = local;
	      if (modeCfg.highlightFormatting) state.formatting = "code-block";
	      state.code = -1
	      return getType(state);
	    }
	
	    return switchInline(stream, state, state.inline);
	  }
	
	  function htmlBlock(stream, state) {
	    var style = htmlMode.token(stream, state.htmlState);
	    if (!htmlModeMissing) {
	      var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
	      if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
	           (!inner.state.context && inner.state.tokenize.isInText)) ||
	          (state.md_inside && stream.current().indexOf(">") > -1)) {
	        state.f = inlineNormal;
	        state.block = blockNormal;
	        state.htmlState = null;
	      }
	    }
	    return style;
	  }
	
	  function local(stream, state) {
	    if (state.fencedChars && stream.match(state.fencedChars)) {
	      if (modeCfg.highlightFormatting) state.formatting = "code-block";
	      var returnType = getType(state)
	      state.localMode = state.localState = null;
	      state.block = blockNormal;
	      state.f = inlineNormal;
	      state.fencedChars = null;
	      state.code = 0
	      return returnType;
	    } else if (state.fencedChars && stream.skipTo(state.fencedChars)) {
	      return "comment"
	    } else if (state.localMode) {
	      return state.localMode.token(stream, state.localState);
	    } else {
	      stream.skipToEnd();
	      return tokenTypes.code;
	    }
	  }
	
	  // Inline
	  function getType(state) {
	    var styles = [];
	
	    if (state.formatting) {
	      styles.push(tokenTypes.formatting);
	
	      if (typeof state.formatting === "string") state.formatting = [state.formatting];
	
	      for (var i = 0; i < state.formatting.length; i++) {
	        styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
	
	        if (state.formatting[i] === "header") {
	          styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
	        }
	
	        // Add `formatting-quote` and `formatting-quote-#` for blockquotes
	        // Add `error` instead if the maximum blockquote nesting depth is passed
	        if (state.formatting[i] === "quote") {
	          if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
	            styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
	          } else {
	            styles.push("error");
	          }
	        }
	      }
	    }
	
	    if (state.taskOpen) {
	      styles.push("meta");
	      return styles.length ? styles.join(' ') : null;
	    }
	    if (state.taskClosed) {
	      styles.push("property");
	      return styles.length ? styles.join(' ') : null;
	    }
	
	    if (state.linkHref) {
	      styles.push(tokenTypes.linkHref, "url");
	    } else { // Only apply inline styles to non-url text
	      if (state.strong) { styles.push(tokenTypes.strong); }
	      if (state.em) { styles.push(tokenTypes.em); }
	      if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
	      if (state.linkText) { styles.push(tokenTypes.linkText); }
	      if (state.code) { styles.push(tokenTypes.code); }
	      if (state.image) { styles.push(tokenTypes.image); }
	      if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
	      if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
	    }
	
	    if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
	
	    if (state.quote) {
	      styles.push(tokenTypes.quote);
	
	      // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
	      if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
	        styles.push(tokenTypes.quote + "-" + state.quote);
	      } else {
	        styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
	      }
	    }
	
	    if (state.list !== false) {
	      var listMod = (state.listStack.length - 1) % 3;
	      if (!listMod) {
	        styles.push(tokenTypes.list1);
	      } else if (listMod === 1) {
	        styles.push(tokenTypes.list2);
	      } else {
	        styles.push(tokenTypes.list3);
	      }
	    }
	
	    if (state.trailingSpaceNewLine) {
	      styles.push("trailing-space-new-line");
	    } else if (state.trailingSpace) {
	      styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
	    }
	
	    return styles.length ? styles.join(' ') : null;
	  }
	
	  function handleText(stream, state) {
	    if (stream.match(textRE, true)) {
	      return getType(state);
	    }
	    return undefined;
	  }
	
	  function inlineNormal(stream, state) {
	    var style = state.text(stream, state);
	    if (typeof style !== 'undefined')
	      return style;
	
	    if (state.list) { // List marker (*, +, -, 1., etc)
	      state.list = null;
	      return getType(state);
	    }
	
	    if (state.taskList) {
	      var taskOpen = stream.match(taskListRE, true)[1] !== "x";
	      if (taskOpen) state.taskOpen = true;
	      else state.taskClosed = true;
	      if (modeCfg.highlightFormatting) state.formatting = "task";
	      state.taskList = false;
	      return getType(state);
	    }
	
	    state.taskOpen = false;
	    state.taskClosed = false;
	
	    if (state.header && stream.match(/^#+$/, true)) {
	      if (modeCfg.highlightFormatting) state.formatting = "header";
	      return getType(state);
	    }
	
	    var ch = stream.next();
	
	    // Matches link titles present on next line
	    if (state.linkTitle) {
	      state.linkTitle = false;
	      var matchCh = ch;
	      if (ch === '(') {
	        matchCh = ')';
	      }
	      matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1");
	      var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
	      if (stream.match(new RegExp(regex), true)) {
	        return tokenTypes.linkHref;
	      }
	    }
	
	    // If this block is changed, it may need to be updated in GFM mode
	    if (ch === '`') {
	      var previousFormatting = state.formatting;
	      if (modeCfg.highlightFormatting) state.formatting = "code";
	      stream.eatWhile('`');
	      var count = stream.current().length
	      if (state.code == 0) {
	        state.code = count
	        return getType(state)
	      } else if (count == state.code) { // Must be exact
	        var t = getType(state)
	        state.code = 0
	        return t
	      } else {
	        state.formatting = previousFormatting
	        return getType(state)
	      }
	    } else if (state.code) {
	      return getType(state);
	    }
	
	    if (ch === '\\') {
	      stream.next();
	      if (modeCfg.highlightFormatting) {
	        var type = getType(state);
	        var formattingEscape = tokenTypes.formatting + "-escape";
	        return type ? type + " " + formattingEscape : formattingEscape;
	      }
	    }
	
	    if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
	      state.imageMarker = true;
	      state.image = true;
	      if (modeCfg.highlightFormatting) state.formatting = "image";
	      return getType(state);
	    }
	
	    if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
	      state.imageMarker = false;
	      state.imageAltText = true
	      if (modeCfg.highlightFormatting) state.formatting = "image";
	      return getType(state);
	    }
	
	    if (ch === ']' && state.imageAltText) {
	      if (modeCfg.highlightFormatting) state.formatting = "image";
	      var type = getType(state);
	      state.imageAltText = false;
	      state.image = false;
	      state.inline = state.f = linkHref;
	      return type;
	    }
	
	    if (ch === '[' && !state.image) {
	      state.linkText = true;
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      return getType(state);
	    }
	
	    if (ch === ']' && state.linkText) {
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      var type = getType(state);
	      state.linkText = false;
	      state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal
	      return type;
	    }
	
	    if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
	      state.f = state.inline = linkInline;
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      var type = getType(state);
	      if (type){
	        type += " ";
	      } else {
	        type = "";
	      }
	      return type + tokenTypes.linkInline;
	    }
	
	    if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
	      state.f = state.inline = linkInline;
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      var type = getType(state);
	      if (type){
	        type += " ";
	      } else {
	        type = "";
	      }
	      return type + tokenTypes.linkEmail;
	    }
	
	    if (ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
	      var end = stream.string.indexOf(">", stream.pos);
	      if (end != -1) {
	        var atts = stream.string.substring(stream.start, end);
	        if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
	      }
	      stream.backUp(1);
	      state.htmlState = CodeMirror.startState(htmlMode);
	      return switchBlock(stream, state, htmlBlock);
	    }
	
	    if (ch === '<' && stream.match(/^\/\w*?>/)) {
	      state.md_inside = false;
	      return "tag";
	    } else if (ch === "*" || ch === "_") {
	      var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2)
	      while (len < 3 && stream.eat(ch)) len++
	      var after = stream.peek() || " "
	      // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
	      var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before))
	      var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after))
	      var setEm = null, setStrong = null
	      if (len % 2) { // Em
	        if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
	          setEm = true
	        else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
	          setEm = false
	      }
	      if (len > 1) { // Strong
	        if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
	          setStrong = true
	        else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
	          setStrong = false
	      }
	      if (setStrong != null || setEm != null) {
	        if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
	        if (setEm === true) state.em = ch
	        if (setStrong === true) state.strong = ch
	        var t = getType(state)
	        if (setEm === false) state.em = false
	        if (setStrong === false) state.strong = false
	        return t
	      }
	    } else if (ch === ' ') {
	      if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
	        if (stream.peek() === ' ') { // Surrounded by spaces, ignore
	          return getType(state);
	        } else { // Not surrounded by spaces, back up pointer
	          stream.backUp(1);
	        }
	      }
	    }
	
	    if (modeCfg.strikethrough) {
	      if (ch === '~' && stream.eatWhile(ch)) {
	        if (state.strikethrough) {// Remove strikethrough
	          if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
	          var t = getType(state);
	          state.strikethrough = false;
	          return t;
	        } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
	          state.strikethrough = true;
	          if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
	          return getType(state);
	        }
	      } else if (ch === ' ') {
	        if (stream.match(/^~~/, true)) { // Probably surrounded by space
	          if (stream.peek() === ' ') { // Surrounded by spaces, ignore
	            return getType(state);
	          } else { // Not surrounded by spaces, back up pointer
	            stream.backUp(2);
	          }
	        }
	      }
	    }
	
	    if (ch === ' ') {
	      if (stream.match(/ +$/, false)) {
	        state.trailingSpace++;
	      } else if (state.trailingSpace) {
	        state.trailingSpaceNewLine = true;
	      }
	    }
	
	    return getType(state);
	  }
	
	  function linkInline(stream, state) {
	    var ch = stream.next();
	
	    if (ch === ">") {
	      state.f = state.inline = inlineNormal;
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      var type = getType(state);
	      if (type){
	        type += " ";
	      } else {
	        type = "";
	      }
	      return type + tokenTypes.linkInline;
	    }
	
	    stream.match(/^[^>]+/, true);
	
	    return tokenTypes.linkInline;
	  }
	
	  function linkHref(stream, state) {
	    // Check if space, and return NULL if so (to avoid marking the space)
	    if(stream.eatSpace()){
	      return null;
	    }
	    var ch = stream.next();
	    if (ch === '(' || ch === '[') {
	      state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
	      if (modeCfg.highlightFormatting) state.formatting = "link-string";
	      state.linkHref = true;
	      return getType(state);
	    }
	    return 'error';
	  }
	
	  var linkRE = {
	    ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
	    "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/
	  }
	
	  function getLinkHrefInside(endChar) {
	    return function(stream, state) {
	      var ch = stream.next();
	
	      if (ch === endChar) {
	        state.f = state.inline = inlineNormal;
	        if (modeCfg.highlightFormatting) state.formatting = "link-string";
	        var returnState = getType(state);
	        state.linkHref = false;
	        return returnState;
	      }
	
	      stream.match(linkRE[endChar])
	      state.linkHref = true;
	      return getType(state);
	    };
	  }
	
	  function footnoteLink(stream, state) {
	    if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
	      state.f = footnoteLinkInside;
	      stream.next(); // Consume [
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      state.linkText = true;
	      return getType(state);
	    }
	    return switchInline(stream, state, inlineNormal);
	  }
	
	  function footnoteLinkInside(stream, state) {
	    if (stream.match(/^\]:/, true)) {
	      state.f = state.inline = footnoteUrl;
	      if (modeCfg.highlightFormatting) state.formatting = "link";
	      var returnType = getType(state);
	      state.linkText = false;
	      return returnType;
	    }
	
	    stream.match(/^([^\]\\]|\\.)+/, true);
	
	    return tokenTypes.linkText;
	  }
	
	  function footnoteUrl(stream, state) {
	    // Check if space, and return NULL if so (to avoid marking the space)
	    if(stream.eatSpace()){
	      return null;
	    }
	    // Match URL
	    stream.match(/^[^\s]+/, true);
	    // Check for link title
	    if (stream.peek() === undefined) { // End of line, set flag to check next line
	      state.linkTitle = true;
	    } else { // More content on line, check if link title
	      stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
	    }
	    state.f = state.inline = inlineNormal;
	    return tokenTypes.linkHref + " url";
	  }
	
	  var mode = {
	    startState: function() {
	      return {
	        f: blockNormal,
	
	        prevLine: null,
	        thisLine: null,
	
	        block: blockNormal,
	        htmlState: null,
	        indentation: 0,
	
	        inline: inlineNormal,
	        text: handleText,
	
	        formatting: false,
	        linkText: false,
	        linkHref: false,
	        linkTitle: false,
	        code: 0,
	        em: false,
	        strong: false,
	        header: 0,
	        hr: false,
	        taskList: false,
	        list: false,
	        listStack: [],
	        quote: 0,
	        trailingSpace: 0,
	        trailingSpaceNewLine: false,
	        strikethrough: false,
	        fencedChars: null
	      };
	    },
	
	    copyState: function(s) {
	      return {
	        f: s.f,
	
	        prevLine: s.prevLine,
	        thisLine: s.thisLine,
	
	        block: s.block,
	        htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
	        indentation: s.indentation,
	
	        localMode: s.localMode,
	        localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
	
	        inline: s.inline,
	        text: s.text,
	        formatting: false,
	        linkText: s.linkText,
	        linkTitle: s.linkTitle,
	        code: s.code,
	        em: s.em,
	        strong: s.strong,
	        strikethrough: s.strikethrough,
	        header: s.header,
	        hr: s.hr,
	        taskList: s.taskList,
	        list: s.list,
	        listStack: s.listStack.slice(0),
	        quote: s.quote,
	        indentedCode: s.indentedCode,
	        trailingSpace: s.trailingSpace,
	        trailingSpaceNewLine: s.trailingSpaceNewLine,
	        md_inside: s.md_inside,
	        fencedChars: s.fencedChars
	      };
	    },
	
	    token: function(stream, state) {
	
	      // Reset state.formatting
	      state.formatting = false;
	
	      if (stream != state.thisLine) {
	        var forceBlankLine = state.header || state.hr;
	
	        // Reset state.header and state.hr
	        state.header = 0;
	        state.hr = false;
	
	        if (stream.match(/^\s*$/, true) || forceBlankLine) {
	          blankLine(state);
	          if (!forceBlankLine) return null
	          state.prevLine = null
	        }
	
	        state.prevLine = state.thisLine
	        state.thisLine = stream
	
	        // Reset state.taskList
	        state.taskList = false;
	
	        // Reset state.trailingSpace
	        state.trailingSpace = 0;
	        state.trailingSpaceNewLine = false;
	
	        state.f = state.block;
	        var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, '    ').length;
	        state.indentationDiff = Math.min(indentation - state.indentation, 4);
	        state.indentation = state.indentation + state.indentationDiff;
	        if (indentation > 0) return null;
	      }
	      return state.f(stream, state);
	    },
	
	    innerMode: function(state) {
	      if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
	      if (state.localState) return {state: state.localState, mode: state.localMode};
	      return {state: state, mode: mode};
	    },
	
	    blankLine: blankLine,
	
	    getType: getType,
	
	    closeBrackets: "()[]{}''\"\"``",
	    fold: "markdown"
	  };
	  return mode;
	}, "xml");
	
	CodeMirror.defineMIME("text/x-markdown", "markdown");
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/markdown/markdown.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/xml/xml.js **/
jupyter.define('codemirror@5.27.2/mode/xml/xml.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	var htmlConfig = {
	  autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
	                    'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
	                    'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
	                    'track': true, 'wbr': true, 'menuitem': true},
	  implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
	                     'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
	                     'th': true, 'tr': true},
	  contextGrabbers: {
	    'dd': {'dd': true, 'dt': true},
	    'dt': {'dd': true, 'dt': true},
	    'li': {'li': true},
	    'option': {'option': true, 'optgroup': true},
	    'optgroup': {'optgroup': true},
	    'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
	          'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
	          'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
	          'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
	          'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
	    'rp': {'rp': true, 'rt': true},
	    'rt': {'rp': true, 'rt': true},
	    'tbody': {'tbody': true, 'tfoot': true},
	    'td': {'td': true, 'th': true},
	    'tfoot': {'tbody': true},
	    'th': {'td': true, 'th': true},
	    'thead': {'tbody': true, 'tfoot': true},
	    'tr': {'tr': true}
	  },
	  doNotIndent: {"pre": true},
	  allowUnquoted: true,
	  allowMissing: true,
	  caseFold: true
	}
	
	var xmlConfig = {
	  autoSelfClosers: {},
	  implicitlyClosed: {},
	  contextGrabbers: {},
	  doNotIndent: {},
	  allowUnquoted: false,
	  allowMissing: false,
	  caseFold: false
	}
	
	CodeMirror.defineMode("xml", function(editorConf, config_) {
	  var indentUnit = editorConf.indentUnit
	  var config = {}
	  var defaults = config_.htmlMode ? htmlConfig : xmlConfig
	  for (var prop in defaults) config[prop] = defaults[prop]
	  for (var prop in config_) config[prop] = config_[prop]
	
	  // Return variables for tokenizers
	  var type, setStyle;
	
	  function inText(stream, state) {
	    function chain(parser) {
	      state.tokenize = parser;
	      return parser(stream, state);
	    }
	
	    var ch = stream.next();
	    if (ch == "<") {
	      if (stream.eat("!")) {
	        if (stream.eat("[")) {
	          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
	          else return null;
	        } else if (stream.match("--")) {
	          return chain(inBlock("comment", "-->"));
	        } else if (stream.match("DOCTYPE", true, true)) {
	          stream.eatWhile(/[\w\._\-]/);
	          return chain(doctype(1));
	        } else {
	          return null;
	        }
	      } else if (stream.eat("?")) {
	        stream.eatWhile(/[\w\._\-]/);
	        state.tokenize = inBlock("meta", "?>");
	        return "meta";
	      } else {
	        type = stream.eat("/") ? "closeTag" : "openTag";
	        state.tokenize = inTag;
	        return "tag bracket";
	      }
	    } else if (ch == "&") {
	      var ok;
	      if (stream.eat("#")) {
	        if (stream.eat("x")) {
	          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
	        } else {
	          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
	        }
	      } else {
	        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
	      }
	      return ok ? "atom" : "error";
	    } else {
	      stream.eatWhile(/[^&<]/);
	      return null;
	    }
	  }
	  inText.isInText = true;
	
	  function inTag(stream, state) {
	    var ch = stream.next();
	    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
	      state.tokenize = inText;
	      type = ch == ">" ? "endTag" : "selfcloseTag";
	      return "tag bracket";
	    } else if (ch == "=") {
	      type = "equals";
	      return null;
	    } else if (ch == "<") {
	      state.tokenize = inText;
	      state.state = baseState;
	      state.tagName = state.tagStart = null;
	      var next = state.tokenize(stream, state);
	      return next ? next + " tag error" : "tag error";
	    } else if (/[\'\"]/.test(ch)) {
	      state.tokenize = inAttribute(ch);
	      state.stringStartCol = stream.column();
	      return state.tokenize(stream, state);
	    } else {
	      stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
	      return "word";
	    }
	  }
	
	  function inAttribute(quote) {
	    var closure = function(stream, state) {
	      while (!stream.eol()) {
	        if (stream.next() == quote) {
	          state.tokenize = inTag;
	          break;
	        }
	      }
	      return "string";
	    };
	    closure.isInAttribute = true;
	    return closure;
	  }
	
	  function inBlock(style, terminator) {
	    return function(stream, state) {
	      while (!stream.eol()) {
	        if (stream.match(terminator)) {
	          state.tokenize = inText;
	          break;
	        }
	        stream.next();
	      }
	      return style;
	    };
	  }
	  function doctype(depth) {
	    return function(stream, state) {
	      var ch;
	      while ((ch = stream.next()) != null) {
	        if (ch == "<") {
	          state.tokenize = doctype(depth + 1);
	          return state.tokenize(stream, state);
	        } else if (ch == ">") {
	          if (depth == 1) {
	            state.tokenize = inText;
	            break;
	          } else {
	            state.tokenize = doctype(depth - 1);
	            return state.tokenize(stream, state);
	          }
	        }
	      }
	      return "meta";
	    };
	  }
	
	  function Context(state, tagName, startOfLine) {
	    this.prev = state.context;
	    this.tagName = tagName;
	    this.indent = state.indented;
	    this.startOfLine = startOfLine;
	    if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
	      this.noIndent = true;
	  }
	  function popContext(state) {
	    if (state.context) state.context = state.context.prev;
	  }
	  function maybePopContext(state, nextTagName) {
	    var parentTagName;
	    while (true) {
	      if (!state.context) {
	        return;
	      }
	      parentTagName = state.context.tagName;
	      if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
	          !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
	        return;
	      }
	      popContext(state);
	    }
	  }
	
	  function baseState(type, stream, state) {
	    if (type == "openTag") {
	      state.tagStart = stream.column();
	      return tagNameState;
	    } else if (type == "closeTag") {
	      return closeTagNameState;
	    } else {
	      return baseState;
	    }
	  }
	  function tagNameState(type, stream, state) {
	    if (type == "word") {
	      state.tagName = stream.current();
	      setStyle = "tag";
	      return attrState;
	    } else {
	      setStyle = "error";
	      return tagNameState;
	    }
	  }
	  function closeTagNameState(type, stream, state) {
	    if (type == "word") {
	      var tagName = stream.current();
	      if (state.context && state.context.tagName != tagName &&
	          config.implicitlyClosed.hasOwnProperty(state.context.tagName))
	        popContext(state);
	      if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
	        setStyle = "tag";
	        return closeState;
	      } else {
	        setStyle = "tag error";
	        return closeStateErr;
	      }
	    } else {
	      setStyle = "error";
	      return closeStateErr;
	    }
	  }
	
	  function closeState(type, _stream, state) {
	    if (type != "endTag") {
	      setStyle = "error";
	      return closeState;
	    }
	    popContext(state);
	    return baseState;
	  }
	  function closeStateErr(type, stream, state) {
	    setStyle = "error";
	    return closeState(type, stream, state);
	  }
	
	  function attrState(type, _stream, state) {
	    if (type == "word") {
	      setStyle = "attribute";
	      return attrEqState;
	    } else if (type == "endTag" || type == "selfcloseTag") {
	      var tagName = state.tagName, tagStart = state.tagStart;
	      state.tagName = state.tagStart = null;
	      if (type == "selfcloseTag" ||
	          config.autoSelfClosers.hasOwnProperty(tagName)) {
	        maybePopContext(state, tagName);
	      } else {
	        maybePopContext(state, tagName);
	        state.context = new Context(state, tagName, tagStart == state.indented);
	      }
	      return baseState;
	    }
	    setStyle = "error";
	    return attrState;
	  }
	  function attrEqState(type, stream, state) {
	    if (type == "equals") return attrValueState;
	    if (!config.allowMissing) setStyle = "error";
	    return attrState(type, stream, state);
	  }
	  function attrValueState(type, stream, state) {
	    if (type == "string") return attrContinuedState;
	    if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
	    setStyle = "error";
	    return attrState(type, stream, state);
	  }
	  function attrContinuedState(type, stream, state) {
	    if (type == "string") return attrContinuedState;
	    return attrState(type, stream, state);
	  }
	
	  return {
	    startState: function(baseIndent) {
	      var state = {tokenize: inText,
	                   state: baseState,
	                   indented: baseIndent || 0,
	                   tagName: null, tagStart: null,
	                   context: null}
	      if (baseIndent != null) state.baseIndent = baseIndent
	      return state
	    },
	
	    token: function(stream, state) {
	      if (!state.tagName && stream.sol())
	        state.indented = stream.indentation();
	
	      if (stream.eatSpace()) return null;
	      type = null;
	      var style = state.tokenize(stream, state);
	      if ((style || type) && style != "comment") {
	        setStyle = null;
	        state.state = state.state(type || style, stream, state);
	        if (setStyle)
	          style = setStyle == "error" ? style + " error" : setStyle;
	      }
	      return style;
	    },
	
	    indent: function(state, textAfter, fullLine) {
	      var context = state.context;
	      // Indent multi-line strings (e.g. css).
	      if (state.tokenize.isInAttribute) {
	        if (state.tagStart == state.indented)
	          return state.stringStartCol + 1;
	        else
	          return state.indented + indentUnit;
	      }
	      if (context && context.noIndent) return CodeMirror.Pass;
	      if (state.tokenize != inTag && state.tokenize != inText)
	        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
	      // Indent the starts of attribute names.
	      if (state.tagName) {
	        if (config.multilineTagIndentPastTag !== false)
	          return state.tagStart + state.tagName.length + 2;
	        else
	          return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
	      }
	      if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
	      var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
	      if (tagAfter && tagAfter[1]) { // Closing tag spotted
	        while (context) {
	          if (context.tagName == tagAfter[2]) {
	            context = context.prev;
	            break;
	          } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
	            context = context.prev;
	          } else {
	            break;
	          }
	        }
	      } else if (tagAfter) { // Opening tag spotted
	        while (context) {
	          var grabbers = config.contextGrabbers[context.tagName];
	          if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
	            context = context.prev;
	          else
	            break;
	        }
	      }
	      while (context && context.prev && !context.startOfLine)
	        context = context.prev;
	      if (context) return context.indent + indentUnit;
	      else return state.baseIndent || 0;
	    },
	
	    electricInput: /<\/[\s\w:]+>$/,
	    blockCommentStart: "<!--",
	    blockCommentEnd: "-->",
	
	    configuration: config.htmlMode ? "html" : "xml",
	    helperType: config.htmlMode ? "html" : "xml",
	
	    skipAttribute: function(state) {
	      if (state.state == attrValueState)
	        state.state = attrState
	    }
	  };
	});
	
	CodeMirror.defineMIME("text/xml", "xml");
	CodeMirror.defineMIME("application/xml", "xml");
	if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
	  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/xml/xml.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/mode/overlay.js **/
jupyter.define('codemirror@5.27.2/addon/mode/overlay.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	// Utility function that allows modes to be combined. The mode given
	// as the base argument takes care of most of the normal mode
	// functionality, but a second (typically simple) mode is used, which
	// can override the style of text. Both modes get to parse all of the
	// text, but when both assign a non-null style to a piece of code, the
	// overlay wins, unless the combine argument was true and not overridden,
	// or state.overlay.combineTokens was true, in which case the styles are
	// combined.
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	CodeMirror.overlayMode = function(base, overlay, combine) {
	  return {
	    startState: function() {
	      return {
	        base: CodeMirror.startState(base),
	        overlay: CodeMirror.startState(overlay),
	        basePos: 0, baseCur: null,
	        overlayPos: 0, overlayCur: null,
	        streamSeen: null
	      };
	    },
	    copyState: function(state) {
	      return {
	        base: CodeMirror.copyState(base, state.base),
	        overlay: CodeMirror.copyState(overlay, state.overlay),
	        basePos: state.basePos, baseCur: null,
	        overlayPos: state.overlayPos, overlayCur: null
	      };
	    },
	
	    token: function(stream, state) {
	      if (stream != state.streamSeen ||
	          Math.min(state.basePos, state.overlayPos) < stream.start) {
	        state.streamSeen = stream;
	        state.basePos = state.overlayPos = stream.start;
	      }
	
	      if (stream.start == state.basePos) {
	        state.baseCur = base.token(stream, state.base);
	        state.basePos = stream.pos;
	      }
	      if (stream.start == state.overlayPos) {
	        stream.pos = stream.start;
	        state.overlayCur = overlay.token(stream, state.overlay);
	        state.overlayPos = stream.pos;
	      }
	      stream.pos = Math.min(state.basePos, state.overlayPos);
	
	      // state.overlay.combineTokens always takes precedence over combine,
	      // unless set to null
	      if (state.overlayCur == null) return state.baseCur;
	      else if (state.baseCur != null &&
	               state.overlay.combineTokens ||
	               combine && state.overlay.combineTokens == null)
	        return state.baseCur + " " + state.overlayCur;
	      else return state.overlayCur;
	    },
	
	    indent: base.indent && function(state, textAfter) {
	      return base.indent(state.base, textAfter);
	    },
	    electricChars: base.electricChars,
	
	    innerMode: function(state) { return {state: state.base, mode: base}; },
	
	    blankLine: function(state) {
	      var baseToken, overlayToken;
	      if (base.blankLine) baseToken = base.blankLine(state.base);
	      if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay);
	
	      return overlayToken == null ?
	        baseToken :
	        (combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken);
	    }
	  };
	};
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/mode/overlay.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/mode/multiplex.js **/
jupyter.define('codemirror@5.27.2/addon/mode/multiplex.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	CodeMirror.multiplexingMode = function(outer /*, others */) {
	  // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
	  var others = Array.prototype.slice.call(arguments, 1);
	
	  function indexOf(string, pattern, from, returnEnd) {
	    if (typeof pattern == "string") {
	      var found = string.indexOf(pattern, from);
	      return returnEnd && found > -1 ? found + pattern.length : found;
	    }
	    var m = pattern.exec(from ? string.slice(from) : string);
	    return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1;
	  }
	
	  return {
	    startState: function() {
	      return {
	        outer: CodeMirror.startState(outer),
	        innerActive: null,
	        inner: null
	      };
	    },
	
	    copyState: function(state) {
	      return {
	        outer: CodeMirror.copyState(outer, state.outer),
	        innerActive: state.innerActive,
	        inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
	      };
	    },
	
	    token: function(stream, state) {
	      if (!state.innerActive) {
	        var cutOff = Infinity, oldContent = stream.string;
	        for (var i = 0; i < others.length; ++i) {
	          var other = others[i];
	          var found = indexOf(oldContent, other.open, stream.pos);
	          if (found == stream.pos) {
	            if (!other.parseDelimiters) stream.match(other.open);
	            state.innerActive = other;
	            state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
	            return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
	          } else if (found != -1 && found < cutOff) {
	            cutOff = found;
	          }
	        }
	        if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
	        var outerToken = outer.token(stream, state.outer);
	        if (cutOff != Infinity) stream.string = oldContent;
	        return outerToken;
	      } else {
	        var curInner = state.innerActive, oldContent = stream.string;
	        if (!curInner.close && stream.sol()) {
	          state.innerActive = state.inner = null;
	          return this.token(stream, state);
	        }
	        var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1;
	        if (found == stream.pos && !curInner.parseDelimiters) {
	          stream.match(curInner.close);
	          state.innerActive = state.inner = null;
	          return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
	        }
	        if (found > -1) stream.string = oldContent.slice(0, found);
	        var innerToken = curInner.mode.token(stream, state.inner);
	        if (found > -1) stream.string = oldContent;
	
	        if (found == stream.pos && curInner.parseDelimiters)
	          state.innerActive = state.inner = null;
	
	        if (curInner.innerStyle) {
	          if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
	          else innerToken = curInner.innerStyle;
	        }
	
	        return innerToken;
	      }
	    },
	
	    indent: function(state, textAfter) {
	      var mode = state.innerActive ? state.innerActive.mode : outer;
	      if (!mode.indent) return CodeMirror.Pass;
	      return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
	    },
	
	    blankLine: function(state) {
	      var mode = state.innerActive ? state.innerActive.mode : outer;
	      if (mode.blankLine) {
	        mode.blankLine(state.innerActive ? state.inner : state.outer);
	      }
	      if (!state.innerActive) {
	        for (var i = 0; i < others.length; ++i) {
	          var other = others[i];
	          if (other.open === "\n") {
	            state.innerActive = other;
	            state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0);
	          }
	        }
	      } else if (state.innerActive.close === "\n") {
	        state.innerActive = state.inner = null;
	      }
	    },
	
	    electricChars: outer.electricChars,
	
	    innerMode: function(state) {
	      return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
	    }
	  };
	};
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/mode/multiplex.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/javascript/javascript.js **/
jupyter.define('codemirror@5.27.2/mode/javascript/javascript.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	function expressionAllowed(stream, state, backUp) {
	  return /^(?:operator|sof|keyword c|case|new|export|default|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
	    (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
	}
	
	CodeMirror.defineMode("javascript", function(config, parserConfig) {
	  var indentUnit = config.indentUnit;
	  var statementIndent = parserConfig.statementIndent;
	  var jsonldMode = parserConfig.jsonld;
	  var jsonMode = parserConfig.json || jsonldMode;
	  var isTS = parserConfig.typescript;
	  var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
	
	  // Tokenizer
	
	  var keywords = function(){
	    function kw(type) {return {type: type, style: "keyword"};}
	    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
	    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
	
	    var jsKeywords = {
	      "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
	      "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
	      "var": kw("var"), "const": kw("var"), "let": kw("var"),
	      "function": kw("function"), "catch": kw("catch"),
	      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
	      "in": operator, "typeof": operator, "instanceof": operator,
	      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
	      "this": kw("this"), "class": kw("class"), "super": kw("atom"),
	      "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
	      "await": C
	    };
	
	    // Extend the 'normal' keywords with the TypeScript language extensions
	    if (isTS) {
	      var type = {type: "variable", style: "type"};
	      var tsKeywords = {
	        // object-like things
	        "interface": kw("class"),
	        "implements": C,
	        "namespace": C,
	        "module": kw("module"),
	        "enum": kw("module"),
	
	        // scope modifiers
	        "public": kw("modifier"),
	        "private": kw("modifier"),
	        "protected": kw("modifier"),
	        "abstract": kw("modifier"),
	
	        // types
	        "string": type, "number": type, "boolean": type, "any": type
	      };
	
	      for (var attr in tsKeywords) {
	        jsKeywords[attr] = tsKeywords[attr];
	      }
	    }
	
	    return jsKeywords;
	  }();
	
	  var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
	  var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
	
	  function readRegexp(stream) {
	    var escaped = false, next, inSet = false;
	    while ((next = stream.next()) != null) {
	      if (!escaped) {
	        if (next == "/" && !inSet) return;
	        if (next == "[") inSet = true;
	        else if (inSet && next == "]") inSet = false;
	      }
	      escaped = !escaped && next == "\\";
	    }
	  }
	
	  // Used as scratch variables to communicate multiple values without
	  // consing up tons of objects.
	  var type, content;
	  function ret(tp, style, cont) {
	    type = tp; content = cont;
	    return style;
	  }
	  function tokenBase(stream, state) {
	    var ch = stream.next();
	    if (ch == '"' || ch == "'") {
	      state.tokenize = tokenString(ch);
	      return state.tokenize(stream, state);
	    } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
	      return ret("number", "number");
	    } else if (ch == "." && stream.match("..")) {
	      return ret("spread", "meta");
	    } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
	      return ret(ch);
	    } else if (ch == "=" && stream.eat(">")) {
	      return ret("=>", "operator");
	    } else if (ch == "0" && stream.eat(/x/i)) {
	      stream.eatWhile(/[\da-f]/i);
	      return ret("number", "number");
	    } else if (ch == "0" && stream.eat(/o/i)) {
	      stream.eatWhile(/[0-7]/i);
	      return ret("number", "number");
	    } else if (ch == "0" && stream.eat(/b/i)) {
	      stream.eatWhile(/[01]/i);
	      return ret("number", "number");
	    } else if (/\d/.test(ch)) {
	      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
	      return ret("number", "number");
	    } else if (ch == "/") {
	      if (stream.eat("*")) {
	        state.tokenize = tokenComment;
	        return tokenComment(stream, state);
	      } else if (stream.eat("/")) {
	        stream.skipToEnd();
	        return ret("comment", "comment");
	      } else if (expressionAllowed(stream, state, 1)) {
	        readRegexp(stream);
	        stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
	        return ret("regexp", "string-2");
	      } else {
	        stream.eatWhile(isOperatorChar);
	        return ret("operator", "operator", stream.current());
	      }
	    } else if (ch == "`") {
	      state.tokenize = tokenQuasi;
	      return tokenQuasi(stream, state);
	    } else if (ch == "#") {
	      stream.skipToEnd();
	      return ret("error", "error");
	    } else if (isOperatorChar.test(ch)) {
	      if (ch != ">" || !state.lexical || state.lexical.type != ">")
	        stream.eatWhile(isOperatorChar);
	      return ret("operator", "operator", stream.current());
	    } else if (wordRE.test(ch)) {
	      stream.eatWhile(wordRE);
	      var word = stream.current()
	      if (state.lastType != ".") {
	        if (keywords.propertyIsEnumerable(word)) {
	          var kw = keywords[word]
	          return ret(kw.type, kw.style, word)
	        }
	        if (word == "async" && stream.match(/^\s*[\(\w]/, false))
	          return ret("async", "keyword", word)
	      }
	      return ret("variable", "variable", word)
	    }
	  }
	
	  function tokenString(quote) {
	    return function(stream, state) {
	      var escaped = false, next;
	      if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
	        state.tokenize = tokenBase;
	        return ret("jsonld-keyword", "meta");
	      }
	      while ((next = stream.next()) != null) {
	        if (next == quote && !escaped) break;
	        escaped = !escaped && next == "\\";
	      }
	      if (!escaped) state.tokenize = tokenBase;
	      return ret("string", "string");
	    };
	  }
	
	  function tokenComment(stream, state) {
	    var maybeEnd = false, ch;
	    while (ch = stream.next()) {
	      if (ch == "/" && maybeEnd) {
	        state.tokenize = tokenBase;
	        break;
	      }
	      maybeEnd = (ch == "*");
	    }
	    return ret("comment", "comment");
	  }
	
	  function tokenQuasi(stream, state) {
	    var escaped = false, next;
	    while ((next = stream.next()) != null) {
	      if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
	        state.tokenize = tokenBase;
	        break;
	      }
	      escaped = !escaped && next == "\\";
	    }
	    return ret("quasi", "string-2", stream.current());
	  }
	
	  var brackets = "([{}])";
	  // This is a crude lookahead trick to try and notice that we're
	  // parsing the argument patterns for a fat-arrow function before we
	  // actually hit the arrow token. It only works if the arrow is on
	  // the same line as the arguments and there's no strange noise
	  // (comments) in between. Fallback is to only notice when we hit the
	  // arrow, and not declare the arguments as locals for the arrow
	  // body.
	  function findFatArrow(stream, state) {
	    if (state.fatArrowAt) state.fatArrowAt = null;
	    var arrow = stream.string.indexOf("=>", stream.start);
	    if (arrow < 0) return;
	
	    if (isTS) { // Try to skip TypeScript return type declarations after the arguments
	      var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
	      if (m) arrow = m.index
	    }
	
	    var depth = 0, sawSomething = false;
	    for (var pos = arrow - 1; pos >= 0; --pos) {
	      var ch = stream.string.charAt(pos);
	      var bracket = brackets.indexOf(ch);
	      if (bracket >= 0 && bracket < 3) {
	        if (!depth) { ++pos; break; }
	        if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
	      } else if (bracket >= 3 && bracket < 6) {
	        ++depth;
	      } else if (wordRE.test(ch)) {
	        sawSomething = true;
	      } else if (/["'\/]/.test(ch)) {
	        return;
	      } else if (sawSomething && !depth) {
	        ++pos;
	        break;
	      }
	    }
	    if (sawSomething && !depth) state.fatArrowAt = pos;
	  }
	
	  // Parser
	
	  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
	
	  function JSLexical(indented, column, type, align, prev, info) {
	    this.indented = indented;
	    this.column = column;
	    this.type = type;
	    this.prev = prev;
	    this.info = info;
	    if (align != null) this.align = align;
	  }
	
	  function inScope(state, varname) {
	    for (var v = state.localVars; v; v = v.next)
	      if (v.name == varname) return true;
	    for (var cx = state.context; cx; cx = cx.prev) {
	      for (var v = cx.vars; v; v = v.next)
	        if (v.name == varname) return true;
	    }
	  }
	
	  function parseJS(state, style, type, content, stream) {
	    var cc = state.cc;
	    // Communicate our context to the combinators.
	    // (Less wasteful than consing up a hundred closures on every call.)
	    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
	
	    if (!state.lexical.hasOwnProperty("align"))
	      state.lexical.align = true;
	
	    while(true) {
	      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
	      if (combinator(type, content)) {
	        while(cc.length && cc[cc.length - 1].lex)
	          cc.pop()();
	        if (cx.marked) return cx.marked;
	        if (type == "variable" && inScope(state, content)) return "variable-2";
	        return style;
	      }
	    }
	  }
	
	  // Combinator utils
	
	  var cx = {state: null, column: null, marked: null, cc: null};
	  function pass() {
	    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
	  }
	  function cont() {
	    pass.apply(null, arguments);
	    return true;
	  }
	  function register(varname) {
	    function inList(list) {
	      for (var v = list; v; v = v.next)
	        if (v.name == varname) return true;
	      return false;
	    }
	    var state = cx.state;
	    cx.marked = "def";
	    if (state.context) {
	      if (inList(state.localVars)) return;
	      state.localVars = {name: varname, next: state.localVars};
	    } else {
	      if (inList(state.globalVars)) return;
	      if (parserConfig.globalVars)
	        state.globalVars = {name: varname, next: state.globalVars};
	    }
	  }
	
	  // Combinators
	
	  var defaultVars = {name: "this", next: {name: "arguments"}};
	  function pushcontext() {
	    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
	    cx.state.localVars = defaultVars;
	  }
	  function popcontext() {
	    cx.state.localVars = cx.state.context.vars;
	    cx.state.context = cx.state.context.prev;
	  }
	  function pushlex(type, info) {
	    var result = function() {
	      var state = cx.state, indent = state.indented;
	      if (state.lexical.type == "stat") indent = state.lexical.indented;
	      else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
	        indent = outer.indented;
	      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
	    };
	    result.lex = true;
	    return result;
	  }
	  function poplex() {
	    var state = cx.state;
	    if (state.lexical.prev) {
	      if (state.lexical.type == ")")
	        state.indented = state.lexical.indented;
	      state.lexical = state.lexical.prev;
	    }
	  }
	  poplex.lex = true;
	
	  function expect(wanted) {
	    function exp(type) {
	      if (type == wanted) return cont();
	      else if (wanted == ";") return pass();
	      else return cont(exp);
	    };
	    return exp;
	  }
	
	  function statement(type, value) {
	    if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
	    if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
	    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
	    if (type == "{") return cont(pushlex("}"), block, poplex);
	    if (type == ";") return cont();
	    if (type == "if") {
	      if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
	        cx.state.cc.pop()();
	      return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
	    }
	    if (type == "function") return cont(functiondef);
	    if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
	    if (type == "variable") {
	      if (isTS && value == "type") {
	        cx.marked = "keyword"
	        return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
	      } else {
	        return cont(pushlex("stat"), maybelabel);
	      }
	    }
	    if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"),
	                                      block, poplex, poplex);
	    if (type == "case") return cont(expression, expect(":"));
	    if (type == "default") return cont(expect(":"));
	    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
	                                     statement, poplex, popcontext);
	    if (type == "class") return cont(pushlex("form"), className, poplex);
	    if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
	    if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
	    if (type == "module") return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
	    if (type == "async") return cont(statement)
	    if (value == "@") return cont(expression, statement)
	    return pass(pushlex("stat"), expression, expect(";"), poplex);
	  }
	  function expression(type) {
	    return expressionInner(type, false);
	  }
	  function expressionNoComma(type) {
	    return expressionInner(type, true);
	  }
	  function parenExpr(type) {
	    if (type != "(") return pass()
	    return cont(pushlex(")"), expression, expect(")"), poplex)
	  }
	  function expressionInner(type, noComma) {
	    if (cx.state.fatArrowAt == cx.stream.start) {
	      var body = noComma ? arrowBodyNoComma : arrowBody;
	      if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
	      else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
	    }
	
	    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
	    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
	    if (type == "function") return cont(functiondef, maybeop);
	    if (type == "class") return cont(pushlex("form"), classExpression, poplex);
	    if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
	    if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
	    if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
	    if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
	    if (type == "{") return contCommasep(objprop, "}", null, maybeop);
	    if (type == "quasi") return pass(quasi, maybeop);
	    if (type == "new") return cont(maybeTarget(noComma));
	    return cont();
	  }
	  function maybeexpression(type) {
	    if (type.match(/[;\}\)\],]/)) return pass();
	    return pass(expression);
	  }
	  function maybeexpressionNoComma(type) {
	    if (type.match(/[;\}\)\],]/)) return pass();
	    return pass(expressionNoComma);
	  }
	
	  function maybeoperatorComma(type, value) {
	    if (type == ",") return cont(expression);
	    return maybeoperatorNoComma(type, value, false);
	  }
	  function maybeoperatorNoComma(type, value, noComma) {
	    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
	    var expr = noComma == false ? expression : expressionNoComma;
	    if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
	    if (type == "operator") {
	      if (/\+\+|--/.test(value)) return cont(me);
	      if (value == "?") return cont(expression, expect(":"), expr);
	      return cont(expr);
	    }
	    if (type == "quasi") { return pass(quasi, me); }
	    if (type == ";") return;
	    if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
	    if (type == ".") return cont(property, me);
	    if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
	    if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
	  }
	  function quasi(type, value) {
	    if (type != "quasi") return pass();
	    if (value.slice(value.length - 2) != "${") return cont(quasi);
	    return cont(expression, continueQuasi);
	  }
	  function continueQuasi(type) {
	    if (type == "}") {
	      cx.marked = "string-2";
	      cx.state.tokenize = tokenQuasi;
	      return cont(quasi);
	    }
	  }
	  function arrowBody(type) {
	    findFatArrow(cx.stream, cx.state);
	    return pass(type == "{" ? statement : expression);
	  }
	  function arrowBodyNoComma(type) {
	    findFatArrow(cx.stream, cx.state);
	    return pass(type == "{" ? statement : expressionNoComma);
	  }
	  function maybeTarget(noComma) {
	    return function(type) {
	      if (type == ".") return cont(noComma ? targetNoComma : target);
	      else return pass(noComma ? expressionNoComma : expression);
	    };
	  }
	  function target(_, value) {
	    if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
	  }
	  function targetNoComma(_, value) {
	    if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
	  }
	  function maybelabel(type) {
	    if (type == ":") return cont(poplex, statement);
	    return pass(maybeoperatorComma, expect(";"), poplex);
	  }
	  function property(type) {
	    if (type == "variable") {cx.marked = "property"; return cont();}
	  }
	  function objprop(type, value) {
	    if (type == "async") {
	      cx.marked = "property";
	      return cont(objprop);
	    } else if (type == "variable" || cx.style == "keyword") {
	      cx.marked = "property";
	      if (value == "get" || value == "set") return cont(getterSetter);
	      return cont(afterprop);
	    } else if (type == "number" || type == "string") {
	      cx.marked = jsonldMode ? "property" : (cx.style + " property");
	      return cont(afterprop);
	    } else if (type == "jsonld-keyword") {
	      return cont(afterprop);
	    } else if (type == "modifier") {
	      return cont(objprop)
	    } else if (type == "[") {
	      return cont(expression, expect("]"), afterprop);
	    } else if (type == "spread") {
	      return cont(expression, afterprop);
	    } else if (type == ":") {
	      return pass(afterprop)
	    }
	  }
	  function getterSetter(type) {
	    if (type != "variable") return pass(afterprop);
	    cx.marked = "property";
	    return cont(functiondef);
	  }
	  function afterprop(type) {
	    if (type == ":") return cont(expressionNoComma);
	    if (type == "(") return pass(functiondef);
	  }
	  function commasep(what, end, sep) {
	    function proceed(type, value) {
	      if (sep ? sep.indexOf(type) > -1 : type == ",") {
	        var lex = cx.state.lexical;
	        if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
	        return cont(function(type, value) {
	          if (type == end || value == end) return pass()
	          return pass(what)
	        }, proceed);
	      }
	      if (type == end || value == end) return cont();
	      return cont(expect(end));
	    }
	    return function(type, value) {
	      if (type == end || value == end) return cont();
	      return pass(what, proceed);
	    };
	  }
	  function contCommasep(what, end, info) {
	    for (var i = 3; i < arguments.length; i++)
	      cx.cc.push(arguments[i]);
	    return cont(pushlex(end, info), commasep(what, end), poplex);
	  }
	  function block(type) {
	    if (type == "}") return cont();
	    return pass(statement, block);
	  }
	  function maybetype(type, value) {
	    if (isTS) {
	      if (type == ":") return cont(typeexpr);
	      if (value == "?") return cont(maybetype);
	    }
	  }
	  function typeexpr(type) {
	    if (type == "variable") {cx.marked = "type"; return cont(afterType);}
	    if (type == "string" || type == "number" || type == "atom") return cont(afterType);
	    if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
	    if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
	  }
	  function maybeReturnType(type) {
	    if (type == "=>") return cont(typeexpr)
	  }
	  function typeprop(type, value) {
	    if (type == "variable" || cx.style == "keyword") {
	      cx.marked = "property"
	      return cont(typeprop)
	    } else if (value == "?") {
	      return cont(typeprop)
	    } else if (type == ":") {
	      return cont(typeexpr)
	    } else if (type == "[") {
	      return cont(expression, maybetype, expect("]"), typeprop)
	    }
	  }
	  function typearg(type) {
	    if (type == "variable") return cont(typearg)
	    else if (type == ":") return cont(typeexpr)
	  }
	  function afterType(type, value) {
	    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
	    if (value == "|" || type == ".") return cont(typeexpr)
	    if (type == "[") return cont(expect("]"), afterType)
	    if (value == "extends") return cont(typeexpr)
	  }
	  function vardef() {
	    return pass(pattern, maybetype, maybeAssign, vardefCont);
	  }
	  function pattern(type, value) {
	    if (type == "modifier") return cont(pattern)
	    if (type == "variable") { register(value); return cont(); }
	    if (type == "spread") return cont(pattern);
	    if (type == "[") return contCommasep(pattern, "]");
	    if (type == "{") return contCommasep(proppattern, "}");
	  }
	  function proppattern(type, value) {
	    if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
	      register(value);
	      return cont(maybeAssign);
	    }
	    if (type == "variable") cx.marked = "property";
	    if (type == "spread") return cont(pattern);
	    if (type == "}") return pass();
	    return cont(expect(":"), pattern, maybeAssign);
	  }
	  function maybeAssign(_type, value) {
	    if (value == "=") return cont(expressionNoComma);
	  }
	  function vardefCont(type) {
	    if (type == ",") return cont(vardef);
	  }
	  function maybeelse(type, value) {
	    if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
	  }
	  function forspec(type) {
	    if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
	  }
	  function forspec1(type) {
	    if (type == "var") return cont(vardef, expect(";"), forspec2);
	    if (type == ";") return cont(forspec2);
	    if (type == "variable") return cont(formaybeinof);
	    return pass(expression, expect(";"), forspec2);
	  }
	  function formaybeinof(_type, value) {
	    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
	    return cont(maybeoperatorComma, forspec2);
	  }
	  function forspec2(type, value) {
	    if (type == ";") return cont(forspec3);
	    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
	    return pass(expression, expect(";"), forspec3);
	  }
	  function forspec3(type) {
	    if (type != ")") cont(expression);
	  }
	  function functiondef(type, value) {
	    if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
	    if (type == "variable") {register(value); return cont(functiondef);}
	    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
	    if (isTS && value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, functiondef)
	  }
	  function funarg(type) {
	    if (type == "spread") return cont(funarg);
	    return pass(pattern, maybetype, maybeAssign);
	  }
	  function classExpression(type, value) {
	    // Class expressions may have an optional name.
	    if (type == "variable") return className(type, value);
	    return classNameAfter(type, value);
	  }
	  function className(type, value) {
	    if (type == "variable") {register(value); return cont(classNameAfter);}
	  }
	  function classNameAfter(type, value) {
	    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, classNameAfter)
	    if (value == "extends" || value == "implements" || (isTS && type == ","))
	      return cont(isTS ? typeexpr : expression, classNameAfter);
	    if (type == "{") return cont(pushlex("}"), classBody, poplex);
	  }
	  function classBody(type, value) {
	    if (type == "variable" || cx.style == "keyword") {
	      if ((value == "async" || value == "static" || value == "get" || value == "set" ||
	           (isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) &&
	          cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) {
	        cx.marked = "keyword";
	        return cont(classBody);
	      }
	      cx.marked = "property";
	      return cont(isTS ? classfield : functiondef, classBody);
	    }
	    if (type == "[")
	      return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
	    if (value == "*") {
	      cx.marked = "keyword";
	      return cont(classBody);
	    }
	    if (type == ";") return cont(classBody);
	    if (type == "}") return cont();
	    if (value == "@") return cont(expression, classBody)
	  }
	  function classfield(type, value) {
	    if (value == "?") return cont(classfield)
	    if (type == ":") return cont(typeexpr, maybeAssign)
	    if (value == "=") return cont(expressionNoComma)
	    return pass(functiondef)
	  }
	  function afterExport(type, value) {
	    if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
	    if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
	    if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
	    return pass(statement);
	  }
	  function exportField(type, value) {
	    if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
	    if (type == "variable") return pass(expressionNoComma, exportField);
	  }
	  function afterImport(type) {
	    if (type == "string") return cont();
	    return pass(importSpec, maybeMoreImports, maybeFrom);
	  }
	  function importSpec(type, value) {
	    if (type == "{") return contCommasep(importSpec, "}");
	    if (type == "variable") register(value);
	    if (value == "*") cx.marked = "keyword";
	    return cont(maybeAs);
	  }
	  function maybeMoreImports(type) {
	    if (type == ",") return cont(importSpec, maybeMoreImports)
	  }
	  function maybeAs(_type, value) {
	    if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
	  }
	  function maybeFrom(_type, value) {
	    if (value == "from") { cx.marked = "keyword"; return cont(expression); }
	  }
	  function arrayLiteral(type) {
	    if (type == "]") return cont();
	    return pass(commasep(expressionNoComma, "]"));
	  }
	
	  function isContinuedStatement(state, textAfter) {
	    return state.lastType == "operator" || state.lastType == "," ||
	      isOperatorChar.test(textAfter.charAt(0)) ||
	      /[,.]/.test(textAfter.charAt(0));
	  }
	
	  // Interface
	
	  return {
	    startState: function(basecolumn) {
	      var state = {
	        tokenize: tokenBase,
	        lastType: "sof",
	        cc: [],
	        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
	        localVars: parserConfig.localVars,
	        context: parserConfig.localVars && {vars: parserConfig.localVars},
	        indented: basecolumn || 0
	      };
	      if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
	        state.globalVars = parserConfig.globalVars;
	      return state;
	    },
	
	    token: function(stream, state) {
	      if (stream.sol()) {
	        if (!state.lexical.hasOwnProperty("align"))
	          state.lexical.align = false;
	        state.indented = stream.indentation();
	        findFatArrow(stream, state);
	      }
	      if (state.tokenize != tokenComment && stream.eatSpace()) return null;
	      var style = state.tokenize(stream, state);
	      if (type == "comment") return style;
	      state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
	      return parseJS(state, style, type, content, stream);
	    },
	
	    indent: function(state, textAfter) {
	      if (state.tokenize == tokenComment) return CodeMirror.Pass;
	      if (state.tokenize != tokenBase) return 0;
	      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
	      // Kludge to prevent 'maybelse' from blocking lexical scope pops
	      if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
	        var c = state.cc[i];
	        if (c == poplex) lexical = lexical.prev;
	        else if (c != maybeelse) break;
	      }
	      while ((lexical.type == "stat" || lexical.type == "form") &&
	             (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
	                                   (top == maybeoperatorComma || top == maybeoperatorNoComma) &&
	                                   !/^[,\.=+\-*:?[\(]/.test(textAfter))))
	        lexical = lexical.prev;
	      if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
	        lexical = lexical.prev;
	      var type = lexical.type, closing = firstChar == type;
	
	      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
	      else if (type == "form" && firstChar == "{") return lexical.indented;
	      else if (type == "form") return lexical.indented + indentUnit;
	      else if (type == "stat")
	        return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
	      else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
	        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
	      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
	      else return lexical.indented + (closing ? 0 : indentUnit);
	    },
	
	    electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
	    blockCommentStart: jsonMode ? null : "/*",
	    blockCommentEnd: jsonMode ? null : "*/",
	    lineComment: jsonMode ? null : "//",
	    fold: "brace",
	    closeBrackets: "()[]{}''\"\"``",
	
	    helperType: jsonMode ? "json" : "javascript",
	    jsonldMode: jsonldMode,
	    jsonMode: jsonMode,
	
	    expressionAllowed: expressionAllowed,
	    skipExpression: function(state) {
	      var top = state.cc[state.cc.length - 1]
	      if (top == expression || top == expressionNoComma) state.cc.pop()
	    }
	  };
	});
	
	CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
	
	CodeMirror.defineMIME("text/javascript", "javascript");
	CodeMirror.defineMIME("text/ecmascript", "javascript");
	CodeMirror.defineMIME("application/javascript", "javascript");
	CodeMirror.defineMIME("application/x-javascript", "javascript");
	CodeMirror.defineMIME("application/ecmascript", "javascript");
	CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
	CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
	CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
	CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
	CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/javascript/javascript.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/css/css.js **/
jupyter.define('codemirror@5.27.2/mode/css/css.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	CodeMirror.defineMode("css", function(config, parserConfig) {
	  var inline = parserConfig.inline
	  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
	
	  var indentUnit = config.indentUnit,
	      tokenHooks = parserConfig.tokenHooks,
	      documentTypes = parserConfig.documentTypes || {},
	      mediaTypes = parserConfig.mediaTypes || {},
	      mediaFeatures = parserConfig.mediaFeatures || {},
	      mediaValueKeywords = parserConfig.mediaValueKeywords || {},
	      propertyKeywords = parserConfig.propertyKeywords || {},
	      nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
	      fontProperties = parserConfig.fontProperties || {},
	      counterDescriptors = parserConfig.counterDescriptors || {},
	      colorKeywords = parserConfig.colorKeywords || {},
	      valueKeywords = parserConfig.valueKeywords || {},
	      allowNested = parserConfig.allowNested,
	      lineComment = parserConfig.lineComment,
	      supportsAtComponent = parserConfig.supportsAtComponent === true;
	
	  var type, override;
	  function ret(style, tp) { type = tp; return style; }
	
	  // Tokenizers
	
	  function tokenBase(stream, state) {
	    var ch = stream.next();
	    if (tokenHooks[ch]) {
	      var result = tokenHooks[ch](stream, state);
	      if (result !== false) return result;
	    }
	    if (ch == "@") {
	      stream.eatWhile(/[\w\\\-]/);
	      return ret("def", stream.current());
	    } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
	      return ret(null, "compare");
	    } else if (ch == "\"" || ch == "'") {
	      state.tokenize = tokenString(ch);
	      return state.tokenize(stream, state);
	    } else if (ch == "#") {
	      stream.eatWhile(/[\w\\\-]/);
	      return ret("atom", "hash");
	    } else if (ch == "!") {
	      stream.match(/^\s*\w*/);
	      return ret("keyword", "important");
	    } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
	      stream.eatWhile(/[\w.%]/);
	      return ret("number", "unit");
	    } else if (ch === "-") {
	      if (/[\d.]/.test(stream.peek())) {
	        stream.eatWhile(/[\w.%]/);
	        return ret("number", "unit");
	      } else if (stream.match(/^-[\w\\\-]+/)) {
	        stream.eatWhile(/[\w\\\-]/);
	        if (stream.match(/^\s*:/, false))
	          return ret("variable-2", "variable-definition");
	        return ret("variable-2", "variable");
	      } else if (stream.match(/^\w+-/)) {
	        return ret("meta", "meta");
	      }
	    } else if (/[,+>*\/]/.test(ch)) {
	      return ret(null, "select-op");
	    } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
	      return ret("qualifier", "qualifier");
	    } else if (/[:;{}\[\]\(\)]/.test(ch)) {
	      return ret(null, ch);
	    } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
	               (ch == "d" && stream.match("omain(")) ||
	               (ch == "r" && stream.match("egexp("))) {
	      stream.backUp(1);
	      state.tokenize = tokenParenthesized;
	      return ret("property", "word");
	    } else if (/[\w\\\-]/.test(ch)) {
	      stream.eatWhile(/[\w\\\-]/);
	      return ret("property", "word");
	    } else {
	      return ret(null, null);
	    }
	  }
	
	  function tokenString(quote) {
	    return function(stream, state) {
	      var escaped = false, ch;
	      while ((ch = stream.next()) != null) {
	        if (ch == quote && !escaped) {
	          if (quote == ")") stream.backUp(1);
	          break;
	        }
	        escaped = !escaped && ch == "\\";
	      }
	      if (ch == quote || !escaped && quote != ")") state.tokenize = null;
	      return ret("string", "string");
	    };
	  }
	
	  function tokenParenthesized(stream, state) {
	    stream.next(); // Must be '('
	    if (!stream.match(/\s*[\"\')]/, false))
	      state.tokenize = tokenString(")");
	    else
	      state.tokenize = null;
	    return ret(null, "(");
	  }
	
	  // Context management
	
	  function Context(type, indent, prev) {
	    this.type = type;
	    this.indent = indent;
	    this.prev = prev;
	  }
	
	  function pushContext(state, stream, type, indent) {
	    state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
	    return type;
	  }
	
	  function popContext(state) {
	    if (state.context.prev)
	      state.context = state.context.prev;
	    return state.context.type;
	  }
	
	  function pass(type, stream, state) {
	    return states[state.context.type](type, stream, state);
	  }
	  function popAndPass(type, stream, state, n) {
	    for (var i = n || 1; i > 0; i--)
	      state.context = state.context.prev;
	    return pass(type, stream, state);
	  }
	
	  // Parser
	
	  function wordAsValue(stream) {
	    var word = stream.current().toLowerCase();
	    if (valueKeywords.hasOwnProperty(word))
	      override = "atom";
	    else if (colorKeywords.hasOwnProperty(word))
	      override = "keyword";
	    else
	      override = "variable";
	  }
	
	  var states = {};
	
	  states.top = function(type, stream, state) {
	    if (type == "{") {
	      return pushContext(state, stream, "block");
	    } else if (type == "}" && state.context.prev) {
	      return popContext(state);
	    } else if (supportsAtComponent && /@component/.test(type)) {
	      return pushContext(state, stream, "atComponentBlock");
	    } else if (/^@(-moz-)?document$/.test(type)) {
	      return pushContext(state, stream, "documentTypes");
	    } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
	      return pushContext(state, stream, "atBlock");
	    } else if (/^@(font-face|counter-style)/.test(type)) {
	      state.stateArg = type;
	      return "restricted_atBlock_before";
	    } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
	      return "keyframes";
	    } else if (type && type.charAt(0) == "@") {
	      return pushContext(state, stream, "at");
	    } else if (type == "hash") {
	      override = "builtin";
	    } else if (type == "word") {
	      override = "tag";
	    } else if (type == "variable-definition") {
	      return "maybeprop";
	    } else if (type == "interpolation") {
	      return pushContext(state, stream, "interpolation");
	    } else if (type == ":") {
	      return "pseudo";
	    } else if (allowNested && type == "(") {
	      return pushContext(state, stream, "parens");
	    }
	    return state.context.type;
	  };
	
	  states.block = function(type, stream, state) {
	    if (type == "word") {
	      var word = stream.current().toLowerCase();
	      if (propertyKeywords.hasOwnProperty(word)) {
	        override = "property";
	        return "maybeprop";
	      } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
	        override = "string-2";
	        return "maybeprop";
	      } else if (allowNested) {
	        override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
	        return "block";
	      } else {
	        override += " error";
	        return "maybeprop";
	      }
	    } else if (type == "meta") {
	      return "block";
	    } else if (!allowNested && (type == "hash" || type == "qualifier")) {
	      override = "error";
	      return "block";
	    } else {
	      return states.top(type, stream, state);
	    }
	  };
	
	  states.maybeprop = function(type, stream, state) {
	    if (type == ":") return pushContext(state, stream, "prop");
	    return pass(type, stream, state);
	  };
	
	  states.prop = function(type, stream, state) {
	    if (type == ";") return popContext(state);
	    if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
	    if (type == "}" || type == "{") return popAndPass(type, stream, state);
	    if (type == "(") return pushContext(state, stream, "parens");
	
	    if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
	      override += " error";
	    } else if (type == "word") {
	      wordAsValue(stream);
	    } else if (type == "interpolation") {
	      return pushContext(state, stream, "interpolation");
	    }
	    return "prop";
	  };
	
	  states.propBlock = function(type, _stream, state) {
	    if (type == "}") return popContext(state);
	    if (type == "word") { override = "property"; return "maybeprop"; }
	    return state.context.type;
	  };
	
	  states.parens = function(type, stream, state) {
	    if (type == "{" || type == "}") return popAndPass(type, stream, state);
	    if (type == ")") return popContext(state);
	    if (type == "(") return pushContext(state, stream, "parens");
	    if (type == "interpolation") return pushContext(state, stream, "interpolation");
	    if (type == "word") wordAsValue(stream);
	    return "parens";
	  };
	
	  states.pseudo = function(type, stream, state) {
	    if (type == "meta") return "pseudo";
	
	    if (type == "word") {
	      override = "variable-3";
	      return state.context.type;
	    }
	    return pass(type, stream, state);
	  };
	
	  states.documentTypes = function(type, stream, state) {
	    if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
	      override = "tag";
	      return state.context.type;
	    } else {
	      return states.atBlock(type, stream, state);
	    }
	  };
	
	  states.atBlock = function(type, stream, state) {
	    if (type == "(") return pushContext(state, stream, "atBlock_parens");
	    if (type == "}" || type == ";") return popAndPass(type, stream, state);
	    if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
	
	    if (type == "interpolation") return pushContext(state, stream, "interpolation");
	
	    if (type == "word") {
	      var word = stream.current().toLowerCase();
	      if (word == "only" || word == "not" || word == "and" || word == "or")
	        override = "keyword";
	      else if (mediaTypes.hasOwnProperty(word))
	        override = "attribute";
	      else if (mediaFeatures.hasOwnProperty(word))
	        override = "property";
	      else if (mediaValueKeywords.hasOwnProperty(word))
	        override = "keyword";
	      else if (propertyKeywords.hasOwnProperty(word))
	        override = "property";
	      else if (nonStandardPropertyKeywords.hasOwnProperty(word))
	        override = "string-2";
	      else if (valueKeywords.hasOwnProperty(word))
	        override = "atom";
	      else if (colorKeywords.hasOwnProperty(word))
	        override = "keyword";
	      else
	        override = "error";
	    }
	    return state.context.type;
	  };
	
	  states.atComponentBlock = function(type, stream, state) {
	    if (type == "}")
	      return popAndPass(type, stream, state);
	    if (type == "{")
	      return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
	    if (type == "word")
	      override = "error";
	    return state.context.type;
	  };
	
	  states.atBlock_parens = function(type, stream, state) {
	    if (type == ")") return popContext(state);
	    if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
	    return states.atBlock(type, stream, state);
	  };
	
	  states.restricted_atBlock_before = function(type, stream, state) {
	    if (type == "{")
	      return pushContext(state, stream, "restricted_atBlock");
	    if (type == "word" && state.stateArg == "@counter-style") {
	      override = "variable";
	      return "restricted_atBlock_before";
	    }
	    return pass(type, stream, state);
	  };
	
	  states.restricted_atBlock = function(type, stream, state) {
	    if (type == "}") {
	      state.stateArg = null;
	      return popContext(state);
	    }
	    if (type == "word") {
	      if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
	          (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
	        override = "error";
	      else
	        override = "property";
	      return "maybeprop";
	    }
	    return "restricted_atBlock";
	  };
	
	  states.keyframes = function(type, stream, state) {
	    if (type == "word") { override = "variable"; return "keyframes"; }
	    if (type == "{") return pushContext(state, stream, "top");
	    return pass(type, stream, state);
	  };
	
	  states.at = function(type, stream, state) {
	    if (type == ";") return popContext(state);
	    if (type == "{" || type == "}") return popAndPass(type, stream, state);
	    if (type == "word") override = "tag";
	    else if (type == "hash") override = "builtin";
	    return "at";
	  };
	
	  states.interpolation = function(type, stream, state) {
	    if (type == "}") return popContext(state);
	    if (type == "{" || type == ";") return popAndPass(type, stream, state);
	    if (type == "word") override = "variable";
	    else if (type != "variable" && type != "(" && type != ")") override = "error";
	    return "interpolation";
	  };
	
	  return {
	    startState: function(base) {
	      return {tokenize: null,
	              state: inline ? "block" : "top",
	              stateArg: null,
	              context: new Context(inline ? "block" : "top", base || 0, null)};
	    },
	
	    token: function(stream, state) {
	      if (!state.tokenize && stream.eatSpace()) return null;
	      var style = (state.tokenize || tokenBase)(stream, state);
	      if (style && typeof style == "object") {
	        type = style[1];
	        style = style[0];
	      }
	      override = style;
	      state.state = states[state.state](type, stream, state);
	      return override;
	    },
	
	    indent: function(state, textAfter) {
	      var cx = state.context, ch = textAfter && textAfter.charAt(0);
	      var indent = cx.indent;
	      if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
	      if (cx.prev) {
	        if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
	                          cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
	          // Resume indentation from parent context.
	          cx = cx.prev;
	          indent = cx.indent;
	        } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
	            ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
	          // Dedent relative to current context.
	          indent = Math.max(0, cx.indent - indentUnit);
	        }
	      }
	      return indent;
	    },
	
	    electricChars: "}",
	    blockCommentStart: "/*",
	    blockCommentEnd: "*/",
	    lineComment: lineComment,
	    fold: "brace"
	  };
	});
	
	  function keySet(array) {
	    var keys = {};
	    for (var i = 0; i < array.length; ++i) {
	      keys[array[i].toLowerCase()] = true;
	    }
	    return keys;
	  }
	
	  var documentTypes_ = [
	    "domain", "regexp", "url", "url-prefix"
	  ], documentTypes = keySet(documentTypes_);
	
	  var mediaTypes_ = [
	    "all", "aural", "braille", "handheld", "print", "projection", "screen",
	    "tty", "tv", "embossed"
	  ], mediaTypes = keySet(mediaTypes_);
	
	  var mediaFeatures_ = [
	    "width", "min-width", "max-width", "height", "min-height", "max-height",
	    "device-width", "min-device-width", "max-device-width", "device-height",
	    "min-device-height", "max-device-height", "aspect-ratio",
	    "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
	    "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
	    "max-color", "color-index", "min-color-index", "max-color-index",
	    "monochrome", "min-monochrome", "max-monochrome", "resolution",
	    "min-resolution", "max-resolution", "scan", "grid", "orientation",
	    "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
	    "pointer", "any-pointer", "hover", "any-hover"
	  ], mediaFeatures = keySet(mediaFeatures_);
	
	  var mediaValueKeywords_ = [
	    "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
	    "interlace", "progressive"
	  ], mediaValueKeywords = keySet(mediaValueKeywords_);
	
	  var propertyKeywords_ = [
	    "align-content", "align-items", "align-self", "alignment-adjust",
	    "alignment-baseline", "anchor-point", "animation", "animation-delay",
	    "animation-direction", "animation-duration", "animation-fill-mode",
	    "animation-iteration-count", "animation-name", "animation-play-state",
	    "animation-timing-function", "appearance", "azimuth", "backface-visibility",
	    "background", "background-attachment", "background-blend-mode", "background-clip",
	    "background-color", "background-image", "background-origin", "background-position",
	    "background-repeat", "background-size", "baseline-shift", "binding",
	    "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
	    "bookmark-target", "border", "border-bottom", "border-bottom-color",
	    "border-bottom-left-radius", "border-bottom-right-radius",
	    "border-bottom-style", "border-bottom-width", "border-collapse",
	    "border-color", "border-image", "border-image-outset",
	    "border-image-repeat", "border-image-slice", "border-image-source",
	    "border-image-width", "border-left", "border-left-color",
	    "border-left-style", "border-left-width", "border-radius", "border-right",
	    "border-right-color", "border-right-style", "border-right-width",
	    "border-spacing", "border-style", "border-top", "border-top-color",
	    "border-top-left-radius", "border-top-right-radius", "border-top-style",
	    "border-top-width", "border-width", "bottom", "box-decoration-break",
	    "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
	    "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
	    "column-fill", "column-gap", "column-rule", "column-rule-color",
	    "column-rule-style", "column-rule-width", "column-span", "column-width",
	    "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
	    "cue-after", "cue-before", "cursor", "direction", "display",
	    "dominant-baseline", "drop-initial-after-adjust",
	    "drop-initial-after-align", "drop-initial-before-adjust",
	    "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
	    "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
	    "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
	    "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
	    "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
	    "font-stretch", "font-style", "font-synthesis", "font-variant",
	    "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
	    "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
	    "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
	    "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
	    "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
	    "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
	    "grid-template-rows", "hanging-punctuation", "height", "hyphens",
	    "icon", "image-orientation", "image-rendering", "image-resolution",
	    "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
	    "line-break", "line-height", "line-stacking", "line-stacking-ruby",
	    "line-stacking-shift", "line-stacking-strategy", "list-style",
	    "list-style-image", "list-style-position", "list-style-type", "margin",
	    "margin-bottom", "margin-left", "margin-right", "margin-top",
	    "marks", "marquee-direction", "marquee-loop",
	    "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
	    "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
	    "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
	    "opacity", "order", "orphans", "outline",
	    "outline-color", "outline-offset", "outline-style", "outline-width",
	    "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
	    "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
	    "page", "page-break-after", "page-break-before", "page-break-inside",
	    "page-policy", "pause", "pause-after", "pause-before", "perspective",
	    "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
	    "presentation-level", "punctuation-trim", "quotes", "region-break-after",
	    "region-break-before", "region-break-inside", "region-fragment",
	    "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
	    "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
	    "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
	    "shape-outside", "size", "speak", "speak-as", "speak-header",
	    "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
	    "tab-size", "table-layout", "target", "target-name", "target-new",
	    "target-position", "text-align", "text-align-last", "text-decoration",
	    "text-decoration-color", "text-decoration-line", "text-decoration-skip",
	    "text-decoration-style", "text-emphasis", "text-emphasis-color",
	    "text-emphasis-position", "text-emphasis-style", "text-height",
	    "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
	    "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
	    "text-wrap", "top", "transform", "transform-origin", "transform-style",
	    "transition", "transition-delay", "transition-duration",
	    "transition-property", "transition-timing-function", "unicode-bidi",
	    "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
	    "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
	    "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
	    "word-spacing", "word-wrap", "z-index",
	    // SVG-specific
	    "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
	    "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
	    "color-interpolation", "color-interpolation-filters",
	    "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
	    "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
	    "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
	    "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
	    "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
	    "glyph-orientation-vertical", "text-anchor", "writing-mode"
	  ], propertyKeywords = keySet(propertyKeywords_);
	
	  var nonStandardPropertyKeywords_ = [
	    "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
	    "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
	    "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
	    "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
	    "searchfield-results-decoration", "zoom"
	  ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
	
	  var fontProperties_ = [
	    "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
	    "font-stretch", "font-weight", "font-style"
	  ], fontProperties = keySet(fontProperties_);
	
	  var counterDescriptors_ = [
	    "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
	    "speak-as", "suffix", "symbols", "system"
	  ], counterDescriptors = keySet(counterDescriptors_);
	
	  var colorKeywords_ = [
	    "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
	    "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
	    "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
	    "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
	    "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
	    "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
	    "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
	    "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
	    "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
	    "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
	    "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
	    "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
	    "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
	    "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
	    "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
	    "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
	    "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
	    "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
	    "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
	    "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
	    "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
	    "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
	    "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
	    "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
	    "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
	    "whitesmoke", "yellow", "yellowgreen"
	  ], colorKeywords = keySet(colorKeywords_);
	
	  var valueKeywords_ = [
	    "above", "absolute", "activeborder", "additive", "activecaption", "afar",
	    "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
	    "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
	    "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
	    "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
	    "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
	    "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
	    "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
	    "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
	    "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
	    "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
	    "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
	    "compact", "condensed", "contain", "content", "contents",
	    "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
	    "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
	    "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
	    "destination-in", "destination-out", "destination-over", "devanagari", "difference",
	    "disc", "discard", "disclosure-closed", "disclosure-open", "document",
	    "dot-dash", "dot-dot-dash",
	    "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
	    "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
	    "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
	    "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
	    "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
	    "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
	    "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
	    "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
	    "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
	    "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
	    "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
	    "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
	    "help", "hidden", "hide", "higher", "highlight", "highlighttext",
	    "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
	    "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
	    "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
	    "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
	    "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
	    "katakana", "katakana-iroha", "keep-all", "khmer",
	    "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
	    "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
	    "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
	    "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
	    "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
	    "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
	    "media-controls-background", "media-current-time-display",
	    "media-fullscreen-button", "media-mute-button", "media-play-button",
	    "media-return-to-realtime-button", "media-rewind-button",
	    "media-seek-back-button", "media-seek-forward-button", "media-slider",
	    "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
	    "media-volume-slider-container", "media-volume-sliderthumb", "medium",
	    "menu", "menulist", "menulist-button", "menulist-text",
	    "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
	    "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
	    "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
	    "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
	    "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
	    "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
	    "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
	    "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
	    "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
	    "progress", "push-button", "radial-gradient", "radio", "read-only",
	    "read-write", "read-write-plaintext-only", "rectangle", "region",
	    "relative", "repeat", "repeating-linear-gradient",
	    "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
	    "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
	    "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
	    "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
	    "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
	    "searchfield-cancel-button", "searchfield-decoration",
	    "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
	    "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
	    "simp-chinese-formal", "simp-chinese-informal", "single",
	    "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
	    "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
	    "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
	    "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
	    "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
	    "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
	    "table-caption", "table-cell", "table-column", "table-column-group",
	    "table-footer-group", "table-header-group", "table-row", "table-row-group",
	    "tamil",
	    "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
	    "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
	    "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
	    "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
	    "trad-chinese-formal", "trad-chinese-informal", "transform",
	    "translate", "translate3d", "translateX", "translateY", "translateZ",
	    "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
	    "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
	    "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
	    "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
	    "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
	    "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
	    "xx-large", "xx-small"
	  ], valueKeywords = keySet(valueKeywords_);
	
	  var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
	    .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
	    .concat(valueKeywords_);
	  CodeMirror.registerHelper("hintWords", "css", allWords);
	
	  function tokenCComment(stream, state) {
	    var maybeEnd = false, ch;
	    while ((ch = stream.next()) != null) {
	      if (maybeEnd && ch == "/") {
	        state.tokenize = null;
	        break;
	      }
	      maybeEnd = (ch == "*");
	    }
	    return ["comment", "comment"];
	  }
	
	  CodeMirror.defineMIME("text/css", {
	    documentTypes: documentTypes,
	    mediaTypes: mediaTypes,
	    mediaFeatures: mediaFeatures,
	    mediaValueKeywords: mediaValueKeywords,
	    propertyKeywords: propertyKeywords,
	    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
	    fontProperties: fontProperties,
	    counterDescriptors: counterDescriptors,
	    colorKeywords: colorKeywords,
	    valueKeywords: valueKeywords,
	    tokenHooks: {
	      "/": function(stream, state) {
	        if (!stream.eat("*")) return false;
	        state.tokenize = tokenCComment;
	        return tokenCComment(stream, state);
	      }
	    },
	    name: "css"
	  });
	
	  CodeMirror.defineMIME("text/x-scss", {
	    mediaTypes: mediaTypes,
	    mediaFeatures: mediaFeatures,
	    mediaValueKeywords: mediaValueKeywords,
	    propertyKeywords: propertyKeywords,
	    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
	    colorKeywords: colorKeywords,
	    valueKeywords: valueKeywords,
	    fontProperties: fontProperties,
	    allowNested: true,
	    lineComment: "//",
	    tokenHooks: {
	      "/": function(stream, state) {
	        if (stream.eat("/")) {
	          stream.skipToEnd();
	          return ["comment", "comment"];
	        } else if (stream.eat("*")) {
	          state.tokenize = tokenCComment;
	          return tokenCComment(stream, state);
	        } else {
	          return ["operator", "operator"];
	        }
	      },
	      ":": function(stream) {
	        if (stream.match(/\s*\{/, false))
	          return [null, null]
	        return false;
	      },
	      "$": function(stream) {
	        stream.match(/^[\w-]+/);
	        if (stream.match(/^\s*:/, false))
	          return ["variable-2", "variable-definition"];
	        return ["variable-2", "variable"];
	      },
	      "#": function(stream) {
	        if (!stream.eat("{")) return false;
	        return [null, "interpolation"];
	      }
	    },
	    name: "css",
	    helperType: "scss"
	  });
	
	  CodeMirror.defineMIME("text/x-less", {
	    mediaTypes: mediaTypes,
	    mediaFeatures: mediaFeatures,
	    mediaValueKeywords: mediaValueKeywords,
	    propertyKeywords: propertyKeywords,
	    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
	    colorKeywords: colorKeywords,
	    valueKeywords: valueKeywords,
	    fontProperties: fontProperties,
	    allowNested: true,
	    lineComment: "//",
	    tokenHooks: {
	      "/": function(stream, state) {
	        if (stream.eat("/")) {
	          stream.skipToEnd();
	          return ["comment", "comment"];
	        } else if (stream.eat("*")) {
	          state.tokenize = tokenCComment;
	          return tokenCComment(stream, state);
	        } else {
	          return ["operator", "operator"];
	        }
	      },
	      "@": function(stream) {
	        if (stream.eat("{")) return [null, "interpolation"];
	        if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
	        stream.eatWhile(/[\w\\\-]/);
	        if (stream.match(/^\s*:/, false))
	          return ["variable-2", "variable-definition"];
	        return ["variable-2", "variable"];
	      },
	      "&": function() {
	        return ["atom", "atom"];
	      }
	    },
	    name: "css",
	    helperType: "less"
	  });
	
	  CodeMirror.defineMIME("text/x-gss", {
	    documentTypes: documentTypes,
	    mediaTypes: mediaTypes,
	    mediaFeatures: mediaFeatures,
	    propertyKeywords: propertyKeywords,
	    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
	    fontProperties: fontProperties,
	    counterDescriptors: counterDescriptors,
	    colorKeywords: colorKeywords,
	    valueKeywords: valueKeywords,
	    supportsAtComponent: true,
	    tokenHooks: {
	      "/": function(stream, state) {
	        if (!stream.eat("*")) return false;
	        state.tokenize = tokenCComment;
	        return tokenCComment(stream, state);
	      }
	    },
	    name: "css",
	    helperType: "gss"
	  });
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/css/css.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/julia/julia.js **/
jupyter.define('codemirror@5.27.2/mode/julia/julia.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	CodeMirror.defineMode("julia", function(config, parserConf) {
	  function wordRegexp(words, end) {
	    if (typeof end === "undefined") { end = "\\b"; }
	    return new RegExp("^((" + words.join(")|(") + "))" + end);
	  }
	
	  var octChar = "\\\\[0-7]{1,3}";
	  var hexChar = "\\\\x[A-Fa-f0-9]{1,2}";
	  var sChar = "\\\\[abefnrtv0%?'\"\\\\]";
	  var uChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])";
	
	  var operators = parserConf.operators || wordRegexp([
	      "\\.?[\\\\%*+\\-<>!=\\/^]=?", "\\.?[|&\\u00F7\\u2260\\u2264\\u2265]",
	      "\\u00D7", "\\u2208", "\\u2209", "\\u220B", "\\u220C", "\\u2229",
	      "\\u222A", "\\u2286", "\\u2288", "\\u228A", "\\u22c5", "\\?", "~", ":",
	      "\\$", "\\.[<>]", "<<=?", ">>>?=?", "\\.[<>=]=", "->?", "\\/\\/", "=>",
	      "<:", "\\bin\\b(?!\\()"], "");
	  var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
	  var identifiers = parserConf.identifiers || /^[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
	
	  var chars = wordRegexp([octChar, hexChar, sChar, uChar], "'");
	  var openers = wordRegexp(["begin", "function", "type", "immutable", "let",
	      "macro", "for", "while", "quote", "if", "else", "elseif", "try",
	      "finally", "catch", "do"]);
	  var closers = wordRegexp(["end", "else", "elseif", "catch", "finally"]);
	  var keywords = wordRegexp(["if", "else", "elseif", "while", "for", "begin",
	      "let", "end", "do", "try", "catch", "finally", "return", "break",
	      "continue", "global", "local", "const", "export", "import", "importall",
	      "using", "function", "macro", "module", "baremodule", "type",
	      "immutable", "quote", "typealias", "abstract", "bitstype"]);
	  var builtins = wordRegexp(["true", "false", "nothing", "NaN", "Inf"]);
	
	  var macro = /^@[_A-Za-z][\w]*/;
	  var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
	  var stringPrefixes = /^(`|([_A-Za-z\u00A1-\uFFFF]*"("")?))/;
	
	  function inArray(state) {
	    return inGenerator(state, '[')
	  }
	
	  function inGenerator(state, bracket) {
	    var curr = currentScope(state),
	        prev = currentScope(state, 1);
	    if (typeof(bracket) === "undefined") { bracket = '('; }
	    if (curr === bracket || (prev === bracket && curr === "for")) {
	      return true;
	    }
	    return false;
	  }
	
	  function currentScope(state, n) {
	    if (typeof(n) === "undefined") { n = 0; }
	    if (state.scopes.length <= n) {
	      return null;
	    }
	    return state.scopes[state.scopes.length - (n + 1)];
	  }
	
	  // tokenizers
	  function tokenBase(stream, state) {
	    // Handle multiline comments
	    if (stream.match(/^#=/, false)) {
	      state.tokenize = tokenComment;
	      return state.tokenize(stream, state);
	    }
	
	    // Handle scope changes
	    var leavingExpr = state.leavingExpr;
	    if (stream.sol()) {
	      leavingExpr = false;
	    }
	    state.leavingExpr = false;
	
	    if (leavingExpr) {
	      if (stream.match(/^'+/)) {
	        return "operator";
	      }
	    }
	
	    if (stream.match(/^\.{2,3}/)) {
	      return "operator";
	    }
	
	    if (stream.eatSpace()) {
	      return null;
	    }
	
	    var ch = stream.peek();
	
	    // Handle single line comments
	    if (ch === '#') {
	      stream.skipToEnd();
	      return "comment";
	    }
	
	    if (ch === '[') {
	      state.scopes.push('[');
	    }
	
	    if (ch === '(') {
	      state.scopes.push('(');
	    }
	
	    var scope = currentScope(state);
	
	    if (inArray(state) && ch === ']') {
	      if (scope === "for") { state.scopes.pop(); }
	      state.scopes.pop();
	      state.leavingExpr = true;
	    }
	
	    if (inGenerator(state) && ch === ')') {
	      if (scope === "for") { state.scopes.pop(); }
	      state.scopes.pop();
	      state.leavingExpr = true;
	    }
	
	    var match;
	    if (match = stream.match(openers, false)) {
	      state.scopes.push(match[0]);
	    }
	
	    if (stream.match(closers, false)) {
	      state.scopes.pop();
	    }
	
	    if (inArray(state)) {
	      if (state.lastToken == "end" && stream.match(/^:/)) {
	        return "operator";
	      }
	      if (stream.match(/^end/)) {
	        return "number";
	      }
	    }
	
	    // Handle type annotations
	    if (stream.match(/^::(?![:\$])/)) {
	      state.tokenize = tokenAnnotation;
	      return state.tokenize(stream, state);
	    }
	
	    // Handle symbols
	    if (!leavingExpr && stream.match(symbol) || stream.match(/:\./)) {
	      return "builtin";
	    }
	
	    // Handle parametric types
	    if (stream.match(/^{[^}]*}(?=\()/)) {
	      return "builtin";
	    }
	
	    // Handle operators and Delimiters
	    if (stream.match(operators)) {
	      return "operator";
	    }
	
	    // Handle Number Literals
	    if (stream.match(/^[0-9\.]/, false)) {
	      var imMatcher = RegExp(/^im\b/);
	      var numberLiteral = false;
	      // Floats
	      if (stream.match(/^\d*\.(?!\.)\d*([Eef][\+\-]?\d+)?/i)) { numberLiteral = true; }
	      if (stream.match(/^\d+\.(?!\.)\d*/)) { numberLiteral = true; }
	      if (stream.match(/^\.\d+/)) { numberLiteral = true; }
	      if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { numberLiteral = true; }
	      // Integers
	      if (stream.match(/^0x[0-9a-f]+/i)) { numberLiteral = true; } // Hex
	      if (stream.match(/^0b[01]+/i)) { numberLiteral = true; } // Binary
	      if (stream.match(/^0o[0-7]+/i)) { numberLiteral = true; } // Octal
	      if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { numberLiteral = true; } // Decimal
	      // Zero by itself with no other piece of number.
	      if (stream.match(/^0(?![\dx])/i)) { numberLiteral = true; }
	      if (numberLiteral) {
	          // Integer literals may be "long"
	          stream.match(imMatcher);
	          state.leavingExpr = true;
	          return "number";
	      }
	    }
	
	    // Handle Chars
	    if (stream.match(/^'/)) {
	      state.tokenize = tokenChar;
	      return state.tokenize(stream, state);
	    }
	
	    // Handle Strings
	    if (stream.match(stringPrefixes)) {
	      state.tokenize = tokenStringFactory(stream.current());
	      return state.tokenize(stream, state);
	    }
	
	    if (stream.match(macro)) {
	      return "meta";
	    }
	
	    if (stream.match(delimiters)) {
	      return null;
	    }
	
	    if (stream.match(keywords)) {
	      return "keyword";
	    }
	
	    if (stream.match(builtins)) {
	      return "builtin";
	    }
	
	    var isDefinition = state.isDefinition || state.lastToken == "function" ||
	                       state.lastToken == "macro" || state.lastToken == "type" ||
	                       state.lastToken == "immutable";
	
	    if (stream.match(identifiers)) {
	      if (isDefinition) {
	        if (stream.peek() === '.') {
	          state.isDefinition = true;
	          return "variable";
	        }
	        state.isDefinition = false;
	        return "def";
	      }
	      if (stream.match(/^({[^}]*})*\(/, false)) {
	        return callOrDef(stream, state);
	      }
	      state.leavingExpr = true;
	      return "variable";
	    }
	
	    // Handle non-detected items
	    stream.next();
	    return "error";
	  }
	
	  function callOrDef(stream, state) {
	    var match = stream.match(/^(\(\s*)/);
	    if (match) {
	      if (state.firstParenPos < 0)
	        state.firstParenPos = state.scopes.length;
	      state.scopes.push('(');
	      state.charsAdvanced += match[1].length;
	    }
	    if (currentScope(state) == '(' && stream.match(/^\)/)) {
	      state.scopes.pop();
	      state.charsAdvanced += 1;
	      if (state.scopes.length <= state.firstParenPos) {
	        var isDefinition = stream.match(/^\s*?=(?!=)/, false);
	        stream.backUp(state.charsAdvanced);
	        state.firstParenPos = -1;
	        state.charsAdvanced = 0;
	        if (isDefinition)
	          return "def";
	        return "builtin";
	      }
	    }
	    // Unfortunately javascript does not support multiline strings, so we have
	    // to undo anything done upto here if a function call or definition splits
	    // over two or more lines.
	    if (stream.match(/^$/g, false)) {
	      stream.backUp(state.charsAdvanced);
	      while (state.scopes.length > state.firstParenPos)
	        state.scopes.pop();
	      state.firstParenPos = -1;
	      state.charsAdvanced = 0;
	      return "builtin";
	    }
	    state.charsAdvanced += stream.match(/^([^()]*)/)[1].length;
	    return callOrDef(stream, state);
	  }
	
	  function tokenAnnotation(stream, state) {
	    stream.match(/.*?(?=,|;|{|}|\(|\)|=|$|\s)/);
	    if (stream.match(/^{/)) {
	      state.nestedLevels++;
	    } else if (stream.match(/^}/)) {
	      state.nestedLevels--;
	    }
	    if (state.nestedLevels > 0) {
	      stream.match(/.*?(?={|})/) || stream.next();
	    } else if (state.nestedLevels == 0) {
	      state.tokenize = tokenBase;
	    }
	    return "builtin";
	  }
	
	  function tokenComment(stream, state) {
	    if (stream.match(/^#=/)) {
	      state.nestedLevels++;
	    }
	    if (!stream.match(/.*?(?=(#=|=#))/)) {
	      stream.skipToEnd();
	    }
	    if (stream.match(/^=#/)) {
	      state.nestedLevels--;
	      if (state.nestedLevels == 0)
	        state.tokenize = tokenBase;
	    }
	    return "comment";
	  }
	
	  function tokenChar(stream, state) {
	    var isChar = false, match;
	    if (stream.match(chars)) {
	      isChar = true;
	    } else if (match = stream.match(/\\u([a-f0-9]{1,4})(?=')/i)) {
	      var value = parseInt(match[1], 16);
	      if (value <= 55295 || value >= 57344) { // (U+0,U+D7FF), (U+E000,U+FFFF)
	        isChar = true;
	        stream.next();
	      }
	    } else if (match = stream.match(/\\U([A-Fa-f0-9]{5,8})(?=')/)) {
	      var value = parseInt(match[1], 16);
	      if (value <= 1114111) { // U+10FFFF
	        isChar = true;
	        stream.next();
	      }
	    }
	    if (isChar) {
	      state.leavingExpr = true;
	      state.tokenize = tokenBase;
	      return "string";
	    }
	    if (!stream.match(/^[^']+(?=')/)) { stream.skipToEnd(); }
	    if (stream.match(/^'/)) { state.tokenize = tokenBase; }
	    return "error";
	  }
	
	  function tokenStringFactory(delimiter) {
	    if (delimiter.substr(-3) === '"""') {
	      delimiter = '"""';
	    } else if (delimiter.substr(-1) === '"') {
	      delimiter = '"';
	    }
	    function tokenString(stream, state) {
	      if (stream.eat('\\')) {
	        stream.next();
	      } else if (stream.match(delimiter)) {
	        state.tokenize = tokenBase;
	        state.leavingExpr = true;
	        return "string";
	      } else {
	        stream.eat(/[`"]/);
	      }
	      stream.eatWhile(/[^\\`"]/);
	      return "string";
	    }
	    return tokenString;
	  }
	
	  var external = {
	    startState: function() {
	      return {
	        tokenize: tokenBase,
	        scopes: [],
	        lastToken: null,
	        leavingExpr: false,
	        isDefinition: false,
	        nestedLevels: 0,
	        charsAdvanced: 0,
	        firstParenPos: -1
	      };
	    },
	
	    token: function(stream, state) {
	      var style = state.tokenize(stream, state);
	      var current = stream.current();
	
	      if (current && style) {
	        state.lastToken = current;
	      }
	
	      // Handle '.' connected identifiers
	      if (current === '.') {
	        style = stream.match(identifiers, false) || stream.match(macro, false) ||
	                stream.match(/\(/, false) ? "operator" : "error";
	      }
	      return style;
	    },
	
	    indent: function(state, textAfter) {
	      var delta = 0;
	      if ( textAfter === ']' || textAfter === ')' || textAfter === "end" ||
	           textAfter === "else" || textAfter === "catch" || textAfter === "elseif" ||
	           textAfter === "finally" ) {
	        delta = -1;
	      }
	      return (state.scopes.length + delta) * config.indentUnit;
	    },
	
	    electricInput: /\b(end|else|catch|finally)\b/,
	    blockCommentStart: "#=",
	    blockCommentEnd: "=#",
	    lineComment: "#",
	    fold: "indent"
	  };
	  return external;
	});
	
	
	CodeMirror.defineMIME("text/x-julia", "julia");
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/julia/julia.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/mode/r/r.js **/
jupyter.define('codemirror@5.27.2/mode/r/r.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	"use strict";
	
	CodeMirror.registerHelper("wordChars", "r", /[\w.]/);
	
	CodeMirror.defineMode("r", function(config) {
	  function wordObj(str) {
	    var words = str.split(" "), res = {};
	    for (var i = 0; i < words.length; ++i) res[words[i]] = true;
	    return res;
	  }
	  var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_");
	  var builtins = wordObj("list quote bquote eval return call parse deparse");
	  var keywords = wordObj("if else repeat while function for in next break");
	  var blockkeywords = wordObj("if else repeat while function for");
	  var opChars = /[+\-*\/^<>=!&|~$:]/;
	  var curPunc;
	
	  function tokenBase(stream, state) {
	    curPunc = null;
	    var ch = stream.next();
	    if (ch == "#") {
	      stream.skipToEnd();
	      return "comment";
	    } else if (ch == "0" && stream.eat("x")) {
	      stream.eatWhile(/[\da-f]/i);
	      return "number";
	    } else if (ch == "." && stream.eat(/\d/)) {
	      stream.match(/\d*(?:e[+\-]?\d+)?/);
	      return "number";
	    } else if (/\d/.test(ch)) {
	      stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/);
	      return "number";
	    } else if (ch == "'" || ch == '"') {
	      state.tokenize = tokenString(ch);
	      return "string";
	    } else if (ch == "`") {
	      stream.match(/[^`]+`/);
	      return "variable-3";
	    } else if (ch == "." && stream.match(/.[.\d]+/)) {
	      return "keyword";
	    } else if (/[\w\.]/.test(ch) && ch != "_") {
	      stream.eatWhile(/[\w\.]/);
	      var word = stream.current();
	      if (atoms.propertyIsEnumerable(word)) return "atom";
	      if (keywords.propertyIsEnumerable(word)) {
	        // Block keywords start new blocks, except 'else if', which only starts
	        // one new block for the 'if', no block for the 'else'.
	        if (blockkeywords.propertyIsEnumerable(word) &&
	            !stream.match(/\s*if(\s+|$)/, false))
	          curPunc = "block";
	        return "keyword";
	      }
	      if (builtins.propertyIsEnumerable(word)) return "builtin";
	      return "variable";
	    } else if (ch == "%") {
	      if (stream.skipTo("%")) stream.next();
	      return "operator variable-2";
	    } else if (
	        (ch == "<" && stream.eat("-")) ||
	        (ch == "<" && stream.match("<-")) ||
	        (ch == "-" && stream.match(/>>?/))
	      ) {
	      return "operator arrow";
	    } else if (ch == "=" && state.ctx.argList) {
	      return "arg-is";
	    } else if (opChars.test(ch)) {
	      if (ch == "$") return "operator dollar";
	      stream.eatWhile(opChars);
	      return "operator";
	    } else if (/[\(\){}\[\];]/.test(ch)) {
	      curPunc = ch;
	      if (ch == ";") return "semi";
	      return null;
	    } else {
	      return null;
	    }
	  }
	
	  function tokenString(quote) {
	    return function(stream, state) {
	      if (stream.eat("\\")) {
	        var ch = stream.next();
	        if (ch == "x") stream.match(/^[a-f0-9]{2}/i);
	        else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next();
	        else if (ch == "u") stream.match(/^[a-f0-9]{4}/i);
	        else if (ch == "U") stream.match(/^[a-f0-9]{8}/i);
	        else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/);
	        return "string-2";
	      } else {
	        var next;
	        while ((next = stream.next()) != null) {
	          if (next == quote) { state.tokenize = tokenBase; break; }
	          if (next == "\\") { stream.backUp(1); break; }
	        }
	        return "string";
	      }
	    };
	  }
	
	  var ALIGN_YES = 1, ALIGN_NO = 2, BRACELESS = 4
	
	  function push(state, type, stream) {
	    state.ctx = {type: type,
	                 indent: state.indent,
	                 flags: 0,
	                 column: stream.column(),
	                 prev: state.ctx};
	  }
	  function setFlag(state, flag) {
	    var ctx = state.ctx
	    state.ctx = {type: ctx.type,
	                 indent: ctx.indent,
	                 flags: ctx.flags | flag,
	                 column: ctx.column,
	                 prev: ctx.prev}
	  }
	  function pop(state) {
	    state.indent = state.ctx.indent;
	    state.ctx = state.ctx.prev;
	  }
	
	  return {
	    startState: function() {
	      return {tokenize: tokenBase,
	              ctx: {type: "top",
	                    indent: -config.indentUnit,
	                    flags: ALIGN_NO},
	              indent: 0,
	              afterIdent: false};
	    },
	
	    token: function(stream, state) {
	      if (stream.sol()) {
	        if ((state.ctx.flags & 3) == 0) state.ctx.flags |= ALIGN_NO
	        if (state.ctx.flags & BRACELESS) pop(state)
	        state.indent = stream.indentation();
	      }
	      if (stream.eatSpace()) return null;
	      var style = state.tokenize(stream, state);
	      if (style != "comment" && (state.ctx.flags & ALIGN_NO) == 0) setFlag(state, ALIGN_YES)
	
	      if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && state.ctx.type == "block") pop(state);
	      if (curPunc == "{") push(state, "}", stream);
	      else if (curPunc == "(") {
	        push(state, ")", stream);
	        if (state.afterIdent) state.ctx.argList = true;
	      }
	      else if (curPunc == "[") push(state, "]", stream);
	      else if (curPunc == "block") push(state, "block", stream);
	      else if (curPunc == state.ctx.type) pop(state);
	      else if (state.ctx.type == "block" && style != "comment") setFlag(state, BRACELESS)
	      state.afterIdent = style == "variable" || style == "keyword";
	      return style;
	    },
	
	    indent: function(state, textAfter) {
	      if (state.tokenize != tokenBase) return 0;
	      var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,
	          closing = firstChar == ctx.type;
	      if (ctx.flags & BRACELESS) ctx = ctx.prev
	      if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
	      else if (ctx.flags & ALIGN_YES) return ctx.column + (closing ? 0 : 1);
	      else return ctx.indent + (closing ? 0 : config.indentUnit);
	    },
	
	    lineComment: "#"
	  };
	});
	
	CodeMirror.defineMIME("text/x-rsrc", "r");
	
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/mode/r/r.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/edit/matchbrackets.js **/
jupyter.define('codemirror@5.27.2/addon/edit/matchbrackets.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
	    (document.documentMode == null || document.documentMode < 8);
	
	  var Pos = CodeMirror.Pos;
	
	  var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
	
	  function findMatchingBracket(cm, where, config) {
	    var line = cm.getLineHandle(where.line), pos = where.ch - 1;
	    var afterCursor = config && config.afterCursor
	    if (afterCursor == null)
	      afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
	
	    // A cursor is defined as between two characters, but in in vim command mode
	    // (i.e. not insert mode), the cursor is visually represented as a
	    // highlighted box on top of the 2nd character. Otherwise, we allow matches
	    // from before or after the cursor.
	    var match = (!afterCursor && pos >= 0 && matching[line.text.charAt(pos)]) ||
	        matching[line.text.charAt(++pos)];
	    if (!match) return null;
	    var dir = match.charAt(1) == ">" ? 1 : -1;
	    if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
	    var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
	
	    var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
	    if (found == null) return null;
	    return {from: Pos(where.line, pos), to: found && found.pos,
	            match: found && found.ch == match.charAt(0), forward: dir > 0};
	  }
	
	  // bracketRegex is used to specify which type of bracket to scan
	  // should be a regexp, e.g. /[[\]]/
	  //
	  // Note: If "where" is on an open bracket, then this bracket is ignored.
	  //
	  // Returns false when no bracket was found, null when it reached
	  // maxScanLines and gave up
	  function scanForBracket(cm, where, dir, style, config) {
	    var maxScanLen = (config && config.maxScanLineLength) || 10000;
	    var maxScanLines = (config && config.maxScanLines) || 1000;
	
	    var stack = [];
	    var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
	    var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
	                          : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
	    for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
	      var line = cm.getLine(lineNo);
	      if (!line) continue;
	      var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
	      if (line.length > maxScanLen) continue;
	      if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
	      for (; pos != end; pos += dir) {
	        var ch = line.charAt(pos);
	        if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
	          var match = matching[ch];
	          if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
	          else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
	          else stack.pop();
	        }
	      }
	    }
	    return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
	  }
	
	  function matchBrackets(cm, autoclear, config) {
	    // Disable brace matching in long lines, since it'll cause hugely slow updates
	    var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
	    var marks = [], ranges = cm.listSelections();
	    for (var i = 0; i < ranges.length; i++) {
	      var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
	      if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
	        var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
	        marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
	        if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
	          marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
	      }
	    }
	
	    if (marks.length) {
	      // Kludge to work around the IE bug from issue #1193, where text
	      // input stops going to the textare whever this fires.
	      if (ie_lt8 && cm.state.focused) cm.focus();
	
	      var clear = function() {
	        cm.operation(function() {
	          for (var i = 0; i < marks.length; i++) marks[i].clear();
	        });
	      };
	      if (autoclear) setTimeout(clear, 800);
	      else return clear;
	    }
	  }
	
	  var currentlyHighlighted = null;
	  function doMatchBrackets(cm) {
	    cm.operation(function() {
	      if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
	      currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
	    });
	  }
	
	  CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
	    if (old && old != CodeMirror.Init) {
	      cm.off("cursorActivity", doMatchBrackets);
	      if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
	    }
	    if (val) {
	      cm.state.matchBrackets = typeof val == "object" ? val : {};
	      cm.on("cursorActivity", doMatchBrackets);
	    }
	  });
	
	  CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
	  CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
	    // Backwards-compatibility kludge
	    if (oldConfig || typeof config == "boolean") {
	      if (!oldConfig) {
	        config = config ? {strict: true} : null
	      } else {
	        oldConfig.strict = config
	        config = oldConfig
	      }
	    }
	    return findMatchingBracket(this, pos, config)
	  });
	  CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
	    return scanForBracket(this, pos, dir, style, config);
	  });
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/edit/matchbrackets.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/edit/closebrackets.js **/
jupyter.define('codemirror@5.27.2/addon/edit/closebrackets.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  var defaults = {
	    pairs: "()[]{}''\"\"",
	    triples: "",
	    explode: "[]{}"
	  };
	
	  var Pos = CodeMirror.Pos;
	
	  CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
	    if (old && old != CodeMirror.Init) {
	      cm.removeKeyMap(keyMap);
	      cm.state.closeBrackets = null;
	    }
	    if (val) {
	      cm.state.closeBrackets = val;
	      cm.addKeyMap(keyMap);
	    }
	  });
	
	  function getOption(conf, name) {
	    if (name == "pairs" && typeof conf == "string") return conf;
	    if (typeof conf == "object" && conf[name] != null) return conf[name];
	    return defaults[name];
	  }
	
	  var bind = defaults.pairs + "`";
	  var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
	  for (var i = 0; i < bind.length; i++)
	    keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));
	
	  function handler(ch) {
	    return function(cm) { return handleChar(cm, ch); };
	  }
	
	  function getConfig(cm) {
	    var deflt = cm.state.closeBrackets;
	    if (!deflt || deflt.override) return deflt;
	    var mode = cm.getModeAt(cm.getCursor());
	    return mode.closeBrackets || deflt;
	  }
	
	  function handleBackspace(cm) {
	    var conf = getConfig(cm);
	    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
	
	    var pairs = getOption(conf, "pairs");
	    var ranges = cm.listSelections();
	    for (var i = 0; i < ranges.length; i++) {
	      if (!ranges[i].empty()) return CodeMirror.Pass;
	      var around = charsAround(cm, ranges[i].head);
	      if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
	    }
	    for (var i = ranges.length - 1; i >= 0; i--) {
	      var cur = ranges[i].head;
	      cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
	    }
	  }
	
	  function handleEnter(cm) {
	    var conf = getConfig(cm);
	    var explode = conf && getOption(conf, "explode");
	    if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
	
	    var ranges = cm.listSelections();
	    for (var i = 0; i < ranges.length; i++) {
	      if (!ranges[i].empty()) return CodeMirror.Pass;
	      var around = charsAround(cm, ranges[i].head);
	      if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
	    }
	    cm.operation(function() {
	      cm.replaceSelection("\n\n", null);
	      cm.execCommand("goCharLeft");
	      ranges = cm.listSelections();
	      for (var i = 0; i < ranges.length; i++) {
	        var line = ranges[i].head.line;
	        cm.indentLine(line, null, true);
	        cm.indentLine(line + 1, null, true);
	      }
	    });
	  }
	
	  function contractSelection(sel) {
	    var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
	    return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
	            head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
	  }
	
	  function handleChar(cm, ch) {
	    var conf = getConfig(cm);
	    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
	
	    var pairs = getOption(conf, "pairs");
	    var pos = pairs.indexOf(ch);
	    if (pos == -1) return CodeMirror.Pass;
	    var triples = getOption(conf, "triples");
	
	    var identical = pairs.charAt(pos + 1) == ch;
	    var ranges = cm.listSelections();
	    var opening = pos % 2 == 0;
	
	    var type;
	    for (var i = 0; i < ranges.length; i++) {
	      var range = ranges[i], cur = range.head, curType;
	      var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
	      if (opening && !range.empty()) {
	        curType = "surround";
	      } else if ((identical || !opening) && next == ch) {
	        if (identical && stringStartsAfter(cm, cur))
	          curType = "both";
	        else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
	          curType = "skipThree";
	        else
	          curType = "skip";
	      } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
	                 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
	                 (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
	        curType = "addFour";
	      } else if (identical) {
	        if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
	        else return CodeMirror.Pass;
	      } else if (opening && (cm.getLine(cur.line).length == cur.ch ||
	                             isClosingBracket(next, pairs) ||
	                             /\s/.test(next))) {
	        curType = "both";
	      } else {
	        return CodeMirror.Pass;
	      }
	      if (!type) type = curType;
	      else if (type != curType) return CodeMirror.Pass;
	    }
	
	    var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
	    var right = pos % 2 ? ch : pairs.charAt(pos + 1);
	    cm.operation(function() {
	      if (type == "skip") {
	        cm.execCommand("goCharRight");
	      } else if (type == "skipThree") {
	        for (var i = 0; i < 3; i++)
	          cm.execCommand("goCharRight");
	      } else if (type == "surround") {
	        var sels = cm.getSelections();
	        for (var i = 0; i < sels.length; i++)
	          sels[i] = left + sels[i] + right;
	        cm.replaceSelections(sels, "around");
	        sels = cm.listSelections().slice();
	        for (var i = 0; i < sels.length; i++)
	          sels[i] = contractSelection(sels[i]);
	        cm.setSelections(sels);
	      } else if (type == "both") {
	        cm.replaceSelection(left + right, null);
	        cm.triggerElectric(left + right);
	        cm.execCommand("goCharLeft");
	      } else if (type == "addFour") {
	        cm.replaceSelection(left + left + left + left, "before");
	        cm.execCommand("goCharRight");
	      }
	    });
	  }
	
	  function isClosingBracket(ch, pairs) {
	    var pos = pairs.lastIndexOf(ch);
	    return pos > -1 && pos % 2 == 1;
	  }
	
	  function charsAround(cm, pos) {
	    var str = cm.getRange(Pos(pos.line, pos.ch - 1),
	                          Pos(pos.line, pos.ch + 1));
	    return str.length == 2 ? str : null;
	  }
	
	  // Project the token type that will exists after the given char is
	  // typed, and use it to determine whether it would cause the start
	  // of a string token.
	  function enteringString(cm, pos, ch) {
	    var line = cm.getLine(pos.line);
	    var token = cm.getTokenAt(pos);
	    if (/\bstring2?\b/.test(token.type) || stringStartsAfter(cm, pos)) return false;
	    var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
	    stream.pos = stream.start = token.start;
	    for (;;) {
	      var type1 = cm.getMode().token(stream, token.state);
	      if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
	      stream.start = stream.pos;
	    }
	  }
	
	  function stringStartsAfter(cm, pos) {
	    var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
	    return /\bstring/.test(token.type) && token.start == pos.ch
	  }
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/edit/closebrackets.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/comment/comment.js **/
jupyter.define('codemirror@5.27.2/addon/comment/comment.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  "use strict";
	
	  var noOptions = {};
	  var nonWS = /[^\s\u00a0]/;
	  var Pos = CodeMirror.Pos;
	
	  function firstNonWS(str) {
	    var found = str.search(nonWS);
	    return found == -1 ? 0 : found;
	  }
	
	  CodeMirror.commands.toggleComment = function(cm) {
	    cm.toggleComment();
	  };
	
	  CodeMirror.defineExtension("toggleComment", function(options) {
	    if (!options) options = noOptions;
	    var cm = this;
	    var minLine = Infinity, ranges = this.listSelections(), mode = null;
	    for (var i = ranges.length - 1; i >= 0; i--) {
	      var from = ranges[i].from(), to = ranges[i].to();
	      if (from.line >= minLine) continue;
	      if (to.line >= minLine) to = Pos(minLine, 0);
	      minLine = from.line;
	      if (mode == null) {
	        if (cm.uncomment(from, to, options)) mode = "un";
	        else { cm.lineComment(from, to, options); mode = "line"; }
	      } else if (mode == "un") {
	        cm.uncomment(from, to, options);
	      } else {
	        cm.lineComment(from, to, options);
	      }
	    }
	  });
	
	  // Rough heuristic to try and detect lines that are part of multi-line string
	  function probablyInsideString(cm, pos, line) {
	    return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
	  }
	
	  function getMode(cm, pos) {
	    var mode = cm.getMode()
	    return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
	  }
	
	  CodeMirror.defineExtension("lineComment", function(from, to, options) {
	    if (!options) options = noOptions;
	    var self = this, mode = getMode(self, from);
	    var firstLine = self.getLine(from.line);
	    if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
	
	    var commentString = options.lineComment || mode.lineComment;
	    if (!commentString) {
	      if (options.blockCommentStart || mode.blockCommentStart) {
	        options.fullLines = true;
	        self.blockComment(from, to, options);
	      }
	      return;
	    }
	
	    var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
	    var pad = options.padding == null ? " " : options.padding;
	    var blankLines = options.commentBlankLines || from.line == to.line;
	
	    self.operation(function() {
	      if (options.indent) {
	        var baseString = null;
	        for (var i = from.line; i < end; ++i) {
	          var line = self.getLine(i);
	          var whitespace = line.slice(0, firstNonWS(line));
	          if (baseString == null || baseString.length > whitespace.length) {
	            baseString = whitespace;
	          }
	        }
	        for (var i = from.line; i < end; ++i) {
	          var line = self.getLine(i), cut = baseString.length;
	          if (!blankLines && !nonWS.test(line)) continue;
	          if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
	          self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
	        }
	      } else {
	        for (var i = from.line; i < end; ++i) {
	          if (blankLines || nonWS.test(self.getLine(i)))
	            self.replaceRange(commentString + pad, Pos(i, 0));
	        }
	      }
	    });
	  });
	
	  CodeMirror.defineExtension("blockComment", function(from, to, options) {
	    if (!options) options = noOptions;
	    var self = this, mode = getMode(self, from);
	    var startString = options.blockCommentStart || mode.blockCommentStart;
	    var endString = options.blockCommentEnd || mode.blockCommentEnd;
	    if (!startString || !endString) {
	      if ((options.lineComment || mode.lineComment) && options.fullLines != false)
	        self.lineComment(from, to, options);
	      return;
	    }
	    if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
	
	    var end = Math.min(to.line, self.lastLine());
	    if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
	
	    var pad = options.padding == null ? " " : options.padding;
	    if (from.line > end) return;
	
	    self.operation(function() {
	      if (options.fullLines != false) {
	        var lastLineHasText = nonWS.test(self.getLine(end));
	        self.replaceRange(pad + endString, Pos(end));
	        self.replaceRange(startString + pad, Pos(from.line, 0));
	        var lead = options.blockCommentLead || mode.blockCommentLead;
	        if (lead != null) for (var i = from.line + 1; i <= end; ++i)
	          if (i != end || lastLineHasText)
	            self.replaceRange(lead + pad, Pos(i, 0));
	      } else {
	        self.replaceRange(endString, to);
	        self.replaceRange(startString, from);
	      }
	    });
	  });
	
	  CodeMirror.defineExtension("uncomment", function(from, to, options) {
	    if (!options) options = noOptions;
	    var self = this, mode = getMode(self, from);
	    var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
	
	    // Try finding line comments
	    var lineString = options.lineComment || mode.lineComment, lines = [];
	    var pad = options.padding == null ? " " : options.padding, didSomething;
	    lineComment: {
	      if (!lineString) break lineComment;
	      for (var i = start; i <= end; ++i) {
	        var line = self.getLine(i);
	        var found = line.indexOf(lineString);
	        if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
	        if (found == -1 && nonWS.test(line)) break lineComment;
	        if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
	        lines.push(line);
	      }
	      self.operation(function() {
	        for (var i = start; i <= end; ++i) {
	          var line = lines[i - start];
	          var pos = line.indexOf(lineString), endPos = pos + lineString.length;
	          if (pos < 0) continue;
	          if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
	          didSomething = true;
	          self.replaceRange("", Pos(i, pos), Pos(i, endPos));
	        }
	      });
	      if (didSomething) return true;
	    }
	
	    // Try block comments
	    var startString = options.blockCommentStart || mode.blockCommentStart;
	    var endString = options.blockCommentEnd || mode.blockCommentEnd;
	    if (!startString || !endString) return false;
	    var lead = options.blockCommentLead || mode.blockCommentLead;
	    var startLine = self.getLine(start), open = startLine.indexOf(startString)
	    if (open == -1) return false
	    var endLine = end == start ? startLine : self.getLine(end)
	    var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
	    if (close == -1 && start != end) {
	      endLine = self.getLine(--end);
	      close = endLine.indexOf(endString);
	    }
	    var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
	    if (close == -1 ||
	        !/comment/.test(self.getTokenTypeAt(insideStart)) ||
	        !/comment/.test(self.getTokenTypeAt(insideEnd)) ||
	        self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
	      return false;
	
	    // Avoid killing block comments completely outside the selection.
	    // Positions of the last startString before the start of the selection, and the first endString after it.
	    var lastStart = startLine.lastIndexOf(startString, from.ch);
	    var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
	    if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
	    // Positions of the first endString after the end of the selection, and the last startString before it.
	    firstEnd = endLine.indexOf(endString, to.ch);
	    var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
	    lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
	    if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
	
	    self.operation(function() {
	      self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
	                        Pos(end, close + endString.length));
	      var openEnd = open + startString.length;
	      if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
	      self.replaceRange("", Pos(start, open), Pos(start, openEnd));
	      if (lead) for (var i = start + 1; i <= end; ++i) {
	        var line = self.getLine(i), found = line.indexOf(lead);
	        if (found == -1 || nonWS.test(line.slice(0, found))) continue;
	        var foundEnd = found + lead.length;
	        if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
	        self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
	      }
	    });
	    return true;
	  });
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/comment/comment.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/keymap/vim.js **/
jupyter.define('codemirror@5.27.2/keymap/vim.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	/**
	 * Supported keybindings:
	 *   Too many to list. Refer to defaultKeyMap below.
	 *
	 * Supported Ex commands:
	 *   Refer to defaultExCommandMap below.
	 *
	 * Registers: unnamed, -, a-z, A-Z, 0-9
	 *   (Does not respect the special case for number registers when delete
	 *    operator is made with these commands: %, (, ),  , /, ?, n, N, {, } )
	 *   TODO: Implement the remaining registers.
	 *
	 * Marks: a-z, A-Z, and 0-9
	 *   TODO: Implement the remaining special marks. They have more complex
	 *       behavior.
	 *
	 * Events:
	 *  'vim-mode-change' - raised on the editor anytime the current mode changes,
	 *                      Event object: {mode: "visual", subMode: "linewise"}
	 *
	 * Code structure:
	 *  1. Default keymap
	 *  2. Variable declarations and short basic helpers
	 *  3. Instance (External API) implementation
	 *  4. Internal state tracking objects (input state, counter) implementation
	 *     and instantiation
	 *  5. Key handler (the main command dispatcher) implementation
	 *  6. Motion, operator, and action implementations
	 *  7. Helper functions for the key handler, motions, operators, and actions
	 *  8. Set up Vim to work as a keymap for CodeMirror.
	 *  9. Ex command implementations.
	 */
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'), __jupyter_require__('codemirror@5.27.2/addon/search/searchcursor.js'), __jupyter_require__('codemirror@5.27.2/addon/dialog/dialog.js'), __jupyter_require__('codemirror@5.27.2/addon/edit/matchbrackets.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/dialog/dialog", "../addon/edit/matchbrackets"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  'use strict';
	
	  var defaultKeymap = [
	    // Key to key mapping. This goes first to make it possible to override
	    // existing mappings.
	    { keys: '<Left>', type: 'keyToKey', toKeys: 'h' },
	    { keys: '<Right>', type: 'keyToKey', toKeys: 'l' },
	    { keys: '<Up>', type: 'keyToKey', toKeys: 'k' },
	    { keys: '<Down>', type: 'keyToKey', toKeys: 'j' },
	    { keys: '<Space>', type: 'keyToKey', toKeys: 'l' },
	    { keys: '<BS>', type: 'keyToKey', toKeys: 'h', context: 'normal'},
	    { keys: '<C-Space>', type: 'keyToKey', toKeys: 'W' },
	    { keys: '<C-BS>', type: 'keyToKey', toKeys: 'B', context: 'normal' },
	    { keys: '<S-Space>', type: 'keyToKey', toKeys: 'w' },
	    { keys: '<S-BS>', type: 'keyToKey', toKeys: 'b', context: 'normal' },
	    { keys: '<C-n>', type: 'keyToKey', toKeys: 'j' },
	    { keys: '<C-p>', type: 'keyToKey', toKeys: 'k' },
	    { keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>' },
	    { keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>' },
	    { keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },
	    { keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },
	    { keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' },
	    { keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'},
	    { keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' },
	    { keys: 'S', type: 'keyToKey', toKeys: 'VdO', context: 'visual' },
	    { keys: '<Home>', type: 'keyToKey', toKeys: '0' },
	    { keys: '<End>', type: 'keyToKey', toKeys: '$' },
	    { keys: '<PageUp>', type: 'keyToKey', toKeys: '<C-b>' },
	    { keys: '<PageDown>', type: 'keyToKey', toKeys: '<C-f>' },
	    { keys: '<CR>', type: 'keyToKey', toKeys: 'j^', context: 'normal' },
	    { keys: '<Ins>', type: 'action', action: 'toggleOverwrite', context: 'insert' },
	    // Motions
	    { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }},
	    { keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }},
	    { keys: 'L', type: 'motion', motion: 'moveToBottomLine', motionArgs: { linewise: true, toJumplist: true }},
	    { keys: 'h', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: false }},
	    { keys: 'l', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: true }},
	    { keys: 'j', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, linewise: true }},
	    { keys: 'k', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, linewise: true }},
	    { keys: 'gj', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: true }},
	    { keys: 'gk', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: false }},
	    { keys: 'w', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false }},
	    { keys: 'W', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false, bigWord: true }},
	    { keys: 'e', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, inclusive: true }},
	    { keys: 'E', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, bigWord: true, inclusive: true }},
	    { keys: 'b', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }},
	    { keys: 'B', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false, bigWord: true }},
	    { keys: 'ge', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, inclusive: true }},
	    { keys: 'gE', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, bigWord: true, inclusive: true }},
	    { keys: '{', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: false, toJumplist: true }},
	    { keys: '}', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: true, toJumplist: true }},
	    { keys: '<C-f>', type: 'motion', motion: 'moveByPage', motionArgs: { forward: true }},
	    { keys: '<C-b>', type: 'motion', motion: 'moveByPage', motionArgs: { forward: false }},
	    { keys: '<C-d>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: true, explicitRepeat: true }},
	    { keys: '<C-u>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }},
	    { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }},
	    { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }},
	    { keys: '0', type: 'motion', motion: 'moveToStartOfLine' },
	    { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' },
	    { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }},
	    { keys: '-', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, toFirstChar:true }},
	    { keys: '_', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true, repeatOffset:-1 }},
	    { keys: '$', type: 'motion', motion: 'moveToEol', motionArgs: { inclusive: true }},
	    { keys: '%', type: 'motion', motion: 'moveToMatchedSymbol', motionArgs: { inclusive: true, toJumplist: true }},
	    { keys: 'f<character>', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: true , inclusive: true }},
	    { keys: 'F<character>', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: false }},
	    { keys: 't<character>', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: true, inclusive: true }},
	    { keys: 'T<character>', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: false }},
	    { keys: ';', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: true }},
	    { keys: ',', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: false }},
	    { keys: '\'<character>', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true, linewise: true}},
	    { keys: '`<character>', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true}},
	    { keys: ']`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true } },
	    { keys: '[`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false } },
	    { keys: ']\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true, linewise: true } },
	    { keys: '[\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false, linewise: true } },
	    // the next two aren't motions but must come before more general motion declarations
	    { keys: ']p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true, matchIndent: true}},
	    { keys: '[p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true, matchIndent: true}},
	    { keys: ']<character>', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: true, toJumplist: true}},
	    { keys: '[<character>', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: false, toJumplist: true}},
	    { keys: '|', type: 'motion', motion: 'moveToColumn'},
	    { keys: 'o', type: 'motion', motion: 'moveToOtherHighlightedEnd', context:'visual'},
	    { keys: 'O', type: 'motion', motion: 'moveToOtherHighlightedEnd', motionArgs: {sameLine: true}, context:'visual'},
	    // Operators
	    { keys: 'd', type: 'operator', operator: 'delete' },
	    { keys: 'y', type: 'operator', operator: 'yank' },
	    { keys: 'c', type: 'operator', operator: 'change' },
	    { keys: '>', type: 'operator', operator: 'indent', operatorArgs: { indentRight: true }},
	    { keys: '<', type: 'operator', operator: 'indent', operatorArgs: { indentRight: false }},
	    { keys: 'g~', type: 'operator', operator: 'changeCase' },
	    { keys: 'gu', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, isEdit: true },
	    { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true },
	    { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }},
	    { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }},
	    // Operator-Motion dual commands
	    { keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }},
	    { keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }},
	    { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},
	    { keys: 'D', type: 'operator', operator: 'delete', operatorArgs: { linewise: true }, context: 'visual'},
	    { keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'expandToLine', motionArgs: { linewise: true }, context: 'normal'},
	    { keys: 'Y', type: 'operator', operator: 'yank', operatorArgs: { linewise: true }, context: 'visual'},
	    { keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},
	    { keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'},
	    { keys: '~', type: 'operatorMotion', operator: 'changeCase', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorArgs: { shouldMoveCursor: true }, context: 'normal'},
	    { keys: '~', type: 'operator', operator: 'changeCase', context: 'visual'},
	    { keys: '<C-w>', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' },
	    // Actions
	    { keys: '<C-i>', type: 'action', action: 'jumpListWalk', actionArgs: { forward: true }},
	    { keys: '<C-o>', type: 'action', action: 'jumpListWalk', actionArgs: { forward: false }},
	    { keys: '<C-e>', type: 'action', action: 'scroll', actionArgs: { forward: true, linewise: true }},
	    { keys: '<C-y>', type: 'action', action: 'scroll', actionArgs: { forward: false, linewise: true }},
	    { keys: 'a', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'charAfter' }, context: 'normal' },
	    { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' },
	    { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' },
	    { keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' },
	    { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' },
	    { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' },
	    { keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' },
	    { keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' },
	    { keys: 'v', type: 'action', action: 'toggleVisualMode' },
	    { keys: 'V', type: 'action', action: 'toggleVisualMode', actionArgs: { linewise: true }},
	    { keys: '<C-v>', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},
	    { keys: '<C-q>', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},
	    { keys: 'gv', type: 'action', action: 'reselectLastSelection' },
	    { keys: 'J', type: 'action', action: 'joinLines', isEdit: true },
	    { keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }},
	    { keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }},
	    { keys: 'r<character>', type: 'action', action: 'replace', isEdit: true },
	    { keys: '@<character>', type: 'action', action: 'replayMacro' },
	    { keys: 'q<character>', type: 'action', action: 'enterMacroRecordMode' },
	    // Handle Replace-mode as a special case of insert mode.
	    { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }},
	    { keys: 'u', type: 'action', action: 'undo', context: 'normal' },
	    { keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true },
	    { keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true },
	    { keys: '<C-r>', type: 'action', action: 'redo' },
	    { keys: 'm<character>', type: 'action', action: 'setMark' },
	    { keys: '"<character>', type: 'action', action: 'setRegister' },
	    { keys: 'zz', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }},
	    { keys: 'z.', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },
	    { keys: 'zt', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }},
	    { keys: 'z<CR>', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },
	    { keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }},
	    { keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },
	    { keys: '.', type: 'action', action: 'repeatLastEdit' },
	    { keys: '<C-a>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: true, backtrack: false}},
	    { keys: '<C-x>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: false, backtrack: false}},
	    { keys: '<C-t>', type: 'action', action: 'indent', actionArgs: { indentRight: true }, context: 'insert' },
	    { keys: '<C-d>', type: 'action', action: 'indent', actionArgs: { indentRight: false }, context: 'insert' },
	    // Text object motions
	    { keys: 'a<character>', type: 'motion', motion: 'textObjectManipulation' },
	    { keys: 'i<character>', type: 'motion', motion: 'textObjectManipulation', motionArgs: { textObjectInner: true }},
	    // Search
	    { keys: '/', type: 'search', searchArgs: { forward: true, querySrc: 'prompt', toJumplist: true }},
	    { keys: '?', type: 'search', searchArgs: { forward: false, querySrc: 'prompt', toJumplist: true }},
	    { keys: '*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }},
	    { keys: '#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }},
	    { keys: 'g*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', toJumplist: true }},
	    { keys: 'g#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', toJumplist: true }},
	    // Ex command
	    { keys: ':', type: 'ex' }
	  ];
	
	  /**
	   * Ex commands
	   * Care must be taken when adding to the default Ex command map. For any
	   * pair of commands that have a shared prefix, at least one of their
	   * shortNames must not match the prefix of the other command.
	   */
	  var defaultExCommandMap = [
	    { name: 'colorscheme', shortName: 'colo' },
	    { name: 'map' },
	    { name: 'imap', shortName: 'im' },
	    { name: 'nmap', shortName: 'nm' },
	    { name: 'vmap', shortName: 'vm' },
	    { name: 'unmap' },
	    { name: 'write', shortName: 'w' },
	    { name: 'undo', shortName: 'u' },
	    { name: 'redo', shortName: 'red' },
	    { name: 'set', shortName: 'se' },
	    { name: 'set', shortName: 'se' },
	    { name: 'setlocal', shortName: 'setl' },
	    { name: 'setglobal', shortName: 'setg' },
	    { name: 'sort', shortName: 'sor' },
	    { name: 'substitute', shortName: 's', possiblyAsync: true },
	    { name: 'nohlsearch', shortName: 'noh' },
	    { name: 'yank', shortName: 'y' },
	    { name: 'delmarks', shortName: 'delm' },
	    { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
	    { name: 'global', shortName: 'g' }
	  ];
	
	  var Pos = CodeMirror.Pos;
	
	  var Vim = function() {
	    function enterVimMode(cm) {
	      cm.setOption('disableInput', true);
	      cm.setOption('showCursorWhenSelecting', false);
	      CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
	      cm.on('cursorActivity', onCursorActivity);
	      maybeInitVimState(cm);
	      CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm));
	    }
	
	    function leaveVimMode(cm) {
	      cm.setOption('disableInput', false);
	      cm.off('cursorActivity', onCursorActivity);
	      CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));
	      cm.state.vim = null;
	    }
	
	    function detachVimMap(cm, next) {
	      if (this == CodeMirror.keyMap.vim)
	        CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor");
	
	      if (!next || next.attach != attachVimMap)
	        leaveVimMode(cm);
	    }
	    function attachVimMap(cm, prev) {
	      if (this == CodeMirror.keyMap.vim)
	        CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor");
	
	      if (!prev || prev.attach != attachVimMap)
	        enterVimMode(cm);
	    }
	
	    // Deprecated, simply setting the keymap works again.
	    CodeMirror.defineOption('vimMode', false, function(cm, val, prev) {
	      if (val && cm.getOption("keyMap") != "vim")
	        cm.setOption("keyMap", "vim");
	      else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption("keyMap")))
	        cm.setOption("keyMap", "default");
	    });
	
	    function cmKey(key, cm) {
	      if (!cm) { return undefined; }
	      if (this[key]) { return this[key]; }
	      var vimKey = cmKeyToVimKey(key);
	      if (!vimKey) {
	        return false;
	      }
	      var cmd = CodeMirror.Vim.findKey(cm, vimKey);
	      if (typeof cmd == 'function') {
	        CodeMirror.signal(cm, 'vim-keypress', vimKey);
	      }
	      return cmd;
	    }
	
	    var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'};
	    var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del',Insert:'Ins'};
	    function cmKeyToVimKey(key) {
	      if (key.charAt(0) == '\'') {
	        // Keypress character binding of format "'a'"
	        return key.charAt(1);
	      }
	      var pieces = key.split(/-(?!$)/);
	      var lastPiece = pieces[pieces.length - 1];
	      if (pieces.length == 1 && pieces[0].length == 1) {
	        // No-modifier bindings use literal character bindings above. Skip.
	        return false;
	      } else if (pieces.length == 2 && pieces[0] == 'Shift' && lastPiece.length == 1) {
	        // Ignore Shift+char bindings as they should be handled by literal character.
	        return false;
	      }
	      var hasCharacter = false;
	      for (var i = 0; i < pieces.length; i++) {
	        var piece = pieces[i];
	        if (piece in modifiers) { pieces[i] = modifiers[piece]; }
	        else { hasCharacter = true; }
	        if (piece in specialKeys) { pieces[i] = specialKeys[piece]; }
	      }
	      if (!hasCharacter) {
	        // Vim does not support modifier only keys.
	        return false;
	      }
	      // TODO: Current bindings expect the character to be lower case, but
	      // it looks like vim key notation uses upper case.
	      if (isUpperCase(lastPiece)) {
	        pieces[pieces.length - 1] = lastPiece.toLowerCase();
	      }
	      return '<' + pieces.join('-') + '>';
	    }
	
	    function getOnPasteFn(cm) {
	      var vim = cm.state.vim;
	      if (!vim.onPasteFn) {
	        vim.onPasteFn = function() {
	          if (!vim.insertMode) {
	            cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));
	            actions.enterInsertMode(cm, {}, vim);
	          }
	        };
	      }
	      return vim.onPasteFn;
	    }
	
	    var numberRegex = /[\d]/;
	    var wordCharTest = [CodeMirror.isWordChar, function(ch) {
	      return ch && !CodeMirror.isWordChar(ch) && !/\s/.test(ch);
	    }], bigWordCharTest = [function(ch) {
	      return /\S/.test(ch);
	    }];
	    function makeKeyRange(start, size) {
	      var keys = [];
	      for (var i = start; i < start + size; i++) {
	        keys.push(String.fromCharCode(i));
	      }
	      return keys;
	    }
	    var upperCaseAlphabet = makeKeyRange(65, 26);
	    var lowerCaseAlphabet = makeKeyRange(97, 26);
	    var numbers = makeKeyRange(48, 10);
	    var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']);
	    var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '/']);
	
	    function isLine(cm, line) {
	      return line >= cm.firstLine() && line <= cm.lastLine();
	    }
	    function isLowerCase(k) {
	      return (/^[a-z]$/).test(k);
	    }
	    function isMatchableSymbol(k) {
	      return '()[]{}'.indexOf(k) != -1;
	    }
	    function isNumber(k) {
	      return numberRegex.test(k);
	    }
	    function isUpperCase(k) {
	      return (/^[A-Z]$/).test(k);
	    }
	    function isWhiteSpaceString(k) {
	      return (/^\s*$/).test(k);
	    }
	    function inArray(val, arr) {
	      for (var i = 0; i < arr.length; i++) {
	        if (arr[i] == val) {
	          return true;
	        }
	      }
	      return false;
	    }
	
	    var options = {};
	    function defineOption(name, defaultValue, type, aliases, callback) {
	      if (defaultValue === undefined && !callback) {
	        throw Error('defaultValue is required unless callback is provided');
	      }
	      if (!type) { type = 'string'; }
	      options[name] = {
	        type: type,
	        defaultValue: defaultValue,
	        callback: callback
	      };
	      if (aliases) {
	        for (var i = 0; i < aliases.length; i++) {
	          options[aliases[i]] = options[name];
	        }
	      }
	      if (defaultValue) {
	        setOption(name, defaultValue);
	      }
	    }
	
	    function setOption(name, value, cm, cfg) {
	      var option = options[name];
	      cfg = cfg || {};
	      var scope = cfg.scope;
	      if (!option) {
	        return new Error('Unknown option: ' + name);
	      }
	      if (option.type == 'boolean') {
	        if (value && value !== true) {
	          return new Error('Invalid argument: ' + name + '=' + value);
	        } else if (value !== false) {
	          // Boolean options are set to true if value is not defined.
	          value = true;
	        }
	      }
	      if (option.callback) {
	        if (scope !== 'local') {
	          option.callback(value, undefined);
	        }
	        if (scope !== 'global' && cm) {
	          option.callback(value, cm);
	        }
	      } else {
	        if (scope !== 'local') {
	          option.value = option.type == 'boolean' ? !!value : value;
	        }
	        if (scope !== 'global' && cm) {
	          cm.state.vim.options[name] = {value: value};
	        }
	      }
	    }
	
	    function getOption(name, cm, cfg) {
	      var option = options[name];
	      cfg = cfg || {};
	      var scope = cfg.scope;
	      if (!option) {
	        return new Error('Unknown option: ' + name);
	      }
	      if (option.callback) {
	        var local = cm && option.callback(undefined, cm);
	        if (scope !== 'global' && local !== undefined) {
	          return local;
	        }
	        if (scope !== 'local') {
	          return option.callback();
	        }
	        return;
	      } else {
	        var local = (scope !== 'global') && (cm && cm.state.vim.options[name]);
	        return (local || (scope !== 'local') && option || {}).value;
	      }
	    }
	
	    defineOption('filetype', undefined, 'string', ['ft'], function(name, cm) {
	      // Option is local. Do nothing for global.
	      if (cm === undefined) {
	        return;
	      }
	      // The 'filetype' option proxies to the CodeMirror 'mode' option.
	      if (name === undefined) {
	        var mode = cm.getOption('mode');
	        return mode == 'null' ? '' : mode;
	      } else {
	        var mode = name == '' ? 'null' : name;
	        cm.setOption('mode', mode);
	      }
	    });
	
	    var createCircularJumpList = function() {
	      var size = 100;
	      var pointer = -1;
	      var head = 0;
	      var tail = 0;
	      var buffer = new Array(size);
	      function add(cm, oldCur, newCur) {
	        var current = pointer % size;
	        var curMark = buffer[current];
	        function useNextSlot(cursor) {
	          var next = ++pointer % size;
	          var trashMark = buffer[next];
	          if (trashMark) {
	            trashMark.clear();
	          }
	          buffer[next] = cm.setBookmark(cursor);
	        }
	        if (curMark) {
	          var markPos = curMark.find();
	          // avoid recording redundant cursor position
	          if (markPos && !cursorEqual(markPos, oldCur)) {
	            useNextSlot(oldCur);
	          }
	        } else {
	          useNextSlot(oldCur);
	        }
	        useNextSlot(newCur);
	        head = pointer;
	        tail = pointer - size + 1;
	        if (tail < 0) {
	          tail = 0;
	        }
	      }
	      function move(cm, offset) {
	        pointer += offset;
	        if (pointer > head) {
	          pointer = head;
	        } else if (pointer < tail) {
	          pointer = tail;
	        }
	        var mark = buffer[(size + pointer) % size];
	        // skip marks that are temporarily removed from text buffer
	        if (mark && !mark.find()) {
	          var inc = offset > 0 ? 1 : -1;
	          var newCur;
	          var oldCur = cm.getCursor();
	          do {
	            pointer += inc;
	            mark = buffer[(size + pointer) % size];
	            // skip marks that are the same as current position
	            if (mark &&
	                (newCur = mark.find()) &&
	                !cursorEqual(oldCur, newCur)) {
	              break;
	            }
	          } while (pointer < head && pointer > tail);
	        }
	        return mark;
	      }
	      return {
	        cachedCursor: undefined, //used for # and * jumps
	        add: add,
	        move: move
	      };
	    };
	
	    // Returns an object to track the changes associated insert mode.  It
	    // clones the object that is passed in, or creates an empty object one if
	    // none is provided.
	    var createInsertModeChanges = function(c) {
	      if (c) {
	        // Copy construction
	        return {
	          changes: c.changes,
	          expectCursorActivityForChange: c.expectCursorActivityForChange
	        };
	      }
	      return {
	        // Change list
	        changes: [],
	        // Set to true on change, false on cursorActivity.
	        expectCursorActivityForChange: false
	      };
	    };
	
	    function MacroModeState() {
	      this.latestRegister = undefined;
	      this.isPlaying = false;
	      this.isRecording = false;
	      this.replaySearchQueries = [];
	      this.onRecordingDone = undefined;
	      this.lastInsertModeChanges = createInsertModeChanges();
	    }
	    MacroModeState.prototype = {
	      exitMacroRecordMode: function() {
	        var macroModeState = vimGlobalState.macroModeState;
	        if (macroModeState.onRecordingDone) {
	          macroModeState.onRecordingDone(); // close dialog
	        }
	        macroModeState.onRecordingDone = undefined;
	        macroModeState.isRecording = false;
	      },
	      enterMacroRecordMode: function(cm, registerName) {
	        var register =
	            vimGlobalState.registerController.getRegister(registerName);
	        if (register) {
	          register.clear();
	          this.latestRegister = registerName;
	          if (cm.openDialog) {
	            this.onRecordingDone = cm.openDialog(
	                '(recording)['+registerName+']', null, {bottom:true});
	          }
	          this.isRecording = true;
	        }
	      }
	    };
	
	    function maybeInitVimState(cm) {
	      if (!cm.state.vim) {
	        // Store instance state in the CodeMirror object.
	        cm.state.vim = {
	          inputState: new InputState(),
	          // Vim's input state that triggered the last edit, used to repeat
	          // motions and operators with '.'.
	          lastEditInputState: undefined,
	          // Vim's action command before the last edit, used to repeat actions
	          // with '.' and insert mode repeat.
	          lastEditActionCommand: undefined,
	          // When using jk for navigation, if you move from a longer line to a
	          // shorter line, the cursor may clip to the end of the shorter line.
	          // If j is pressed again and cursor goes to the next line, the
	          // cursor should go back to its horizontal position on the longer
	          // line if it can. This is to keep track of the horizontal position.
	          lastHPos: -1,
	          // Doing the same with screen-position for gj/gk
	          lastHSPos: -1,
	          // The last motion command run. Cleared if a non-motion command gets
	          // executed in between.
	          lastMotion: null,
	          marks: {},
	          // Mark for rendering fake cursor for visual mode.
	          fakeCursor: null,
	          insertMode: false,
	          // Repeat count for changes made in insert mode, triggered by key
	          // sequences like 3,i. Only exists when insertMode is true.
	          insertModeRepeat: undefined,
	          visualMode: false,
	          // If we are in visual line mode. No effect if visualMode is false.
	          visualLine: false,
	          visualBlock: false,
	          lastSelection: null,
	          lastPastedText: null,
	          sel: {},
	          // Buffer-local/window-local values of vim options.
	          options: {}
	        };
	      }
	      return cm.state.vim;
	    }
	    var vimGlobalState;
	    function resetVimGlobalState() {
	      vimGlobalState = {
	        // The current search query.
	        searchQuery: null,
	        // Whether we are searching backwards.
	        searchIsReversed: false,
	        // Replace part of the last substituted pattern
	        lastSubstituteReplacePart: undefined,
	        jumpList: createCircularJumpList(),
	        macroModeState: new MacroModeState,
	        // Recording latest f, t, F or T motion command.
	        lastCharacterSearch: {increment:0, forward:true, selectedCharacter:''},
	        registerController: new RegisterController({}),
	        // search history buffer
	        searchHistoryController: new HistoryController(),
	        // ex Command history buffer
	        exCommandHistoryController : new HistoryController()
	      };
	      for (var optionName in options) {
	        var option = options[optionName];
	        option.value = option.defaultValue;
	      }
	    }
	
	    var lastInsertModeKeyTimer;
	    var vimApi= {
	      buildKeyMap: function() {
	        // TODO: Convert keymap into dictionary format for fast lookup.
	      },
	      // Testing hook, though it might be useful to expose the register
	      // controller anyways.
	      getRegisterController: function() {
	        return vimGlobalState.registerController;
	      },
	      // Testing hook.
	      resetVimGlobalState_: resetVimGlobalState,
	
	      // Testing hook.
	      getVimGlobalState_: function() {
	        return vimGlobalState;
	      },
	
	      // Testing hook.
	      maybeInitVimState_: maybeInitVimState,
	
	      suppressErrorLogging: false,
	
	      InsertModeKey: InsertModeKey,
	      map: function(lhs, rhs, ctx) {
	        // Add user defined key bindings.
	        exCommandDispatcher.map(lhs, rhs, ctx);
	      },
	      unmap: function(lhs, ctx) {
	        exCommandDispatcher.unmap(lhs, ctx);
	      },
	      // TODO: Expose setOption and getOption as instance methods. Need to decide how to namespace
	      // them, or somehow make them work with the existing CodeMirror setOption/getOption API.
	      setOption: setOption,
	      getOption: getOption,
	      defineOption: defineOption,
	      defineEx: function(name, prefix, func){
	        if (!prefix) {
	          prefix = name;
	        } else if (name.indexOf(prefix) !== 0) {
	          throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered');
	        }
	        exCommands[name]=func;
	        exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'};
	      },
	      handleKey: function (cm, key, origin) {
	        var command = this.findKey(cm, key, origin);
	        if (typeof command === 'function') {
	          return command();
	        }
	      },
	      /**
	       * This is the outermost function called by CodeMirror, after keys have
	       * been mapped to their Vim equivalents.
	       *
	       * Finds a command based on the key (and cached keys if there is a
	       * multi-key sequence). Returns `undefined` if no key is matched, a noop
	       * function if a partial match is found (multi-key), and a function to
	       * execute the bound command if a a key is matched. The function always
	       * returns true.
	       */
	      findKey: function(cm, key, origin) {
	        var vim = maybeInitVimState(cm);
	        function handleMacroRecording() {
	          var macroModeState = vimGlobalState.macroModeState;
	          if (macroModeState.isRecording) {
	            if (key == 'q') {
	              macroModeState.exitMacroRecordMode();
	              clearInputState(cm);
	              return true;
	            }
	            if (origin != 'mapping') {
	              logKey(macroModeState, key);
	            }
	          }
	        }
	        function handleEsc() {
	          if (key == '<Esc>') {
	            // Clear input state and get back to normal mode.
	            clearInputState(cm);
	            if (vim.visualMode) {
	              exitVisualMode(cm);
	            } else if (vim.insertMode) {
	              exitInsertMode(cm);
	            }
	            return true;
	          }
	        }
	        function doKeyToKey(keys) {
	          // TODO: prevent infinite recursion.
	          var match;
	          while (keys) {
	            // Pull off one command key, which is either a single character
	            // or a special sequence wrapped in '<' and '>', e.g. '<Space>'.
	            match = (/<\w+-.+?>|<\w+>|./).exec(keys);
	            key = match[0];
	            keys = keys.substring(match.index + key.length);
	            CodeMirror.Vim.handleKey(cm, key, 'mapping');
	          }
	        }
	
	        function handleKeyInsertMode() {
	          if (handleEsc()) { return true; }
	          var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key;
	          var keysAreChars = key.length == 1;
	          var match = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert');
	          // Need to check all key substrings in insert mode.
	          while (keys.length > 1 && match.type != 'full') {
	            var keys = vim.inputState.keyBuffer = keys.slice(1);
	            var thisMatch = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert');
	            if (thisMatch.type != 'none') { match = thisMatch; }
	          }
	          if (match.type == 'none') { clearInputState(cm); return false; }
	          else if (match.type == 'partial') {
	            if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); }
	            lastInsertModeKeyTimer = window.setTimeout(
	              function() { if (vim.insertMode && vim.inputState.keyBuffer) { clearInputState(cm); } },
	              getOption('insertModeEscKeysTimeout'));
	            return !keysAreChars;
	          }
	
	          if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); }
	          if (keysAreChars) {
	            var selections = cm.listSelections();
	            for (var i = 0; i < selections.length; i++) {
	              var here = selections[i].head;
	              cm.replaceRange('', offsetCursor(here, 0, -(keys.length - 1)), here, '+input');
	            }
	            vimGlobalState.macroModeState.lastInsertModeChanges.changes.pop();
	          }
	          clearInputState(cm);
	          return match.command;
	        }
	
	        function handleKeyNonInsertMode() {
	          if (handleMacroRecording() || handleEsc()) { return true; };
	
	          var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key;
	          if (/^[1-9]\d*$/.test(keys)) { return true; }
	
	          var keysMatcher = /^(\d*)(.*)$/.exec(keys);
	          if (!keysMatcher) { clearInputState(cm); return false; }
	          var context = vim.visualMode ? 'visual' :
	                                         'normal';
	          var match = commandDispatcher.matchCommand(keysMatcher[2] || keysMatcher[1], defaultKeymap, vim.inputState, context);
	          if (match.type == 'none') { clearInputState(cm); return false; }
	          else if (match.type == 'partial') { return true; }
	
	          vim.inputState.keyBuffer = '';
	          var keysMatcher = /^(\d*)(.*)$/.exec(keys);
	          if (keysMatcher[1] && keysMatcher[1] != '0') {
	            vim.inputState.pushRepeatDigit(keysMatcher[1]);
	          }
	          return match.command;
	        }
	
	        var command;
	        if (vim.insertMode) { command = handleKeyInsertMode(); }
	        else { command = handleKeyNonInsertMode(); }
	        if (command === false) {
	          return undefined;
	        } else if (command === true) {
	          // TODO: Look into using CodeMirror's multi-key handling.
	          // Return no-op since we are caching the key. Counts as handled, but
	          // don't want act on it just yet.
	          return function() { return true; };
	        } else {
	          return function() {
	            return cm.operation(function() {
	              cm.curOp.isVimOp = true;
	              try {
	                if (command.type == 'keyToKey') {
	                  doKeyToKey(command.toKeys);
	                } else {
	                  commandDispatcher.processCommand(cm, vim, command);
	                }
	              } catch (e) {
	                // clear VIM state in case it's in a bad state.
	                cm.state.vim = undefined;
	                maybeInitVimState(cm);
	                if (!CodeMirror.Vim.suppressErrorLogging) {
	                  console['log'](e);
	                }
	                throw e;
	              }
	              return true;
	            });
	          };
	        }
	      },
	      handleEx: function(cm, input) {
	        exCommandDispatcher.processCommand(cm, input);
	      },
	
	      defineMotion: defineMotion,
	      defineAction: defineAction,
	      defineOperator: defineOperator,
	      mapCommand: mapCommand,
	      _mapCommand: _mapCommand,
	
	      defineRegister: defineRegister,
	
	      exitVisualMode: exitVisualMode,
	      exitInsertMode: exitInsertMode
	    };
	
	    // Represents the current input state.
	    function InputState() {
	      this.prefixRepeat = [];
	      this.motionRepeat = [];
	
	      this.operator = null;
	      this.operatorArgs = null;
	      this.motion = null;
	      this.motionArgs = null;
	      this.keyBuffer = []; // For matching multi-key commands.
	      this.registerName = null; // Defaults to the unnamed register.
	    }
	    InputState.prototype.pushRepeatDigit = function(n) {
	      if (!this.operator) {
	        this.prefixRepeat = this.prefixRepeat.concat(n);
	      } else {
	        this.motionRepeat = this.motionRepeat.concat(n);
	      }
	    };
	    InputState.prototype.getRepeat = function() {
	      var repeat = 0;
	      if (this.prefixRepeat.length > 0 || this.motionRepeat.length > 0) {
	        repeat = 1;
	        if (this.prefixRepeat.length > 0) {
	          repeat *= parseInt(this.prefixRepeat.join(''), 10);
	        }
	        if (this.motionRepeat.length > 0) {
	          repeat *= parseInt(this.motionRepeat.join(''), 10);
	        }
	      }
	      return repeat;
	    };
	
	    function clearInputState(cm, reason) {
	      cm.state.vim.inputState = new InputState();
	      CodeMirror.signal(cm, 'vim-command-done', reason);
	    }
	
	    /*
	     * Register stores information about copy and paste registers.  Besides
	     * text, a register must store whether it is linewise (i.e., when it is
	     * pasted, should it insert itself into a new line, or should the text be
	     * inserted at the cursor position.)
	     */
	    function Register(text, linewise, blockwise) {
	      this.clear();
	      this.keyBuffer = [text || ''];
	      this.insertModeChanges = [];
	      this.searchQueries = [];
	      this.linewise = !!linewise;
	      this.blockwise = !!blockwise;
	    }
	    Register.prototype = {
	      setText: function(text, linewise, blockwise) {
	        this.keyBuffer = [text || ''];
	        this.linewise = !!linewise;
	        this.blockwise = !!blockwise;
	      },
	      pushText: function(text, linewise) {
	        // if this register has ever been set to linewise, use linewise.
	        if (linewise) {
	          if (!this.linewise) {
	            this.keyBuffer.push('\n');
	          }
	          this.linewise = true;
	        }
	        this.keyBuffer.push(text);
	      },
	      pushInsertModeChanges: function(changes) {
	        this.insertModeChanges.push(createInsertModeChanges(changes));
	      },
	      pushSearchQuery: function(query) {
	        this.searchQueries.push(query);
	      },
	      clear: function() {
	        this.keyBuffer = [];
	        this.insertModeChanges = [];
	        this.searchQueries = [];
	        this.linewise = false;
	      },
	      toString: function() {
	        return this.keyBuffer.join('');
	      }
	    };
	
	    /**
	     * Defines an external register.
	     *
	     * The name should be a single character that will be used to reference the register.
	     * The register should support setText, pushText, clear, and toString(). See Register
	     * for a reference implementation.
	     */
	    function defineRegister(name, register) {
	      var registers = vimGlobalState.registerController.registers;
	      if (!name || name.length != 1) {
	        throw Error('Register name must be 1 character');
	      }
	      if (registers[name]) {
	        throw Error('Register already defined ' + name);
	      }
	      registers[name] = register;
	      validRegisters.push(name);
	    }
	
	    /*
	     * vim registers allow you to keep many independent copy and paste buffers.
	     * See http://usevim.com/2012/04/13/registers/ for an introduction.
	     *
	     * RegisterController keeps the state of all the registers.  An initial
	     * state may be passed in.  The unnamed register '"' will always be
	     * overridden.
	     */
	    function RegisterController(registers) {
	      this.registers = registers;
	      this.unnamedRegister = registers['"'] = new Register();
	      registers['.'] = new Register();
	      registers[':'] = new Register();
	      registers['/'] = new Register();
	    }
	    RegisterController.prototype = {
	      pushText: function(registerName, operator, text, linewise, blockwise) {
	        if (linewise && text.charAt(text.length - 1) !== '\n'){
	          text += '\n';
	        }
	        // Lowercase and uppercase registers refer to the same register.
	        // Uppercase just means append.
	        var register = this.isValidRegister(registerName) ?
	            this.getRegister(registerName) : null;
	        // if no register/an invalid register was specified, things go to the
	        // default registers
	        if (!register) {
	          switch (operator) {
	            case 'yank':
	              // The 0 register contains the text from the most recent yank.
	              this.registers['0'] = new Register(text, linewise, blockwise);
	              break;
	            case 'delete':
	            case 'change':
	              if (text.indexOf('\n') == -1) {
	                // Delete less than 1 line. Update the small delete register.
	                this.registers['-'] = new Register(text, linewise);
	              } else {
	                // Shift down the contents of the numbered registers and put the
	                // deleted text into register 1.
	                this.shiftNumericRegisters_();
	                this.registers['1'] = new Register(text, linewise);
	              }
	              break;
	          }
	          // Make sure the unnamed register is set to what just happened
	          this.unnamedRegister.setText(text, linewise, blockwise);
	          return;
	        }
	
	        // If we've gotten to this point, we've actually specified a register
	        var append = isUpperCase(registerName);
	        if (append) {
	          register.pushText(text, linewise);
	        } else {
	          register.setText(text, linewise, blockwise);
	        }
	        // The unnamed register always has the same value as the last used
	        // register.
	        this.unnamedRegister.setText(register.toString(), linewise);
	      },
	      // Gets the register named @name.  If one of @name doesn't already exist,
	      // create it.  If @name is invalid, return the unnamedRegister.
	      getRegister: function(name) {
	        if (!this.isValidRegister(name)) {
	          return this.unnamedRegister;
	        }
	        name = name.toLowerCase();
	        if (!this.registers[name]) {
	          this.registers[name] = new Register();
	        }
	        return this.registers[name];
	      },
	      isValidRegister: function(name) {
	        return name && inArray(name, validRegisters);
	      },
	      shiftNumericRegisters_: function() {
	        for (var i = 9; i >= 2; i--) {
	          this.registers[i] = this.getRegister('' + (i - 1));
	        }
	      }
	    };
	    function HistoryController() {
	        this.historyBuffer = [];
	        this.iterator = 0;
	        this.initialPrefix = null;
	    }
	    HistoryController.prototype = {
	      // the input argument here acts a user entered prefix for a small time
	      // until we start autocompletion in which case it is the autocompleted.
	      nextMatch: function (input, up) {
	        var historyBuffer = this.historyBuffer;
	        var dir = up ? -1 : 1;
	        if (this.initialPrefix === null) this.initialPrefix = input;
	        for (var i = this.iterator + dir; up ? i >= 0 : i < historyBuffer.length; i+= dir) {
	          var element = historyBuffer[i];
	          for (var j = 0; j <= element.length; j++) {
	            if (this.initialPrefix == element.substring(0, j)) {
	              this.iterator = i;
	              return element;
	            }
	          }
	        }
	        // should return the user input in case we reach the end of buffer.
	        if (i >= historyBuffer.length) {
	          this.iterator = historyBuffer.length;
	          return this.initialPrefix;
	        }
	        // return the last autocompleted query or exCommand as it is.
	        if (i < 0 ) return input;
	      },
	      pushInput: function(input) {
	        var index = this.historyBuffer.indexOf(input);
	        if (index > -1) this.historyBuffer.splice(index, 1);
	        if (input.length) this.historyBuffer.push(input);
	      },
	      reset: function() {
	        this.initialPrefix = null;
	        this.iterator = this.historyBuffer.length;
	      }
	    };
	    var commandDispatcher = {
	      matchCommand: function(keys, keyMap, inputState, context) {
	        var matches = commandMatches(keys, keyMap, context, inputState);
	        if (!matches.full && !matches.partial) {
	          return {type: 'none'};
	        } else if (!matches.full && matches.partial) {
	          return {type: 'partial'};
	        }
	
	        var bestMatch;
	        for (var i = 0; i < matches.full.length; i++) {
	          var match = matches.full[i];
	          if (!bestMatch) {
	            bestMatch = match;
	          }
	        }
	        if (bestMatch.keys.slice(-11) == '<character>') {
	          var character = lastChar(keys);
	          if (!character) return {type: 'none'};
	          inputState.selectedCharacter = character;
	        }
	        return {type: 'full', command: bestMatch};
	      },
	      processCommand: function(cm, vim, command) {
	        vim.inputState.repeatOverride = command.repeatOverride;
	        switch (command.type) {
	          case 'motion':
	            this.processMotion(cm, vim, command);
	            break;
	          case 'operator':
	            this.processOperator(cm, vim, command);
	            break;
	          case 'operatorMotion':
	            this.processOperatorMotion(cm, vim, command);
	            break;
	          case 'action':
	            this.processAction(cm, vim, command);
	            break;
	          case 'search':
	            this.processSearch(cm, vim, command);
	            break;
	          case 'ex':
	          case 'keyToEx':
	            this.processEx(cm, vim, command);
	            break;
	          default:
	            break;
	        }
	      },
	      processMotion: function(cm, vim, command) {
	        vim.inputState.motion = command.motion;
	        vim.inputState.motionArgs = copyArgs(command.motionArgs);
	        this.evalInput(cm, vim);
	      },
	      processOperator: function(cm, vim, command) {
	        var inputState = vim.inputState;
	        if (inputState.operator) {
	          if (inputState.operator == command.operator) {
	            // Typing an operator twice like 'dd' makes the operator operate
	            // linewise
	            inputState.motion = 'expandToLine';
	            inputState.motionArgs = { linewise: true };
	            this.evalInput(cm, vim);
	            return;
	          } else {
	            // 2 different operators in a row doesn't make sense.
	            clearInputState(cm);
	          }
	        }
	        inputState.operator = command.operator;
	        inputState.operatorArgs = copyArgs(command.operatorArgs);
	        if (vim.visualMode) {
	          // Operating on a selection in visual mode. We don't need a motion.
	          this.evalInput(cm, vim);
	        }
	      },
	      processOperatorMotion: function(cm, vim, command) {
	        var visualMode = vim.visualMode;
	        var operatorMotionArgs = copyArgs(command.operatorMotionArgs);
	        if (operatorMotionArgs) {
	          // Operator motions may have special behavior in visual mode.
	          if (visualMode && operatorMotionArgs.visualLine) {
	            vim.visualLine = true;
	          }
	        }
	        this.processOperator(cm, vim, command);
	        if (!visualMode) {
	          this.processMotion(cm, vim, command);
	        }
	      },
	      processAction: function(cm, vim, command) {
	        var inputState = vim.inputState;
	        var repeat = inputState.getRepeat();
	        var repeatIsExplicit = !!repeat;
	        var actionArgs = copyArgs(command.actionArgs) || {};
	        if (inputState.selectedCharacter) {
	          actionArgs.selectedCharacter = inputState.selectedCharacter;
	        }
	        // Actions may or may not have motions and operators. Do these first.
	        if (command.operator) {
	          this.processOperator(cm, vim, command);
	        }
	        if (command.motion) {
	          this.processMotion(cm, vim, command);
	        }
	        if (command.motion || command.operator) {
	          this.evalInput(cm, vim);
	        }
	        actionArgs.repeat = repeat || 1;
	        actionArgs.repeatIsExplicit = repeatIsExplicit;
	        actionArgs.registerName = inputState.registerName;
	        clearInputState(cm);
	        vim.lastMotion = null;
	        if (command.isEdit) {
	          this.recordLastEdit(vim, inputState, command);
	        }
	        actions[command.action](cm, actionArgs, vim);
	      },
	      processSearch: function(cm, vim, command) {
	        if (!cm.getSearchCursor) {
	          // Search depends on SearchCursor.
	          return;
	        }
	        var forward = command.searchArgs.forward;
	        var wholeWordOnly = command.searchArgs.wholeWordOnly;
	        getSearchState(cm).setReversed(!forward);
	        var promptPrefix = (forward) ? '/' : '?';
	        var originalQuery = getSearchState(cm).getQuery();
	        var originalScrollPos = cm.getScrollInfo();
	        function handleQuery(query, ignoreCase, smartCase) {
	          vimGlobalState.searchHistoryController.pushInput(query);
	          vimGlobalState.searchHistoryController.reset();
	          try {
	            updateSearchQuery(cm, query, ignoreCase, smartCase);
	          } catch (e) {
	            showConfirm(cm, 'Invalid regex: ' + query);
	            clearInputState(cm);
	            return;
	          }
	          commandDispatcher.processMotion(cm, vim, {
	            type: 'motion',
	            motion: 'findNext',
	            motionArgs: { forward: true, toJumplist: command.searchArgs.toJumplist }
	          });
	        }
	        function onPromptClose(query) {
	          cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
	          handleQuery(query, true /** ignoreCase */, true /** smartCase */);
	          var macroModeState = vimGlobalState.macroModeState;
	          if (macroModeState.isRecording) {
	            logSearchQuery(macroModeState, query);
	          }
	        }
	        function onPromptKeyUp(e, query, close) {
	          var keyName = CodeMirror.keyName(e), up, offset;
	          if (keyName == 'Up' || keyName == 'Down') {
	            up = keyName == 'Up' ? true : false;
	            offset = e.target ? e.target.selectionEnd : 0;
	            query = vimGlobalState.searchHistoryController.nextMatch(query, up) || '';
	            close(query);
	            if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);
	          } else {
	            if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift')
	              vimGlobalState.searchHistoryController.reset();
	          }
	          var parsedQuery;
	          try {
	            parsedQuery = updateSearchQuery(cm, query,
	                true /** ignoreCase */, true /** smartCase */);
	          } catch (e) {
	            // Swallow bad regexes for incremental search.
	          }
	          if (parsedQuery) {
	            cm.scrollIntoView(findNext(cm, !forward, parsedQuery), 30);
	          } else {
	            clearSearchHighlight(cm);
	            cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
	          }
	        }
	        function onPromptKeyDown(e, query, close) {
	          var keyName = CodeMirror.keyName(e);
	          if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' ||
	              (keyName == 'Backspace' && query == '')) {
	            vimGlobalState.searchHistoryController.pushInput(query);
	            vimGlobalState.searchHistoryController.reset();
	            updateSearchQuery(cm, originalQuery);
	            clearSearchHighlight(cm);
	            cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
	            CodeMirror.e_stop(e);
	            clearInputState(cm);
	            close();
	            cm.focus();
	          } else if (keyName == 'Up' || keyName == 'Down') {
	            CodeMirror.e_stop(e);
	          } else if (keyName == 'Ctrl-U') {
	            // Ctrl-U clears input.
	            CodeMirror.e_stop(e);
	            close('');
	          }
	        }
	        switch (command.searchArgs.querySrc) {
	          case 'prompt':
	            var macroModeState = vimGlobalState.macroModeState;
	            if (macroModeState.isPlaying) {
	              var query = macroModeState.replaySearchQueries.shift();
	              handleQuery(query, true /** ignoreCase */, false /** smartCase */);
	            } else {
	              showPrompt(cm, {
	                  onClose: onPromptClose,
	                  prefix: promptPrefix,
	                  desc: searchPromptDesc,
	                  onKeyUp: onPromptKeyUp,
	                  onKeyDown: onPromptKeyDown
	              });
	            }
	            break;
	          case 'wordUnderCursor':
	            var word = expandWordUnderCursor(cm, false /** inclusive */,
	                true /** forward */, false /** bigWord */,
	                true /** noSymbol */);
	            var isKeyword = true;
	            if (!word) {
	              word = expandWordUnderCursor(cm, false /** inclusive */,
	                  true /** forward */, false /** bigWord */,
	                  false /** noSymbol */);
	              isKeyword = false;
	            }
	            if (!word) {
	              return;
	            }
	            var query = cm.getLine(word.start.line).substring(word.start.ch,
	                word.end.ch);
	            if (isKeyword && wholeWordOnly) {
	                query = '\\b' + query + '\\b';
	            } else {
	              query = escapeRegex(query);
	            }
	
	            // cachedCursor is used to save the old position of the cursor
	            // when * or # causes vim to seek for the nearest word and shift
	            // the cursor before entering the motion.
	            vimGlobalState.jumpList.cachedCursor = cm.getCursor();
	            cm.setCursor(word.start);
	
	            handleQuery(query, true /** ignoreCase */, false /** smartCase */);
	            break;
	        }
	      },
	      processEx: function(cm, vim, command) {
	        function onPromptClose(input) {
	          // Give the prompt some time to close so that if processCommand shows
	          // an error, the elements don't overlap.
	          vimGlobalState.exCommandHistoryController.pushInput(input);
	          vimGlobalState.exCommandHistoryController.reset();
	          exCommandDispatcher.processCommand(cm, input);
	        }
	        function onPromptKeyDown(e, input, close) {
	          var keyName = CodeMirror.keyName(e), up, offset;
	          if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' ||
	              (keyName == 'Backspace' && input == '')) {
	            vimGlobalState.exCommandHistoryController.pushInput(input);
	            vimGlobalState.exCommandHistoryController.reset();
	            CodeMirror.e_stop(e);
	            clearInputState(cm);
	            close();
	            cm.focus();
	          }
	          if (keyName == 'Up' || keyName == 'Down') {
	            CodeMirror.e_stop(e);
	            up = keyName == 'Up' ? true : false;
	            offset = e.target ? e.target.selectionEnd : 0;
	            input = vimGlobalState.exCommandHistoryController.nextMatch(input, up) || '';
	            close(input);
	            if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);
	          } else if (keyName == 'Ctrl-U') {
	            // Ctrl-U clears input.
	            CodeMirror.e_stop(e);
	            close('');
	          } else {
	            if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift')
	              vimGlobalState.exCommandHistoryController.reset();
	          }
	        }
	        if (command.type == 'keyToEx') {
	          // Handle user defined Ex to Ex mappings
	          exCommandDispatcher.processCommand(cm, command.exArgs.input);
	        } else {
	          if (vim.visualMode) {
	            showPrompt(cm, { onClose: onPromptClose, prefix: ':', value: '\'<,\'>',
	                onKeyDown: onPromptKeyDown});
	          } else {
	            showPrompt(cm, { onClose: onPromptClose, prefix: ':',
	                onKeyDown: onPromptKeyDown});
	          }
	        }
	      },
	      evalInput: function(cm, vim) {
	        // If the motion command is set, execute both the operator and motion.
	        // Otherwise return.
	        var inputState = vim.inputState;
	        var motion = inputState.motion;
	        var motionArgs = inputState.motionArgs || {};
	        var operator = inputState.operator;
	        var operatorArgs = inputState.operatorArgs || {};
	        var registerName = inputState.registerName;
	        var sel = vim.sel;
	        // TODO: Make sure cm and vim selections are identical outside visual mode.
	        var origHead = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.head): cm.getCursor('head'));
	        var origAnchor = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.anchor) : cm.getCursor('anchor'));
	        var oldHead = copyCursor(origHead);
	        var oldAnchor = copyCursor(origAnchor);
	        var newHead, newAnchor;
	        var repeat;
	        if (operator) {
	          this.recordLastEdit(vim, inputState);
	        }
	        if (inputState.repeatOverride !== undefined) {
	          // If repeatOverride is specified, that takes precedence over the
	          // input state's repeat. Used by Ex mode and can be user defined.
	          repeat = inputState.repeatOverride;
	        } else {
	          repeat = inputState.getRepeat();
	        }
	        if (repeat > 0 && motionArgs.explicitRepeat) {
	          motionArgs.repeatIsExplicit = true;
	        } else if (motionArgs.noRepeat ||
	            (!motionArgs.explicitRepeat && repeat === 0)) {
	          repeat = 1;
	          motionArgs.repeatIsExplicit = false;
	        }
	        if (inputState.selectedCharacter) {
	          // If there is a character input, stick it in all of the arg arrays.
	          motionArgs.selectedCharacter = operatorArgs.selectedCharacter =
	              inputState.selectedCharacter;
	        }
	        motionArgs.repeat = repeat;
	        clearInputState(cm);
	        if (motion) {
	          var motionResult = motions[motion](cm, origHead, motionArgs, vim);
	          vim.lastMotion = motions[motion];
	          if (!motionResult) {
	            return;
	          }
	          if (motionArgs.toJumplist) {
	            var jumpList = vimGlobalState.jumpList;
	            // if the current motion is # or *, use cachedCursor
	            var cachedCursor = jumpList.cachedCursor;
	            if (cachedCursor) {
	              recordJumpPosition(cm, cachedCursor, motionResult);
	              delete jumpList.cachedCursor;
	            } else {
	              recordJumpPosition(cm, origHead, motionResult);
	            }
	          }
	          if (motionResult instanceof Array) {
	            newAnchor = motionResult[0];
	            newHead = motionResult[1];
	          } else {
	            newHead = motionResult;
	          }
	          // TODO: Handle null returns from motion commands better.
	          if (!newHead) {
	            newHead = copyCursor(origHead);
	          }
	          if (vim.visualMode) {
	            if (!(vim.visualBlock && newHead.ch === Infinity)) {
	              newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
	            }
	            if (newAnchor) {
	              newAnchor = clipCursorToContent(cm, newAnchor, true);
	            }
	            newAnchor = newAnchor || oldAnchor;
	            sel.anchor = newAnchor;
	            sel.head = newHead;
	            updateCmSelection(cm);
	            updateMark(cm, vim, '<',
	                cursorIsBefore(newAnchor, newHead) ? newAnchor
	                    : newHead);
	            updateMark(cm, vim, '>',
	                cursorIsBefore(newAnchor, newHead) ? newHead
	                    : newAnchor);
	          } else if (!operator) {
	            newHead = clipCursorToContent(cm, newHead);
	            cm.setCursor(newHead.line, newHead.ch);
	          }
	        }
	        if (operator) {
	          if (operatorArgs.lastSel) {
	            // Replaying a visual mode operation
	            newAnchor = oldAnchor;
	            var lastSel = operatorArgs.lastSel;
	            var lineOffset = Math.abs(lastSel.head.line - lastSel.anchor.line);
	            var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch);
	            if (lastSel.visualLine) {
	              // Linewise Visual mode: The same number of lines.
	              newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch);
	            } else if (lastSel.visualBlock) {
	              // Blockwise Visual mode: The same number of lines and columns.
	              newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset);
	            } else if (lastSel.head.line == lastSel.anchor.line) {
	              // Normal Visual mode within one line: The same number of characters.
	              newHead = Pos(oldAnchor.line, oldAnchor.ch + chOffset);
	            } else {
	              // Normal Visual mode with several lines: The same number of lines, in the
	              // last line the same number of characters as in the last line the last time.
	              newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch);
	            }
	            vim.visualMode = true;
	            vim.visualLine = lastSel.visualLine;
	            vim.visualBlock = lastSel.visualBlock;
	            sel = vim.sel = {
	              anchor: newAnchor,
	              head: newHead
	            };
	            updateCmSelection(cm);
	          } else if (vim.visualMode) {
	            operatorArgs.lastSel = {
	              anchor: copyCursor(sel.anchor),
	              head: copyCursor(sel.head),
	              visualBlock: vim.visualBlock,
	              visualLine: vim.visualLine
	            };
	          }
	          var curStart, curEnd, linewise, mode;
	          var cmSel;
	          if (vim.visualMode) {
	            // Init visual op
	            curStart = cursorMin(sel.head, sel.anchor);
	            curEnd = cursorMax(sel.head, sel.anchor);
	            linewise = vim.visualLine || operatorArgs.linewise;
	            mode = vim.visualBlock ? 'block' :
	                   linewise ? 'line' :
	                   'char';
	            cmSel = makeCmSelection(cm, {
	              anchor: curStart,
	              head: curEnd
	            }, mode);
	            if (linewise) {
	              var ranges = cmSel.ranges;
	              if (mode == 'block') {
	                // Linewise operators in visual block mode extend to end of line
	                for (var i = 0; i < ranges.length; i++) {
	                  ranges[i].head.ch = lineLength(cm, ranges[i].head.line);
	                }
	              } else if (mode == 'line') {
	                ranges[0].head = Pos(ranges[0].head.line + 1, 0);
	              }
	            }
	          } else {
	            // Init motion op
	            curStart = copyCursor(newAnchor || oldAnchor);
	            curEnd = copyCursor(newHead || oldHead);
	            if (cursorIsBefore(curEnd, curStart)) {
	              var tmp = curStart;
	              curStart = curEnd;
	              curEnd = tmp;
	            }
	            linewise = motionArgs.linewise || operatorArgs.linewise;
	            if (linewise) {
	              // Expand selection to entire line.
	              expandSelectionToLine(cm, curStart, curEnd);
	            } else if (motionArgs.forward) {
	              // Clip to trailing newlines only if the motion goes forward.
	              clipToLine(cm, curStart, curEnd);
	            }
	            mode = 'char';
	            var exclusive = !motionArgs.inclusive || linewise;
	            cmSel = makeCmSelection(cm, {
	              anchor: curStart,
	              head: curEnd
	            }, mode, exclusive);
	          }
	          cm.setSelections(cmSel.ranges, cmSel.primary);
	          vim.lastMotion = null;
	          operatorArgs.repeat = repeat; // For indent in visual mode.
	          operatorArgs.registerName = registerName;
	          // Keep track of linewise as it affects how paste and change behave.
	          operatorArgs.linewise = linewise;
	          var operatorMoveTo = operators[operator](
	            cm, operatorArgs, cmSel.ranges, oldAnchor, newHead);
	          if (vim.visualMode) {
	            exitVisualMode(cm, operatorMoveTo != null);
	          }
	          if (operatorMoveTo) {
	            cm.setCursor(operatorMoveTo);
	          }
	        }
	      },
	      recordLastEdit: function(vim, inputState, actionCommand) {
	        var macroModeState = vimGlobalState.macroModeState;
	        if (macroModeState.isPlaying) { return; }
	        vim.lastEditInputState = inputState;
	        vim.lastEditActionCommand = actionCommand;
	        macroModeState.lastInsertModeChanges.changes = [];
	        macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false;
	      }
	    };
	
	    /**
	     * typedef {Object{line:number,ch:number}} Cursor An object containing the
	     *     position of the cursor.
	     */
	    // All of the functions below return Cursor objects.
	    var motions = {
	      moveToTopLine: function(cm, _head, motionArgs) {
	        var line = getUserVisibleLines(cm).top + motionArgs.repeat -1;
	        return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
	      },
	      moveToMiddleLine: function(cm) {
	        var range = getUserVisibleLines(cm);
	        var line = Math.floor((range.top + range.bottom) * 0.5);
	        return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
	      },
	      moveToBottomLine: function(cm, _head, motionArgs) {
	        var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1;
	        return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
	      },
	      expandToLine: function(_cm, head, motionArgs) {
	        // Expands forward to end of line, and then to next line if repeat is
	        // >1. Does not handle backward motion!
	        var cur = head;
	        return Pos(cur.line + motionArgs.repeat - 1, Infinity);
	      },
	      findNext: function(cm, _head, motionArgs) {
	        var state = getSearchState(cm);
	        var query = state.getQuery();
	        if (!query) {
	          return;
	        }
	        var prev = !motionArgs.forward;
	        // If search is initiated with ? instead of /, negate direction.
	        prev = (state.isReversed()) ? !prev : prev;
	        highlightSearchMatches(cm, query);
	        return findNext(cm, prev/** prev */, query, motionArgs.repeat);
	      },
	      goToMark: function(cm, _head, motionArgs, vim) {
	        var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter);
	        if (pos) {
	          return motionArgs.linewise ? { line: pos.line, ch: findFirstNonWhiteSpaceCharacter(cm.getLine(pos.line)) } : pos;
	        }
	        return null;
	      },
	      moveToOtherHighlightedEnd: function(cm, _head, motionArgs, vim) {
	        if (vim.visualBlock && motionArgs.sameLine) {
	          var sel = vim.sel;
	          return [
	            clipCursorToContent(cm, Pos(sel.anchor.line, sel.head.ch)),
	            clipCursorToContent(cm, Pos(sel.head.line, sel.anchor.ch))
	          ];
	        } else {
	          return ([vim.sel.head, vim.sel.anchor]);
	        }
	      },
	      jumpToMark: function(cm, head, motionArgs, vim) {
	        var best = head;
	        for (var i = 0; i < motionArgs.repeat; i++) {
	          var cursor = best;
	          for (var key in vim.marks) {
	            if (!isLowerCase(key)) {
	              continue;
	            }
	            var mark = vim.marks[key].find();
	            var isWrongDirection = (motionArgs.forward) ?
	              cursorIsBefore(mark, cursor) : cursorIsBefore(cursor, mark);
	
	            if (isWrongDirection) {
	              continue;
	            }
	            if (motionArgs.linewise && (mark.line == cursor.line)) {
	              continue;
	            }
	
	            var equal = cursorEqual(cursor, best);
	            var between = (motionArgs.forward) ?
	              cursorIsBetween(cursor, mark, best) :
	              cursorIsBetween(best, mark, cursor);
	
	            if (equal || between) {
	              best = mark;
	            }
	          }
	        }
	
	        if (motionArgs.linewise) {
	          // Vim places the cursor on the first non-whitespace character of
	          // the line if there is one, else it places the cursor at the end
	          // of the line, regardless of whether a mark was found.
	          best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line)));
	        }
	        return best;
	      },
	      moveByCharacters: function(_cm, head, motionArgs) {
	        var cur = head;
	        var repeat = motionArgs.repeat;
	        var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat;
	        return Pos(cur.line, ch);
	      },
	      moveByLines: function(cm, head, motionArgs, vim) {
	        var cur = head;
	        var endCh = cur.ch;
	        // Depending what our last motion was, we may want to do different
	        // things. If our last motion was moving vertically, we want to
	        // preserve the HPos from our last horizontal move.  If our last motion
	        // was going to the end of a line, moving vertically we should go to
	        // the end of the line, etc.
	        switch (vim.lastMotion) {
	          case this.moveByLines:
	          case this.moveByDisplayLines:
	          case this.moveByScroll:
	          case this.moveToColumn:
	          case this.moveToEol:
	            endCh = vim.lastHPos;
	            break;
	          default:
	            vim.lastHPos = endCh;
	        }
	        var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0);
	        var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat;
	        var first = cm.firstLine();
	        var last = cm.lastLine();
	        // Vim go to line begin or line end when cursor at first/last line and
	        // move to previous/next line is triggered.
	        if (line < first && cur.line == first){
	          return this.moveToStartOfLine(cm, head, motionArgs, vim);
	        }else if (line > last && cur.line == last){
	            return this.moveToEol(cm, head, motionArgs, vim);
	        }
	        if (motionArgs.toFirstChar){
	          endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
	          vim.lastHPos = endCh;
	        }
	        vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left;
	        return Pos(line, endCh);
	      },
	      moveByDisplayLines: function(cm, head, motionArgs, vim) {
	        var cur = head;
	        switch (vim.lastMotion) {
	          case this.moveByDisplayLines:
	          case this.moveByScroll:
	          case this.moveByLines:
	          case this.moveToColumn:
	          case this.moveToEol:
	            break;
	          default:
	            vim.lastHSPos = cm.charCoords(cur,'div').left;
	        }
	        var repeat = motionArgs.repeat;
	        var res=cm.findPosV(cur,(motionArgs.forward ? repeat : -repeat),'line',vim.lastHSPos);
	        if (res.hitSide) {
	          if (motionArgs.forward) {
	            var lastCharCoords = cm.charCoords(res, 'div');
	            var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos };
	            var res = cm.coordsChar(goalCoords, 'div');
	          } else {
	            var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div');
	            resCoords.left = vim.lastHSPos;
	            res = cm.coordsChar(resCoords, 'div');
	          }
	        }
	        vim.lastHPos = res.ch;
	        return res;
	      },
	      moveByPage: function(cm, head, motionArgs) {
	        // CodeMirror only exposes functions that move the cursor page down, so
	        // doing this bad hack to move the cursor and move it back. evalInput
	        // will move the cursor to where it should be in the end.
	        var curStart = head;
	        var repeat = motionArgs.repeat;
	        return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page');
	      },
	      moveByParagraph: function(cm, head, motionArgs) {
	        var dir = motionArgs.forward ? 1 : -1;
	        return findParagraph(cm, head, motionArgs.repeat, dir);
	      },
	      moveByScroll: function(cm, head, motionArgs, vim) {
	        var scrollbox = cm.getScrollInfo();
	        var curEnd = null;
	        var repeat = motionArgs.repeat;
	        if (!repeat) {
	          repeat = scrollbox.clientHeight / (2 * cm.defaultTextHeight());
	        }
	        var orig = cm.charCoords(head, 'local');
	        motionArgs.repeat = repeat;
	        var curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim);
	        if (!curEnd) {
	          return null;
	        }
	        var dest = cm.charCoords(curEnd, 'local');
	        cm.scrollTo(null, scrollbox.top + dest.top - orig.top);
	        return curEnd;
	      },
	      moveByWords: function(cm, head, motionArgs) {
	        return moveToWord(cm, head, motionArgs.repeat, !!motionArgs.forward,
	            !!motionArgs.wordEnd, !!motionArgs.bigWord);
	      },
	      moveTillCharacter: function(cm, _head, motionArgs) {
	        var repeat = motionArgs.repeat;
	        var curEnd = moveToCharacter(cm, repeat, motionArgs.forward,
	            motionArgs.selectedCharacter);
	        var increment = motionArgs.forward ? -1 : 1;
	        recordLastCharacterSearch(increment, motionArgs);
	        if (!curEnd) return null;
	        curEnd.ch += increment;
	        return curEnd;
	      },
	      moveToCharacter: function(cm, head, motionArgs) {
	        var repeat = motionArgs.repeat;
	        recordLastCharacterSearch(0, motionArgs);
	        return moveToCharacter(cm, repeat, motionArgs.forward,
	            motionArgs.selectedCharacter) || head;
	      },
	      moveToSymbol: function(cm, head, motionArgs) {
	        var repeat = motionArgs.repeat;
	        return findSymbol(cm, repeat, motionArgs.forward,
	            motionArgs.selectedCharacter) || head;
	      },
	      moveToColumn: function(cm, head, motionArgs, vim) {
	        var repeat = motionArgs.repeat;
	        // repeat is equivalent to which column we want to move to!
	        vim.lastHPos = repeat - 1;
	        vim.lastHSPos = cm.charCoords(head,'div').left;
	        return moveToColumn(cm, repeat);
	      },
	      moveToEol: function(cm, head, motionArgs, vim) {
	        var cur = head;
	        vim.lastHPos = Infinity;
	        var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
	        var end=cm.clipPos(retval);
	        end.ch--;
	        vim.lastHSPos = cm.charCoords(end,'div').left;
	        return retval;
	      },
	      moveToFirstNonWhiteSpaceCharacter: function(cm, head) {
	        // Go to the start of the line where the text begins, or the end for
	        // whitespace-only lines
	        var cursor = head;
	        return Pos(cursor.line,
	                   findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line)));
	      },
	      moveToMatchedSymbol: function(cm, head) {
	        var cursor = head;
	        var line = cursor.line;
	        var ch = cursor.ch;
	        var lineText = cm.getLine(line);
	        var symbol;
	        for (; ch < lineText.length; ch++) {
	          symbol = lineText.charAt(ch);
	          if (symbol && isMatchableSymbol(symbol)) {
	            var style = cm.getTokenTypeAt(Pos(line, ch + 1));
	            if (style !== "string" && style !== "comment") {
	              break;
	            }
	          }
	        }
	        if (ch < lineText.length) {
	          var matched = cm.findMatchingBracket(Pos(line, ch));
	          return matched.to;
	        } else {
	          return cursor;
	        }
	      },
	      moveToStartOfLine: function(_cm, head) {
	        return Pos(head.line, 0);
	      },
	      moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) {
	        var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine();
	        if (motionArgs.repeatIsExplicit) {
	          lineNum = motionArgs.repeat - cm.getOption('firstLineNumber');
	        }
	        return Pos(lineNum,
	                   findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum)));
	      },
	      textObjectManipulation: function(cm, head, motionArgs, vim) {
	        // TODO: lots of possible exceptions that can be thrown here. Try da(
	        //     outside of a () block.
	
	        // TODO: adding <> >< to this map doesn't work, presumably because
	        // they're operators
	        var mirroredPairs = {'(': ')', ')': '(',
	                             '{': '}', '}': '{',
	                             '[': ']', ']': '['};
	        var selfPaired = {'\'': true, '"': true};
	
	        var character = motionArgs.selectedCharacter;
	        // 'b' refers to  '()' block.
	        // 'B' refers to  '{}' block.
	        if (character == 'b') {
	          character = '(';
	        } else if (character == 'B') {
	          character = '{';
	        }
	
	        // Inclusive is the difference between a and i
	        // TODO: Instead of using the additional text object map to perform text
	        //     object operations, merge the map into the defaultKeyMap and use
	        //     motionArgs to define behavior. Define separate entries for 'aw',
	        //     'iw', 'a[', 'i[', etc.
	        var inclusive = !motionArgs.textObjectInner;
	
	        var tmp;
	        if (mirroredPairs[character]) {
	          tmp = selectCompanionObject(cm, head, character, inclusive);
	        } else if (selfPaired[character]) {
	          tmp = findBeginningAndEnd(cm, head, character, inclusive);
	        } else if (character === 'W') {
	          tmp = expandWordUnderCursor(cm, inclusive, true /** forward */,
	                                                     true /** bigWord */);
	        } else if (character === 'w') {
	          tmp = expandWordUnderCursor(cm, inclusive, true /** forward */,
	                                                     false /** bigWord */);
	        } else if (character === 'p') {
	          tmp = findParagraph(cm, head, motionArgs.repeat, 0, inclusive);
	          motionArgs.linewise = true;
	          if (vim.visualMode) {
	            if (!vim.visualLine) { vim.visualLine = true; }
	          } else {
	            var operatorArgs = vim.inputState.operatorArgs;
	            if (operatorArgs) { operatorArgs.linewise = true; }
	            tmp.end.line--;
	          }
	        } else {
	          // No text object defined for this, don't move.
	          return null;
	        }
	
	        if (!cm.state.vim.visualMode) {
	          return [tmp.start, tmp.end];
	        } else {
	          return expandSelection(cm, tmp.start, tmp.end);
	        }
	      },
	
	      repeatLastCharacterSearch: function(cm, head, motionArgs) {
	        var lastSearch = vimGlobalState.lastCharacterSearch;
	        var repeat = motionArgs.repeat;
	        var forward = motionArgs.forward === lastSearch.forward;
	        var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1);
	        cm.moveH(-increment, 'char');
	        motionArgs.inclusive = forward ? true : false;
	        var curEnd = moveToCharacter(cm, repeat, forward, lastSearch.selectedCharacter);
	        if (!curEnd) {
	          cm.moveH(increment, 'char');
	          return head;
	        }
	        curEnd.ch += increment;
	        return curEnd;
	      }
	    };
	
	    function defineMotion(name, fn) {
	      motions[name] = fn;
	    }
	
	    function fillArray(val, times) {
	      var arr = [];
	      for (var i = 0; i < times; i++) {
	        arr.push(val);
	      }
	      return arr;
	    }
	    /**
	     * An operator acts on a text selection. It receives the list of selections
	     * as input. The corresponding CodeMirror selection is guaranteed to
	    * match the input selection.
	     */
	    var operators = {
	      change: function(cm, args, ranges) {
	        var finalHead, text;
	        var vim = cm.state.vim;
	        vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock = vim.visualBlock;
	        if (!vim.visualMode) {
	          var anchor = ranges[0].anchor,
	              head = ranges[0].head;
	          text = cm.getRange(anchor, head);
	          var lastState = vim.lastEditInputState || {};
	          if (lastState.motion == "moveByWords" && !isWhiteSpaceString(text)) {
	            // Exclude trailing whitespace if the range is not all whitespace.
	            var match = (/\s+$/).exec(text);
	            if (match && lastState.motionArgs && lastState.motionArgs.forward) {
	              head = offsetCursor(head, 0, - match[0].length);
	              text = text.slice(0, - match[0].length);
	            }
	          }
	          var prevLineEnd = new Pos(anchor.line - 1, Number.MAX_VALUE);
	          var wasLastLine = cm.firstLine() == cm.lastLine();
	          if (head.line > cm.lastLine() && args.linewise && !wasLastLine) {
	            cm.replaceRange('', prevLineEnd, head);
	          } else {
	            cm.replaceRange('', anchor, head);
	          }
	          if (args.linewise) {
	            // Push the next line back down, if there is a next line.
	            if (!wasLastLine) {
	              cm.setCursor(prevLineEnd);
	              CodeMirror.commands.newlineAndIndent(cm);
	            }
	            // make sure cursor ends up at the end of the line.
	            anchor.ch = Number.MAX_VALUE;
	          }
	          finalHead = anchor;
	        } else {
	          text = cm.getSelection();
	          var replacement = fillArray('', ranges.length);
	          cm.replaceSelections(replacement);
	          finalHead = cursorMin(ranges[0].head, ranges[0].anchor);
	        }
	        vimGlobalState.registerController.pushText(
	            args.registerName, 'change', text,
	            args.linewise, ranges.length > 1);
	        actions.enterInsertMode(cm, {head: finalHead}, cm.state.vim);
	      },
	      // delete is a javascript keyword.
	      'delete': function(cm, args, ranges) {
	        var finalHead, text;
	        var vim = cm.state.vim;
	        if (!vim.visualBlock) {
	          var anchor = ranges[0].anchor,
	              head = ranges[0].head;
	          if (args.linewise &&
	              head.line != cm.firstLine() &&
	              anchor.line == cm.lastLine() &&
	              anchor.line == head.line - 1) {
	            // Special case for dd on last line (and first line).
	            if (anchor.line == cm.firstLine()) {
	              anchor.ch = 0;
	            } else {
	              anchor = Pos(anchor.line - 1, lineLength(cm, anchor.line - 1));
	            }
	          }
	          text = cm.getRange(anchor, head);
	          cm.replaceRange('', anchor, head);
	          finalHead = anchor;
	          if (args.linewise) {
	            finalHead = motions.moveToFirstNonWhiteSpaceCharacter(cm, anchor);
	          }
	        } else {
	          text = cm.getSelection();
	          var replacement = fillArray('', ranges.length);
	          cm.replaceSelections(replacement);
	          finalHead = ranges[0].anchor;
	        }
	        vimGlobalState.registerController.pushText(
	            args.registerName, 'delete', text,
	            args.linewise, vim.visualBlock);
	        return clipCursorToContent(cm, finalHead);
	      },
	      indent: function(cm, args, ranges) {
	        var vim = cm.state.vim;
	        var startLine = ranges[0].anchor.line;
	        var endLine = vim.visualBlock ?
	          ranges[ranges.length - 1].anchor.line :
	          ranges[0].head.line;
	        // In visual mode, n> shifts the selection right n times, instead of
	        // shifting n lines right once.
	        var repeat = (vim.visualMode) ? args.repeat : 1;
	        if (args.linewise) {
	          // The only way to delete a newline is to delete until the start of
	          // the next line, so in linewise mode evalInput will include the next
	          // line. We don't want this in indent, so we go back a line.
	          endLine--;
	        }
	        for (var i = startLine; i <= endLine; i++) {
	          for (var j = 0; j < repeat; j++) {
	            cm.indentLine(i, args.indentRight);
	          }
	        }
	        return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor);
	      },
	      changeCase: function(cm, args, ranges, oldAnchor, newHead) {
	        var selections = cm.getSelections();
	        var swapped = [];
	        var toLower = args.toLower;
	        for (var j = 0; j < selections.length; j++) {
	          var toSwap = selections[j];
	          var text = '';
	          if (toLower === true) {
	            text = toSwap.toLowerCase();
	          } else if (toLower === false) {
	            text = toSwap.toUpperCase();
	          } else {
	            for (var i = 0; i < toSwap.length; i++) {
	              var character = toSwap.charAt(i);
	              text += isUpperCase(character) ? character.toLowerCase() :
	                  character.toUpperCase();
	            }
	          }
	          swapped.push(text);
	        }
	        cm.replaceSelections(swapped);
	        if (args.shouldMoveCursor){
	          return newHead;
	        } else if (!cm.state.vim.visualMode && args.linewise && ranges[0].anchor.line + 1 == ranges[0].head.line) {
	          return motions.moveToFirstNonWhiteSpaceCharacter(cm, oldAnchor);
	        } else if (args.linewise){
	          return oldAnchor;
	        } else {
	          return cursorMin(ranges[0].anchor, ranges[0].head);
	        }
	      },
	      yank: function(cm, args, ranges, oldAnchor) {
	        var vim = cm.state.vim;
	        var text = cm.getSelection();
	        var endPos = vim.visualMode
	          ? cursorMin(vim.sel.anchor, vim.sel.head, ranges[0].head, ranges[0].anchor)
	          : oldAnchor;
	        vimGlobalState.registerController.pushText(
	            args.registerName, 'yank',
	            text, args.linewise, vim.visualBlock);
	        return endPos;
	      }
	    };
	
	    function defineOperator(name, fn) {
	      operators[name] = fn;
	    }
	
	    var actions = {
	      jumpListWalk: function(cm, actionArgs, vim) {
	        if (vim.visualMode) {
	          return;
	        }
	        var repeat = actionArgs.repeat;
	        var forward = actionArgs.forward;
	        var jumpList = vimGlobalState.jumpList;
	
	        var mark = jumpList.move(cm, forward ? repeat : -repeat);
	        var markPos = mark ? mark.find() : undefined;
	        markPos = markPos ? markPos : cm.getCursor();
	        cm.setCursor(markPos);
	      },
	      scroll: function(cm, actionArgs, vim) {
	        if (vim.visualMode) {
	          return;
	        }
	        var repeat = actionArgs.repeat || 1;
	        var lineHeight = cm.defaultTextHeight();
	        var top = cm.getScrollInfo().top;
	        var delta = lineHeight * repeat;
	        var newPos = actionArgs.forward ? top + delta : top - delta;
	        var cursor = copyCursor(cm.getCursor());
	        var cursorCoords = cm.charCoords(cursor, 'local');
	        if (actionArgs.forward) {
	          if (newPos > cursorCoords.top) {
	             cursor.line += (newPos - cursorCoords.top) / lineHeight;
	             cursor.line = Math.ceil(cursor.line);
	             cm.setCursor(cursor);
	             cursorCoords = cm.charCoords(cursor, 'local');
	             cm.scrollTo(null, cursorCoords.top);
	          } else {
	             // Cursor stays within bounds.  Just reposition the scroll window.
	             cm.scrollTo(null, newPos);
	          }
	        } else {
	          var newBottom = newPos + cm.getScrollInfo().clientHeight;
	          if (newBottom < cursorCoords.bottom) {
	             cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight;
	             cursor.line = Math.floor(cursor.line);
	             cm.setCursor(cursor);
	             cursorCoords = cm.charCoords(cursor, 'local');
	             cm.scrollTo(
	                 null, cursorCoords.bottom - cm.getScrollInfo().clientHeight);
	          } else {
	             // Cursor stays within bounds.  Just reposition the scroll window.
	             cm.scrollTo(null, newPos);
	          }
	        }
	      },
	      scrollToCursor: function(cm, actionArgs) {
	        var lineNum = cm.getCursor().line;
	        var charCoords = cm.charCoords(Pos(lineNum, 0), 'local');
	        var height = cm.getScrollInfo().clientHeight;
	        var y = charCoords.top;
	        var lineHeight = charCoords.bottom - y;
	        switch (actionArgs.position) {
	          case 'center': y = y - (height / 2) + lineHeight;
	            break;
	          case 'bottom': y = y - height + lineHeight;
	            break;
	        }
	        cm.scrollTo(null, y);
	      },
	      replayMacro: function(cm, actionArgs, vim) {
	        var registerName = actionArgs.selectedCharacter;
	        var repeat = actionArgs.repeat;
	        var macroModeState = vimGlobalState.macroModeState;
	        if (registerName == '@') {
	          registerName = macroModeState.latestRegister;
	        }
	        while(repeat--){
	          executeMacroRegister(cm, vim, macroModeState, registerName);
	        }
	      },
	      enterMacroRecordMode: function(cm, actionArgs) {
	        var macroModeState = vimGlobalState.macroModeState;
	        var registerName = actionArgs.selectedCharacter;
	        if (vimGlobalState.registerController.isValidRegister(registerName)) {
	          macroModeState.enterMacroRecordMode(cm, registerName);
	        }
	      },
	      toggleOverwrite: function(cm) {
	        if (!cm.state.overwrite) {
	          cm.toggleOverwrite(true);
	          cm.setOption('keyMap', 'vim-replace');
	          CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"});
	        } else {
	          cm.toggleOverwrite(false);
	          cm.setOption('keyMap', 'vim-insert');
	          CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"});
	        }
	      },
	      enterInsertMode: function(cm, actionArgs, vim) {
	        if (cm.getOption('readOnly')) { return; }
	        vim.insertMode = true;
	        vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1;
	        var insertAt = (actionArgs) ? actionArgs.insertAt : null;
	        var sel = vim.sel;
	        var head = actionArgs.head || cm.getCursor('head');
	        var height = cm.listSelections().length;
	        if (insertAt == 'eol') {
	          head = Pos(head.line, lineLength(cm, head.line));
	        } else if (insertAt == 'charAfter') {
	          head = offsetCursor(head, 0, 1);
	        } else if (insertAt == 'firstNonBlank') {
	          head = motions.moveToFirstNonWhiteSpaceCharacter(cm, head);
	        } else if (insertAt == 'startOfSelectedArea') {
	          if (!vim.visualBlock) {
	            if (sel.head.line < sel.anchor.line) {
	              head = sel.head;
	            } else {
	              head = Pos(sel.anchor.line, 0);
	            }
	          } else {
	            head = Pos(
	                Math.min(sel.head.line, sel.anchor.line),
	                Math.min(sel.head.ch, sel.anchor.ch));
	            height = Math.abs(sel.head.line - sel.anchor.line) + 1;
	          }
	        } else if (insertAt == 'endOfSelectedArea') {
	          if (!vim.visualBlock) {
	            if (sel.head.line >= sel.anchor.line) {
	              head = offsetCursor(sel.head, 0, 1);
	            } else {
	              head = Pos(sel.anchor.line, 0);
	            }
	          } else {
	            head = Pos(
	                Math.min(sel.head.line, sel.anchor.line),
	                Math.max(sel.head.ch + 1, sel.anchor.ch));
	            height = Math.abs(sel.head.line - sel.anchor.line) + 1;
	          }
	        } else if (insertAt == 'inplace') {
	          if (vim.visualMode){
	            return;
	          }
	        }
	        cm.setOption('disableInput', false);
	        if (actionArgs && actionArgs.replace) {
	          // Handle Replace-mode as a special case of insert mode.
	          cm.toggleOverwrite(true);
	          cm.setOption('keyMap', 'vim-replace');
	          CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"});
	        } else {
	          cm.toggleOverwrite(false);
	          cm.setOption('keyMap', 'vim-insert');
	          CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"});
	        }
	        if (!vimGlobalState.macroModeState.isPlaying) {
	          // Only record if not replaying.
	          cm.on('change', onChange);
	          CodeMirror.on(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);
	        }
	        if (vim.visualMode) {
	          exitVisualMode(cm);
	        }
	        selectForInsert(cm, head, height);
	      },
	      toggleVisualMode: function(cm, actionArgs, vim) {
	        var repeat = actionArgs.repeat;
	        var anchor = cm.getCursor();
	        var head;
	        // TODO: The repeat should actually select number of characters/lines
	        //     equal to the repeat times the size of the previous visual
	        //     operation.
	        if (!vim.visualMode) {
	          // Entering visual mode
	          vim.visualMode = true;
	          vim.visualLine = !!actionArgs.linewise;
	          vim.visualBlock = !!actionArgs.blockwise;
	          head = clipCursorToContent(
	              cm, Pos(anchor.line, anchor.ch + repeat - 1),
	              true /** includeLineBreak */);
	          vim.sel = {
	            anchor: anchor,
	            head: head
	          };
	          CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""});
	          updateCmSelection(cm);
	          updateMark(cm, vim, '<', cursorMin(anchor, head));
	          updateMark(cm, vim, '>', cursorMax(anchor, head));
	        } else if (vim.visualLine ^ actionArgs.linewise ||
	            vim.visualBlock ^ actionArgs.blockwise) {
	          // Toggling between modes
	          vim.visualLine = !!actionArgs.linewise;
	          vim.visualBlock = !!actionArgs.blockwise;
	          CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""});
	          updateCmSelection(cm);
	        } else {
	          exitVisualMode(cm);
	        }
	      },
	      reselectLastSelection: function(cm, _actionArgs, vim) {
	        var lastSelection = vim.lastSelection;
	        if (vim.visualMode) {
	          updateLastSelection(cm, vim);
	        }
	        if (lastSelection) {
	          var anchor = lastSelection.anchorMark.find();
	          var head = lastSelection.headMark.find();
	          if (!anchor || !head) {
	            // If the marks have been destroyed due to edits, do nothing.
	            return;
	          }
	          vim.sel = {
	            anchor: anchor,
	            head: head
	          };
	          vim.visualMode = true;
	          vim.visualLine = lastSelection.visualLine;
	          vim.visualBlock = lastSelection.visualBlock;
	          updateCmSelection(cm);
	          updateMark(cm, vim, '<', cursorMin(anchor, head));
	          updateMark(cm, vim, '>', cursorMax(anchor, head));
	          CodeMirror.signal(cm, 'vim-mode-change', {
	            mode: 'visual',
	            subMode: vim.visualLine ? 'linewise' :
	                     vim.visualBlock ? 'blockwise' : ''});
	        }
	      },
	      joinLines: function(cm, actionArgs, vim) {
	        var curStart, curEnd;
	        if (vim.visualMode) {
	          curStart = cm.getCursor('anchor');
	          curEnd = cm.getCursor('head');
	          if (cursorIsBefore(curEnd, curStart)) {
	            var tmp = curEnd;
	            curEnd = curStart;
	            curStart = tmp;
	          }
	          curEnd.ch = lineLength(cm, curEnd.line) - 1;
	        } else {
	          // Repeat is the number of lines to join. Minimum 2 lines.
	          var repeat = Math.max(actionArgs.repeat, 2);
	          curStart = cm.getCursor();
	          curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1,
	                                               Infinity));
	        }
	        var finalCh = 0;
	        for (var i = curStart.line; i < curEnd.line; i++) {
	          finalCh = lineLength(cm, curStart.line);
	          var tmp = Pos(curStart.line + 1,
	                        lineLength(cm, curStart.line + 1));
	          var text = cm.getRange(curStart, tmp);
	          text = text.replace(/\n\s*/g, ' ');
	          cm.replaceRange(text, curStart, tmp);
	        }
	        var curFinalPos = Pos(curStart.line, finalCh);
	        if (vim.visualMode) {
	          exitVisualMode(cm, false);
	        }
	        cm.setCursor(curFinalPos);
	      },
	      newLineAndEnterInsertMode: function(cm, actionArgs, vim) {
	        vim.insertMode = true;
	        var insertAt = copyCursor(cm.getCursor());
	        if (insertAt.line === cm.firstLine() && !actionArgs.after) {
	          // Special case for inserting newline before start of document.
	          cm.replaceRange('\n', Pos(cm.firstLine(), 0));
	          cm.setCursor(cm.firstLine(), 0);
	        } else {
	          insertAt.line = (actionArgs.after) ? insertAt.line :
	              insertAt.line - 1;
	          insertAt.ch = lineLength(cm, insertAt.line);
	          cm.setCursor(insertAt);
	          var newlineFn = CodeMirror.commands.newlineAndIndentContinueComment ||
	              CodeMirror.commands.newlineAndIndent;
	          newlineFn(cm);
	        }
	        this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim);
	      },
	      paste: function(cm, actionArgs, vim) {
	        var cur = copyCursor(cm.getCursor());
	        var register = vimGlobalState.registerController.getRegister(
	            actionArgs.registerName);
	        var text = register.toString();
	        if (!text) {
	          return;
	        }
	        if (actionArgs.matchIndent) {
	          var tabSize = cm.getOption("tabSize");
	          // length that considers tabs and tabSize
	          var whitespaceLength = function(str) {
	            var tabs = (str.split("\t").length - 1);
	            var spaces = (str.split(" ").length - 1);
	            return tabs * tabSize + spaces * 1;
	          };
	          var currentLine = cm.getLine(cm.getCursor().line);
	          var indent = whitespaceLength(currentLine.match(/^\s*/)[0]);
	          // chomp last newline b/c don't want it to match /^\s*/gm
	          var chompedText = text.replace(/\n$/, '');
	          var wasChomped = text !== chompedText;
	          var firstIndent = whitespaceLength(text.match(/^\s*/)[0]);
	          var text = chompedText.replace(/^\s*/gm, function(wspace) {
	            var newIndent = indent + (whitespaceLength(wspace) - firstIndent);
	            if (newIndent < 0) {
	              return "";
	            }
	            else if (cm.getOption("indentWithTabs")) {
	              var quotient = Math.floor(newIndent / tabSize);
	              return Array(quotient + 1).join('\t');
	            }
	            else {
	              return Array(newIndent + 1).join(' ');
	            }
	          });
	          text += wasChomped ? "\n" : "";
	        }
	        if (actionArgs.repeat > 1) {
	          var text = Array(actionArgs.repeat + 1).join(text);
	        }
	        var linewise = register.linewise;
	        var blockwise = register.blockwise;
	        if (linewise) {
	          if(vim.visualMode) {
	            text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n';
	          } else if (actionArgs.after) {
	            // Move the newline at the end to the start instead, and paste just
	            // before the newline character of the line we are on right now.
	            text = '\n' + text.slice(0, text.length - 1);
	            cur.ch = lineLength(cm, cur.line);
	          } else {
	            cur.ch = 0;
	          }
	        } else {
	          if (blockwise) {
	            text = text.split('\n');
	            for (var i = 0; i < text.length; i++) {
	              text[i] = (text[i] == '') ? ' ' : text[i];
	            }
	          }
	          cur.ch += actionArgs.after ? 1 : 0;
	        }
	        var curPosFinal;
	        var idx;
	        if (vim.visualMode) {
	          //  save the pasted text for reselection if the need arises
	          vim.lastPastedText = text;
	          var lastSelectionCurEnd;
	          var selectedArea = getSelectedAreaRange(cm, vim);
	          var selectionStart = selectedArea[0];
	          var selectionEnd = selectedArea[1];
	          var selectedText = cm.getSelection();
	          var selections = cm.listSelections();
	          var emptyStrings = new Array(selections.length).join('1').split('1');
	          // save the curEnd marker before it get cleared due to cm.replaceRange.
	          if (vim.lastSelection) {
	            lastSelectionCurEnd = vim.lastSelection.headMark.find();
	          }
	          // push the previously selected text to unnamed register
	          vimGlobalState.registerController.unnamedRegister.setText(selectedText);
	          if (blockwise) {
	            // first delete the selected text
	            cm.replaceSelections(emptyStrings);
	            // Set new selections as per the block length of the yanked text
	            selectionEnd = Pos(selectionStart.line + text.length-1, selectionStart.ch);
	            cm.setCursor(selectionStart);
	            selectBlock(cm, selectionEnd);
	            cm.replaceSelections(text);
	            curPosFinal = selectionStart;
	          } else if (vim.visualBlock) {
	            cm.replaceSelections(emptyStrings);
	            cm.setCursor(selectionStart);
	            cm.replaceRange(text, selectionStart, selectionStart);
	            curPosFinal = selectionStart;
	          } else {
	            cm.replaceRange(text, selectionStart, selectionEnd);
	            curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1);
	          }
	          // restore the the curEnd marker
	          if(lastSelectionCurEnd) {
	            vim.lastSelection.headMark = cm.setBookmark(lastSelectionCurEnd);
	          }
	          if (linewise) {
	            curPosFinal.ch=0;
	          }
	        } else {
	          if (blockwise) {
	            cm.setCursor(cur);
	            for (var i = 0; i < text.length; i++) {
	              var line = cur.line+i;
	              if (line > cm.lastLine()) {
	                cm.replaceRange('\n',  Pos(line, 0));
	              }
	              var lastCh = lineLength(cm, line);
	              if (lastCh < cur.ch) {
	                extendLineToColumn(cm, line, cur.ch);
	              }
	            }
	            cm.setCursor(cur);
	            selectBlock(cm, Pos(cur.line + text.length-1, cur.ch));
	            cm.replaceSelections(text);
	            curPosFinal = cur;
	          } else {
	            cm.replaceRange(text, cur);
	            // Now fine tune the cursor to where we want it.
	            if (linewise && actionArgs.after) {
	              curPosFinal = Pos(
	              cur.line + 1,
	              findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1)));
	            } else if (linewise && !actionArgs.after) {
	              curPosFinal = Pos(
	                cur.line,
	                findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line)));
	            } else if (!linewise && actionArgs.after) {
	              idx = cm.indexFromPos(cur);
	              curPosFinal = cm.posFromIndex(idx + text.length - 1);
	            } else {
	              idx = cm.indexFromPos(cur);
	              curPosFinal = cm.posFromIndex(idx + text.length);
	            }
	          }
	        }
	        if (vim.visualMode) {
	          exitVisualMode(cm, false);
	        }
	        cm.setCursor(curPosFinal);
	      },
	      undo: function(cm, actionArgs) {
	        cm.operation(function() {
	          repeatFn(cm, CodeMirror.commands.undo, actionArgs.repeat)();
	          cm.setCursor(cm.getCursor('anchor'));
	        });
	      },
	      redo: function(cm, actionArgs) {
	        repeatFn(cm, CodeMirror.commands.redo, actionArgs.repeat)();
	      },
	      setRegister: function(_cm, actionArgs, vim) {
	        vim.inputState.registerName = actionArgs.selectedCharacter;
	      },
	      setMark: function(cm, actionArgs, vim) {
	        var markName = actionArgs.selectedCharacter;
	        updateMark(cm, vim, markName, cm.getCursor());
	      },
	      replace: function(cm, actionArgs, vim) {
	        var replaceWith = actionArgs.selectedCharacter;
	        var curStart = cm.getCursor();
	        var replaceTo;
	        var curEnd;
	        var selections = cm.listSelections();
	        if (vim.visualMode) {
	          curStart = cm.getCursor('start');
	          curEnd = cm.getCursor('end');
	        } else {
	          var line = cm.getLine(curStart.line);
	          replaceTo = curStart.ch + actionArgs.repeat;
	          if (replaceTo > line.length) {
	            replaceTo=line.length;
	          }
	          curEnd = Pos(curStart.line, replaceTo);
	        }
	        if (replaceWith=='\n') {
	          if (!vim.visualMode) cm.replaceRange('', curStart, curEnd);
	          // special case, where vim help says to replace by just one line-break
	          (CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm);
	        } else {
	          var replaceWithStr = cm.getRange(curStart, curEnd);
	          //replace all characters in range by selected, but keep linebreaks
	          replaceWithStr = replaceWithStr.replace(/[^\n]/g, replaceWith);
	          if (vim.visualBlock) {
	            // Tabs are split in visua block before replacing
	            var spaces = new Array(cm.getOption("tabSize")+1).join(' ');
	            replaceWithStr = cm.getSelection();
	            replaceWithStr = replaceWithStr.replace(/\t/g, spaces).replace(/[^\n]/g, replaceWith).split('\n');
	            cm.replaceSelections(replaceWithStr);
	          } else {
	            cm.replaceRange(replaceWithStr, curStart, curEnd);
	          }
	          if (vim.visualMode) {
	            curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ?
	                         selections[0].anchor : selections[0].head;
	            cm.setCursor(curStart);
	            exitVisualMode(cm, false);
	          } else {
	            cm.setCursor(offsetCursor(curEnd, 0, -1));
	          }
	        }
	      },
	      incrementNumberToken: function(cm, actionArgs) {
	        var cur = cm.getCursor();
	        var lineStr = cm.getLine(cur.line);
	        var re = /-?\d+/g;
	        var match;
	        var start;
	        var end;
	        var numberStr;
	        var token;
	        while ((match = re.exec(lineStr)) !== null) {
	          token = match[0];
	          start = match.index;
	          end = start + token.length;
	          if (cur.ch < end)break;
	        }
	        if (!actionArgs.backtrack && (end <= cur.ch))return;
	        if (token) {
	          var increment = actionArgs.increase ? 1 : -1;
	          var number = parseInt(token) + (increment * actionArgs.repeat);
	          var from = Pos(cur.line, start);
	          var to = Pos(cur.line, end);
	          numberStr = number.toString();
	          cm.replaceRange(numberStr, from, to);
	        } else {
	          return;
	        }
	        cm.setCursor(Pos(cur.line, start + numberStr.length - 1));
	      },
	      repeatLastEdit: function(cm, actionArgs, vim) {
	        var lastEditInputState = vim.lastEditInputState;
	        if (!lastEditInputState) { return; }
	        var repeat = actionArgs.repeat;
	        if (repeat && actionArgs.repeatIsExplicit) {
	          vim.lastEditInputState.repeatOverride = repeat;
	        } else {
	          repeat = vim.lastEditInputState.repeatOverride || repeat;
	        }
	        repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */);
	      },
	      indent: function(cm, actionArgs) {
	        cm.indentLine(cm.getCursor().line, actionArgs.indentRight);
	      },
	      exitInsertMode: exitInsertMode
	    };
	
	    function defineAction(name, fn) {
	      actions[name] = fn;
	    }
	
	    /*
	     * Below are miscellaneous utility functions used by vim.js
	     */
	
	    /**
	     * Clips cursor to ensure that line is within the buffer's range
	     * If includeLineBreak is true, then allow cur.ch == lineLength.
	     */
	    function clipCursorToContent(cm, cur, includeLineBreak) {
	      var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
	      var maxCh = lineLength(cm, line) - 1;
	      maxCh = (includeLineBreak) ? maxCh + 1 : maxCh;
	      var ch = Math.min(Math.max(0, cur.ch), maxCh);
	      return Pos(line, ch);
	    }
	    function copyArgs(args) {
	      var ret = {};
	      for (var prop in args) {
	        if (args.hasOwnProperty(prop)) {
	          ret[prop] = args[prop];
	        }
	      }
	      return ret;
	    }
	    function offsetCursor(cur, offsetLine, offsetCh) {
	      if (typeof offsetLine === 'object') {
	        offsetCh = offsetLine.ch;
	        offsetLine = offsetLine.line;
	      }
	      return Pos(cur.line + offsetLine, cur.ch + offsetCh);
	    }
	    function getOffset(anchor, head) {
	      return {
	        line: head.line - anchor.line,
	        ch: head.line - anchor.line
	      };
	    }
	    function commandMatches(keys, keyMap, context, inputState) {
	      // Partial matches are not applied. They inform the key handler
	      // that the current key sequence is a subsequence of a valid key
	      // sequence, so that the key buffer is not cleared.
	      var match, partial = [], full = [];
	      for (var i = 0; i < keyMap.length; i++) {
	        var command = keyMap[i];
	        if (context == 'insert' && command.context != 'insert' ||
	            command.context && command.context != context ||
	            inputState.operator && command.type == 'action' ||
	            !(match = commandMatch(keys, command.keys))) { continue; }
	        if (match == 'partial') { partial.push(command); }
	        if (match == 'full') { full.push(command); }
	      }
	      return {
	        partial: partial.length && partial,
	        full: full.length && full
	      };
	    }
	    function commandMatch(pressed, mapped) {
	      if (mapped.slice(-11) == '<character>') {
	        // Last character matches anything.
	        var prefixLen = mapped.length - 11;
	        var pressedPrefix = pressed.slice(0, prefixLen);
	        var mappedPrefix = mapped.slice(0, prefixLen);
	        return pressedPrefix == mappedPrefix && pressed.length > prefixLen ? 'full' :
	               mappedPrefix.indexOf(pressedPrefix) == 0 ? 'partial' : false;
	      } else {
	        return pressed == mapped ? 'full' :
	               mapped.indexOf(pressed) == 0 ? 'partial' : false;
	      }
	    }
	    function lastChar(keys) {
	      var match = /^.*(<[^>]+>)$/.exec(keys);
	      var selectedCharacter = match ? match[1] : keys.slice(-1);
	      if (selectedCharacter.length > 1){
	        switch(selectedCharacter){
	          case '<CR>':
	            selectedCharacter='\n';
	            break;
	          case '<Space>':
	            selectedCharacter=' ';
	            break;
	          default:
	            selectedCharacter='';
	            break;
	        }
	      }
	      return selectedCharacter;
	    }
	    function repeatFn(cm, fn, repeat) {
	      return function() {
	        for (var i = 0; i < repeat; i++) {
	          fn(cm);
	        }
	      };
	    }
	    function copyCursor(cur) {
	      return Pos(cur.line, cur.ch);
	    }
	    function cursorEqual(cur1, cur2) {
	      return cur1.ch == cur2.ch && cur1.line == cur2.line;
	    }
	    function cursorIsBefore(cur1, cur2) {
	      if (cur1.line < cur2.line) {
	        return true;
	      }
	      if (cur1.line == cur2.line && cur1.ch < cur2.ch) {
	        return true;
	      }
	      return false;
	    }
	    function cursorMin(cur1, cur2) {
	      if (arguments.length > 2) {
	        cur2 = cursorMin.apply(undefined, Array.prototype.slice.call(arguments, 1));
	      }
	      return cursorIsBefore(cur1, cur2) ? cur1 : cur2;
	    }
	    function cursorMax(cur1, cur2) {
	      if (arguments.length > 2) {
	        cur2 = cursorMax.apply(undefined, Array.prototype.slice.call(arguments, 1));
	      }
	      return cursorIsBefore(cur1, cur2) ? cur2 : cur1;
	    }
	    function cursorIsBetween(cur1, cur2, cur3) {
	      // returns true if cur2 is between cur1 and cur3.
	      var cur1before2 = cursorIsBefore(cur1, cur2);
	      var cur2before3 = cursorIsBefore(cur2, cur3);
	      return cur1before2 && cur2before3;
	    }
	    function lineLength(cm, lineNum) {
	      return cm.getLine(lineNum).length;
	    }
	    function trim(s) {
	      if (s.trim) {
	        return s.trim();
	      }
	      return s.replace(/^\s+|\s+$/g, '');
	    }
	    function escapeRegex(s) {
	      return s.replace(/([.?*+$\[\]\/\\(){}|\-])/g, '\\$1');
	    }
	    function extendLineToColumn(cm, lineNum, column) {
	      var endCh = lineLength(cm, lineNum);
	      var spaces = new Array(column-endCh+1).join(' ');
	      cm.setCursor(Pos(lineNum, endCh));
	      cm.replaceRange(spaces, cm.getCursor());
	    }
	    // This functions selects a rectangular block
	    // of text with selectionEnd as any of its corner
	    // Height of block:
	    // Difference in selectionEnd.line and first/last selection.line
	    // Width of the block:
	    // Distance between selectionEnd.ch and any(first considered here) selection.ch
	    function selectBlock(cm, selectionEnd) {
	      var selections = [], ranges = cm.listSelections();
	      var head = copyCursor(cm.clipPos(selectionEnd));
	      var isClipped = !cursorEqual(selectionEnd, head);
	      var curHead = cm.getCursor('head');
	      var primIndex = getIndex(ranges, curHead);
	      var wasClipped = cursorEqual(ranges[primIndex].head, ranges[primIndex].anchor);
	      var max = ranges.length - 1;
	      var index = max - primIndex > primIndex ? max : 0;
	      var base = ranges[index].anchor;
	
	      var firstLine = Math.min(base.line, head.line);
	      var lastLine = Math.max(base.line, head.line);
	      var baseCh = base.ch, headCh = head.ch;
	
	      var dir = ranges[index].head.ch - baseCh;
	      var newDir = headCh - baseCh;
	      if (dir > 0 && newDir <= 0) {
	        baseCh++;
	        if (!isClipped) { headCh--; }
	      } else if (dir < 0 && newDir >= 0) {
	        baseCh--;
	        if (!wasClipped) { headCh++; }
	      } else if (dir < 0 && newDir == -1) {
	        baseCh--;
	        headCh++;
	      }
	      for (var line = firstLine; line <= lastLine; line++) {
	        var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)};
	        selections.push(range);
	      }
	      cm.setSelections(selections);
	      selectionEnd.ch = headCh;
	      base.ch = baseCh;
	      return base;
	    }
	    function selectForInsert(cm, head, height) {
	      var sel = [];
	      for (var i = 0; i < height; i++) {
	        var lineHead = offsetCursor(head, i, 0);
	        sel.push({anchor: lineHead, head: lineHead});
	      }
	      cm.setSelections(sel, 0);
	    }
	    // getIndex returns the index of the cursor in the selections.
	    function getIndex(ranges, cursor, end) {
	      for (var i = 0; i < ranges.length; i++) {
	        var atAnchor = end != 'head' && cursorEqual(ranges[i].anchor, cursor);
	        var atHead = end != 'anchor' && cursorEqual(ranges[i].head, cursor);
	        if (atAnchor || atHead) {
	          return i;
	        }
	      }
	      return -1;
	    }
	    function getSelectedAreaRange(cm, vim) {
	      var lastSelection = vim.lastSelection;
	      var getCurrentSelectedAreaRange = function() {
	        var selections = cm.listSelections();
	        var start =  selections[0];
	        var end = selections[selections.length-1];
	        var selectionStart = cursorIsBefore(start.anchor, start.head) ? start.anchor : start.head;
	        var selectionEnd = cursorIsBefore(end.anchor, end.head) ? end.head : end.anchor;
	        return [selectionStart, selectionEnd];
	      };
	      var getLastSelectedAreaRange = function() {
	        var selectionStart = cm.getCursor();
	        var selectionEnd = cm.getCursor();
	        var block = lastSelection.visualBlock;
	        if (block) {
	          var width = block.width;
	          var height = block.height;
	          selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width);
	          var selections = [];
	          // selectBlock creates a 'proper' rectangular block.
	          // We do not want that in all cases, so we manually set selections.
	          for (var i = selectionStart.line; i < selectionEnd.line; i++) {
	            var anchor = Pos(i, selectionStart.ch);
	            var head = Pos(i, selectionEnd.ch);
	            var range = {anchor: anchor, head: head};
	            selections.push(range);
	          }
	          cm.setSelections(selections);
	        } else {
	          var start = lastSelection.anchorMark.find();
	          var end = lastSelection.headMark.find();
	          var line = end.line - start.line;
	          var ch = end.ch - start.ch;
	          selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch};
	          if (lastSelection.visualLine) {
	            selectionStart = Pos(selectionStart.line, 0);
	            selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line));
	          }
	          cm.setSelection(selectionStart, selectionEnd);
	        }
	        return [selectionStart, selectionEnd];
	      };
	      if (!vim.visualMode) {
	      // In case of replaying the action.
	        return getLastSelectedAreaRange();
	      } else {
	        return getCurrentSelectedAreaRange();
	      }
	    }
	    // Updates the previous selection with the current selection's values. This
	    // should only be called in visual mode.
	    function updateLastSelection(cm, vim) {
	      var anchor = vim.sel.anchor;
	      var head = vim.sel.head;
	      // To accommodate the effect of lastPastedText in the last selection
	      if (vim.lastPastedText) {
	        head = cm.posFromIndex(cm.indexFromPos(anchor) + vim.lastPastedText.length);
	        vim.lastPastedText = null;
	      }
	      vim.lastSelection = {'anchorMark': cm.setBookmark(anchor),
	                           'headMark': cm.setBookmark(head),
	                           'anchor': copyCursor(anchor),
	                           'head': copyCursor(head),
	                           'visualMode': vim.visualMode,
	                           'visualLine': vim.visualLine,
	                           'visualBlock': vim.visualBlock};
	    }
	    function expandSelection(cm, start, end) {
	      var sel = cm.state.vim.sel;
	      var head = sel.head;
	      var anchor = sel.anchor;
	      var tmp;
	      if (cursorIsBefore(end, start)) {
	        tmp = end;
	        end = start;
	        start = tmp;
	      }
	      if (cursorIsBefore(head, anchor)) {
	        head = cursorMin(start, head);
	        anchor = cursorMax(anchor, end);
	      } else {
	        anchor = cursorMin(start, anchor);
	        head = cursorMax(head, end);
	        head = offsetCursor(head, 0, -1);
	        if (head.ch == -1 && head.line != cm.firstLine()) {
	          head = Pos(head.line - 1, lineLength(cm, head.line - 1));
	        }
	      }
	      return [anchor, head];
	    }
	    /**
	     * Updates the CodeMirror selection to match the provided vim selection.
	     * If no arguments are given, it uses the current vim selection state.
	     */
	    function updateCmSelection(cm, sel, mode) {
	      var vim = cm.state.vim;
	      sel = sel || vim.sel;
	      var mode = mode ||
	        vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char';
	      var cmSel = makeCmSelection(cm, sel, mode);
	      cm.setSelections(cmSel.ranges, cmSel.primary);
	      updateFakeCursor(cm);
	    }
	    function makeCmSelection(cm, sel, mode, exclusive) {
	      var head = copyCursor(sel.head);
	      var anchor = copyCursor(sel.anchor);
	      if (mode == 'char') {
	        var headOffset = !exclusive && !cursorIsBefore(sel.head, sel.anchor) ? 1 : 0;
	        var anchorOffset = cursorIsBefore(sel.head, sel.anchor) ? 1 : 0;
	        head = offsetCursor(sel.head, 0, headOffset);
	        anchor = offsetCursor(sel.anchor, 0, anchorOffset);
	        return {
	          ranges: [{anchor: anchor, head: head}],
	          primary: 0
	        };
	      } else if (mode == 'line') {
	        if (!cursorIsBefore(sel.head, sel.anchor)) {
	          anchor.ch = 0;
	
	          var lastLine = cm.lastLine();
	          if (head.line > lastLine) {
	            head.line = lastLine;
	          }
	          head.ch = lineLength(cm, head.line);
	        } else {
	          head.ch = 0;
	          anchor.ch = lineLength(cm, anchor.line);
	        }
	        return {
	          ranges: [{anchor: anchor, head: head}],
	          primary: 0
	        };
	      } else if (mode == 'block') {
	        var top = Math.min(anchor.line, head.line),
	            left = Math.min(anchor.ch, head.ch),
	            bottom = Math.max(anchor.line, head.line),
	            right = Math.max(anchor.ch, head.ch) + 1;
	        var height = bottom - top + 1;
	        var primary = head.line == top ? 0 : height - 1;
	        var ranges = [];
	        for (var i = 0; i < height; i++) {
	          ranges.push({
	            anchor: Pos(top + i, left),
	            head: Pos(top + i, right)
	          });
	        }
	        return {
	          ranges: ranges,
	          primary: primary
	        };
	      }
	    }
	    function getHead(cm) {
	      var cur = cm.getCursor('head');
	      if (cm.getSelection().length == 1) {
	        // Small corner case when only 1 character is selected. The "real"
	        // head is the left of head and anchor.
	        cur = cursorMin(cur, cm.getCursor('anchor'));
	      }
	      return cur;
	    }
	
	    /**
	     * If moveHead is set to false, the CodeMirror selection will not be
	     * touched. The caller assumes the responsibility of putting the cursor
	    * in the right place.
	     */
	    function exitVisualMode(cm, moveHead) {
	      var vim = cm.state.vim;
	      if (moveHead !== false) {
	        cm.setCursor(clipCursorToContent(cm, vim.sel.head));
	      }
	      updateLastSelection(cm, vim);
	      vim.visualMode = false;
	      vim.visualLine = false;
	      vim.visualBlock = false;
	      CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
	      if (vim.fakeCursor) {
	        vim.fakeCursor.clear();
	      }
	    }
	
	    // Remove any trailing newlines from the selection. For
	    // example, with the caret at the start of the last word on the line,
	    // 'dw' should word, but not the newline, while 'w' should advance the
	    // caret to the first character of the next line.
	    function clipToLine(cm, curStart, curEnd) {
	      var selection = cm.getRange(curStart, curEnd);
	      // Only clip if the selection ends with trailing newline + whitespace
	      if (/\n\s*$/.test(selection)) {
	        var lines = selection.split('\n');
	        // We know this is all whitespace.
	        lines.pop();
	
	        // Cases:
	        // 1. Last word is an empty line - do not clip the trailing '\n'
	        // 2. Last word is not an empty line - clip the trailing '\n'
	        var line;
	        // Find the line containing the last word, and clip all whitespace up
	        // to it.
	        for (var line = lines.pop(); lines.length > 0 && line && isWhiteSpaceString(line); line = lines.pop()) {
	          curEnd.line--;
	          curEnd.ch = 0;
	        }
	        // If the last word is not an empty line, clip an additional newline
	        if (line) {
	          curEnd.line--;
	          curEnd.ch = lineLength(cm, curEnd.line);
	        } else {
	          curEnd.ch = 0;
	        }
	      }
	    }
	
	    // Expand the selection to line ends.
	    function expandSelectionToLine(_cm, curStart, curEnd) {
	      curStart.ch = 0;
	      curEnd.ch = 0;
	      curEnd.line++;
	    }
	
	    function findFirstNonWhiteSpaceCharacter(text) {
	      if (!text) {
	        return 0;
	      }
	      var firstNonWS = text.search(/\S/);
	      return firstNonWS == -1 ? text.length : firstNonWS;
	    }
	
	    function expandWordUnderCursor(cm, inclusive, _forward, bigWord, noSymbol) {
	      var cur = getHead(cm);
	      var line = cm.getLine(cur.line);
	      var idx = cur.ch;
	
	      // Seek to first word or non-whitespace character, depending on if
	      // noSymbol is true.
	      var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0];
	      while (!test(line.charAt(idx))) {
	        idx++;
	        if (idx >= line.length) { return null; }
	      }
	
	      if (bigWord) {
	        test = bigWordCharTest[0];
	      } else {
	        test = wordCharTest[0];
	        if (!test(line.charAt(idx))) {
	          test = wordCharTest[1];
	        }
	      }
	
	      var end = idx, start = idx;
	      while (test(line.charAt(end)) && end < line.length) { end++; }
	      while (test(line.charAt(start)) && start >= 0) { start--; }
	      start++;
	
	      if (inclusive) {
	        // If present, include all whitespace after word.
	        // Otherwise, include all whitespace before word, except indentation.
	        var wordEnd = end;
	        while (/\s/.test(line.charAt(end)) && end < line.length) { end++; }
	        if (wordEnd == end) {
	          var wordStart = start;
	          while (/\s/.test(line.charAt(start - 1)) && start > 0) { start--; }
	          if (!start) { start = wordStart; }
	        }
	      }
	      return { start: Pos(cur.line, start), end: Pos(cur.line, end) };
	    }
	
	    function recordJumpPosition(cm, oldCur, newCur) {
	      if (!cursorEqual(oldCur, newCur)) {
	        vimGlobalState.jumpList.add(cm, oldCur, newCur);
	      }
	    }
	
	    function recordLastCharacterSearch(increment, args) {
	        vimGlobalState.lastCharacterSearch.increment = increment;
	        vimGlobalState.lastCharacterSearch.forward = args.forward;
	        vimGlobalState.lastCharacterSearch.selectedCharacter = args.selectedCharacter;
	    }
	
	    var symbolToMode = {
	        '(': 'bracket', ')': 'bracket', '{': 'bracket', '}': 'bracket',
	        '[': 'section', ']': 'section',
	        '*': 'comment', '/': 'comment',
	        'm': 'method', 'M': 'method',
	        '#': 'preprocess'
	    };
	    var findSymbolModes = {
	      bracket: {
	        isComplete: function(state) {
	          if (state.nextCh === state.symb) {
	            state.depth++;
	            if (state.depth >= 1)return true;
	          } else if (state.nextCh === state.reverseSymb) {
	            state.depth--;
	          }
	          return false;
	        }
	      },
	      section: {
	        init: function(state) {
	          state.curMoveThrough = true;
	          state.symb = (state.forward ? ']' : '[') === state.symb ? '{' : '}';
	        },
	        isComplete: function(state) {
	          return state.index === 0 && state.nextCh === state.symb;
	        }
	      },
	      comment: {
	        isComplete: function(state) {
	          var found = state.lastCh === '*' && state.nextCh === '/';
	          state.lastCh = state.nextCh;
	          return found;
	        }
	      },
	      // TODO: The original Vim implementation only operates on level 1 and 2.
	      // The current implementation doesn't check for code block level and
	      // therefore it operates on any levels.
	      method: {
	        init: function(state) {
	          state.symb = (state.symb === 'm' ? '{' : '}');
	          state.reverseSymb = state.symb === '{' ? '}' : '{';
	        },
	        isComplete: function(state) {
	          if (state.nextCh === state.symb)return true;
	          return false;
	        }
	      },
	      preprocess: {
	        init: function(state) {
	          state.index = 0;
	        },
	        isComplete: function(state) {
	          if (state.nextCh === '#') {
	            var token = state.lineText.match(/#(\w+)/)[1];
	            if (token === 'endif') {
	              if (state.forward && state.depth === 0) {
	                return true;
	              }
	              state.depth++;
	            } else if (token === 'if') {
	              if (!state.forward && state.depth === 0) {
	                return true;
	              }
	              state.depth--;
	            }
	            if (token === 'else' && state.depth === 0)return true;
	          }
	          return false;
	        }
	      }
	    };
	    function findSymbol(cm, repeat, forward, symb) {
	      var cur = copyCursor(cm.getCursor());
	      var increment = forward ? 1 : -1;
	      var endLine = forward ? cm.lineCount() : -1;
	      var curCh = cur.ch;
	      var line = cur.line;
	      var lineText = cm.getLine(line);
	      var state = {
	        lineText: lineText,
	        nextCh: lineText.charAt(curCh),
	        lastCh: null,
	        index: curCh,
	        symb: symb,
	        reverseSymb: (forward ?  { ')': '(', '}': '{' } : { '(': ')', '{': '}' })[symb],
	        forward: forward,
	        depth: 0,
	        curMoveThrough: false
	      };
	      var mode = symbolToMode[symb];
	      if (!mode)return cur;
	      var init = findSymbolModes[mode].init;
	      var isComplete = findSymbolModes[mode].isComplete;
	      if (init) { init(state); }
	      while (line !== endLine && repeat) {
	        state.index += increment;
	        state.nextCh = state.lineText.charAt(state.index);
	        if (!state.nextCh) {
	          line += increment;
	          state.lineText = cm.getLine(line) || '';
	          if (increment > 0) {
	            state.index = 0;
	          } else {
	            var lineLen = state.lineText.length;
	            state.index = (lineLen > 0) ? (lineLen-1) : 0;
	          }
	          state.nextCh = state.lineText.charAt(state.index);
	        }
	        if (isComplete(state)) {
	          cur.line = line;
	          cur.ch = state.index;
	          repeat--;
	        }
	      }
	      if (state.nextCh || state.curMoveThrough) {
	        return Pos(line, state.index);
	      }
	      return cur;
	    }
	
	    /**
	     * Returns the boundaries of the next word. If the cursor in the middle of
	     * the word, then returns the boundaries of the current word, starting at
	     * the cursor. If the cursor is at the start/end of a word, and we are going
	     * forward/backward, respectively, find the boundaries of the next word.
	     *
	     * @param {CodeMirror} cm CodeMirror object.
	     * @param {Cursor} cur The cursor position.
	     * @param {boolean} forward True to search forward. False to search
	     *     backward.
	     * @param {boolean} bigWord True if punctuation count as part of the word.
	     *     False if only [a-zA-Z0-9] characters count as part of the word.
	     * @param {boolean} emptyLineIsWord True if empty lines should be treated
	     *     as words.
	     * @return {Object{from:number, to:number, line: number}} The boundaries of
	     *     the word, or null if there are no more words.
	     */
	    function findWord(cm, cur, forward, bigWord, emptyLineIsWord) {
	      var lineNum = cur.line;
	      var pos = cur.ch;
	      var line = cm.getLine(lineNum);
	      var dir = forward ? 1 : -1;
	      var charTests = bigWord ? bigWordCharTest: wordCharTest;
	
	      if (emptyLineIsWord && line == '') {
	        lineNum += dir;
	        line = cm.getLine(lineNum);
	        if (!isLine(cm, lineNum)) {
	          return null;
	        }
	        pos = (forward) ? 0 : line.length;
	      }
	
	      while (true) {
	        if (emptyLineIsWord && line == '') {
	          return { from: 0, to: 0, line: lineNum };
	        }
	        var stop = (dir > 0) ? line.length : -1;
	        var wordStart = stop, wordEnd = stop;
	        // Find bounds of next word.
	        while (pos != stop) {
	          var foundWord = false;
	          for (var i = 0; i < charTests.length && !foundWord; ++i) {
	            if (charTests[i](line.charAt(pos))) {
	              wordStart = pos;
	              // Advance to end of word.
	              while (pos != stop && charTests[i](line.charAt(pos))) {
	                pos += dir;
	              }
	              wordEnd = pos;
	              foundWord = wordStart != wordEnd;
	              if (wordStart == cur.ch && lineNum == cur.line &&
	                  wordEnd == wordStart + dir) {
	                // We started at the end of a word. Find the next one.
	                continue;
	              } else {
	                return {
	                  from: Math.min(wordStart, wordEnd + 1),
	                  to: Math.max(wordStart, wordEnd),
	                  line: lineNum };
	              }
	            }
	          }
	          if (!foundWord) {
	            pos += dir;
	          }
	        }
	        // Advance to next/prev line.
	        lineNum += dir;
	        if (!isLine(cm, lineNum)) {
	          return null;
	        }
	        line = cm.getLine(lineNum);
	        pos = (dir > 0) ? 0 : line.length;
	      }
	    }
	
	    /**
	     * @param {CodeMirror} cm CodeMirror object.
	     * @param {Pos} cur The position to start from.
	     * @param {int} repeat Number of words to move past.
	     * @param {boolean} forward True to search forward. False to search
	     *     backward.
	     * @param {boolean} wordEnd True to move to end of word. False to move to
	     *     beginning of word.
	     * @param {boolean} bigWord True if punctuation count as part of the word.
	     *     False if only alphabet characters count as part of the word.
	     * @return {Cursor} The position the cursor should move to.
	     */
	    function moveToWord(cm, cur, repeat, forward, wordEnd, bigWord) {
	      var curStart = copyCursor(cur);
	      var words = [];
	      if (forward && !wordEnd || !forward && wordEnd) {
	        repeat++;
	      }
	      // For 'e', empty lines are not considered words, go figure.
	      var emptyLineIsWord = !(forward && wordEnd);
	      for (var i = 0; i < repeat; i++) {
	        var word = findWord(cm, cur, forward, bigWord, emptyLineIsWord);
	        if (!word) {
	          var eodCh = lineLength(cm, cm.lastLine());
	          words.push(forward
	              ? {line: cm.lastLine(), from: eodCh, to: eodCh}
	              : {line: 0, from: 0, to: 0});
	          break;
	        }
	        words.push(word);
	        cur = Pos(word.line, forward ? (word.to - 1) : word.from);
	      }
	      var shortCircuit = words.length != repeat;
	      var firstWord = words[0];
	      var lastWord = words.pop();
	      if (forward && !wordEnd) {
	        // w
	        if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) {
	          // We did not start in the middle of a word. Discard the extra word at the end.
	          lastWord = words.pop();
	        }
	        return Pos(lastWord.line, lastWord.from);
	      } else if (forward && wordEnd) {
	        return Pos(lastWord.line, lastWord.to - 1);
	      } else if (!forward && wordEnd) {
	        // ge
	        if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) {
	          // We did not start in the middle of a word. Discard the extra word at the end.
	          lastWord = words.pop();
	        }
	        return Pos(lastWord.line, lastWord.to);
	      } else {
	        // b
	        return Pos(lastWord.line, lastWord.from);
	      }
	    }
	
	    function moveToCharacter(cm, repeat, forward, character) {
	      var cur = cm.getCursor();
	      var start = cur.ch;
	      var idx;
	      for (var i = 0; i < repeat; i ++) {
	        var line = cm.getLine(cur.line);
	        idx = charIdxInLine(start, line, character, forward, true);
	        if (idx == -1) {
	          return null;
	        }
	        start = idx;
	      }
	      return Pos(cm.getCursor().line, idx);
	    }
	
	    function moveToColumn(cm, repeat) {
	      // repeat is always >= 1, so repeat - 1 always corresponds
	      // to the column we want to go to.
	      var line = cm.getCursor().line;
	      return clipCursorToContent(cm, Pos(line, repeat - 1));
	    }
	
	    function updateMark(cm, vim, markName, pos) {
	      if (!inArray(markName, validMarks)) {
	        return;
	      }
	      if (vim.marks[markName]) {
	        vim.marks[markName].clear();
	      }
	      vim.marks[markName] = cm.setBookmark(pos);
	    }
	
	    function charIdxInLine(start, line, character, forward, includeChar) {
	      // Search for char in line.
	      // motion_options: {forward, includeChar}
	      // If includeChar = true, include it too.
	      // If forward = true, search forward, else search backwards.
	      // If char is not found on this line, do nothing
	      var idx;
	      if (forward) {
	        idx = line.indexOf(character, start + 1);
	        if (idx != -1 && !includeChar) {
	          idx -= 1;
	        }
	      } else {
	        idx = line.lastIndexOf(character, start - 1);
	        if (idx != -1 && !includeChar) {
	          idx += 1;
	        }
	      }
	      return idx;
	    }
	
	    function findParagraph(cm, head, repeat, dir, inclusive) {
	      var line = head.line;
	      var min = cm.firstLine();
	      var max = cm.lastLine();
	      var start, end, i = line;
	      function isEmpty(i) { return !cm.getLine(i); }
	      function isBoundary(i, dir, any) {
	        if (any) { return isEmpty(i) != isEmpty(i + dir); }
	        return !isEmpty(i) && isEmpty(i + dir);
	      }
	      if (dir) {
	        while (min <= i && i <= max && repeat > 0) {
	          if (isBoundary(i, dir)) { repeat--; }
	          i += dir;
	        }
	        return new Pos(i, 0);
	      }
	
	      var vim = cm.state.vim;
	      if (vim.visualLine && isBoundary(line, 1, true)) {
	        var anchor = vim.sel.anchor;
	        if (isBoundary(anchor.line, -1, true)) {
	          if (!inclusive || anchor.line != line) {
	            line += 1;
	          }
	        }
	      }
	      var startState = isEmpty(line);
	      for (i = line; i <= max && repeat; i++) {
	        if (isBoundary(i, 1, true)) {
	          if (!inclusive || isEmpty(i) != startState) {
	            repeat--;
	          }
	        }
	      }
	      end = new Pos(i, 0);
	      // select boundary before paragraph for the last one
	      if (i > max && !startState) { startState = true; }
	      else { inclusive = false; }
	      for (i = line; i > min; i--) {
	        if (!inclusive || isEmpty(i) == startState || i == line) {
	          if (isBoundary(i, -1, true)) { break; }
	        }
	      }
	      start = new Pos(i, 0);
	      return { start: start, end: end };
	    }
	
	    // TODO: perhaps this finagling of start and end positions belonds
	    // in codemirror/replaceRange?
	    function selectCompanionObject(cm, head, symb, inclusive) {
	      var cur = head, start, end;
	
	      var bracketRegexp = ({
	        '(': /[()]/, ')': /[()]/,
	        '[': /[[\]]/, ']': /[[\]]/,
	        '{': /[{}]/, '}': /[{}]/})[symb];
	      var openSym = ({
	        '(': '(', ')': '(',
	        '[': '[', ']': '[',
	        '{': '{', '}': '{'})[symb];
	      var curChar = cm.getLine(cur.line).charAt(cur.ch);
	      // Due to the behavior of scanForBracket, we need to add an offset if the
	      // cursor is on a matching open bracket.
	      var offset = curChar === openSym ? 1 : 0;
	
	      start = cm.scanForBracket(Pos(cur.line, cur.ch + offset), -1, null, {'bracketRegex': bracketRegexp});
	      end = cm.scanForBracket(Pos(cur.line, cur.ch + offset), 1, null, {'bracketRegex': bracketRegexp});
	
	      if (!start || !end) {
	        return { start: cur, end: cur };
	      }
	
	      start = start.pos;
	      end = end.pos;
	
	      if ((start.line == end.line && start.ch > end.ch)
	          || (start.line > end.line)) {
	        var tmp = start;
	        start = end;
	        end = tmp;
	      }
	
	      if (inclusive) {
	        end.ch += 1;
	      } else {
	        start.ch += 1;
	      }
	
	      return { start: start, end: end };
	    }
	
	    // Takes in a symbol and a cursor and tries to simulate text objects that
	    // have identical opening and closing symbols
	    // TODO support across multiple lines
	    function findBeginningAndEnd(cm, head, symb, inclusive) {
	      var cur = copyCursor(head);
	      var line = cm.getLine(cur.line);
	      var chars = line.split('');
	      var start, end, i, len;
	      var firstIndex = chars.indexOf(symb);
	
	      // the decision tree is to always look backwards for the beginning first,
	      // but if the cursor is in front of the first instance of the symb,
	      // then move the cursor forward
	      if (cur.ch < firstIndex) {
	        cur.ch = firstIndex;
	        // Why is this line even here???
	        // cm.setCursor(cur.line, firstIndex+1);
	      }
	      // otherwise if the cursor is currently on the closing symbol
	      else if (firstIndex < cur.ch && chars[cur.ch] == symb) {
	        end = cur.ch; // assign end to the current cursor
	        --cur.ch; // make sure to look backwards
	      }
	
	      // if we're currently on the symbol, we've got a start
	      if (chars[cur.ch] == symb && !end) {
	        start = cur.ch + 1; // assign start to ahead of the cursor
	      } else {
	        // go backwards to find the start
	        for (i = cur.ch; i > -1 && !start; i--) {
	          if (chars[i] == symb) {
	            start = i + 1;
	          }
	        }
	      }
	
	      // look forwards for the end symbol
	      if (start && !end) {
	        for (i = start, len = chars.length; i < len && !end; i++) {
	          if (chars[i] == symb) {
	            end = i;
	          }
	        }
	      }
	
	      // nothing found
	      if (!start || !end) {
	        return { start: cur, end: cur };
	      }
	
	      // include the symbols
	      if (inclusive) {
	        --start; ++end;
	      }
	
	      return {
	        start: Pos(cur.line, start),
	        end: Pos(cur.line, end)
	      };
	    }
	
	    // Search functions
	    defineOption('pcre', true, 'boolean');
	    function SearchState() {}
	    SearchState.prototype = {
	      getQuery: function() {
	        return vimGlobalState.query;
	      },
	      setQuery: function(query) {
	        vimGlobalState.query = query;
	      },
	      getOverlay: function() {
	        return this.searchOverlay;
	      },
	      setOverlay: function(overlay) {
	        this.searchOverlay = overlay;
	      },
	      isReversed: function() {
	        return vimGlobalState.isReversed;
	      },
	      setReversed: function(reversed) {
	        vimGlobalState.isReversed = reversed;
	      },
	      getScrollbarAnnotate: function() {
	        return this.annotate;
	      },
	      setScrollbarAnnotate: function(annotate) {
	        this.annotate = annotate;
	      }
	    };
	    function getSearchState(cm) {
	      var vim = cm.state.vim;
	      return vim.searchState_ || (vim.searchState_ = new SearchState());
	    }
	    function dialog(cm, template, shortText, onClose, options) {
	      if (cm.openDialog) {
	        cm.openDialog(template, onClose, { bottom: true, value: options.value,
	            onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp,
	            selectValueOnOpen: false});
	      }
	      else {
	        onClose(prompt(shortText, ''));
	      }
	    }
	    function splitBySlash(argString) {
	      var slashes = findUnescapedSlashes(argString) || [];
	      if (!slashes.length) return [];
	      var tokens = [];
	      // in case of strings like foo/bar
	      if (slashes[0] !== 0) return;
	      for (var i = 0; i < slashes.length; i++) {
	        if (typeof slashes[i] == 'number')
	          tokens.push(argString.substring(slashes[i] + 1, slashes[i+1]));
	      }
	      return tokens;
	    }
	
	    function findUnescapedSlashes(str) {
	      var escapeNextChar = false;
	      var slashes = [];
	      for (var i = 0; i < str.length; i++) {
	        var c = str.charAt(i);
	        if (!escapeNextChar && c == '/') {
	          slashes.push(i);
	        }
	        escapeNextChar = !escapeNextChar && (c == '\\');
	      }
	      return slashes;
	    }
	
	    // Translates a search string from ex (vim) syntax into javascript form.
	    function translateRegex(str) {
	      // When these match, add a '\' if unescaped or remove one if escaped.
	      var specials = '|(){';
	      // Remove, but never add, a '\' for these.
	      var unescape = '}';
	      var escapeNextChar = false;
	      var out = [];
	      for (var i = -1; i < str.length; i++) {
	        var c = str.charAt(i) || '';
	        var n = str.charAt(i+1) || '';
	        var specialComesNext = (n && specials.indexOf(n) != -1);
	        if (escapeNextChar) {
	          if (c !== '\\' || !specialComesNext) {
	            out.push(c);
	          }
	          escapeNextChar = false;
	        } else {
	          if (c === '\\') {
	            escapeNextChar = true;
	            // Treat the unescape list as special for removing, but not adding '\'.
	            if (n && unescape.indexOf(n) != -1) {
	              specialComesNext = true;
	            }
	            // Not passing this test means removing a '\'.
	            if (!specialComesNext || n === '\\') {
	              out.push(c);
	            }
	          } else {
	            out.push(c);
	            if (specialComesNext && n !== '\\') {
	              out.push('\\');
	            }
	          }
	        }
	      }
	      return out.join('');
	    }
	
	    // Translates the replace part of a search and replace from ex (vim) syntax into
	    // javascript form.  Similar to translateRegex, but additionally fixes back references
	    // (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'.
	    var charUnescapes = {'\\n': '\n', '\\r': '\r', '\\t': '\t'};
	    function translateRegexReplace(str) {
	      var escapeNextChar = false;
	      var out = [];
	      for (var i = -1; i < str.length; i++) {
	        var c = str.charAt(i) || '';
	        var n = str.charAt(i+1) || '';
	        if (charUnescapes[c + n]) {
	          out.push(charUnescapes[c+n]);
	          i++;
	        } else if (escapeNextChar) {
	          // At any point in the loop, escapeNextChar is true if the previous
	          // character was a '\' and was not escaped.
	          out.push(c);
	          escapeNextChar = false;
	        } else {
	          if (c === '\\') {
	            escapeNextChar = true;
	            if ((isNumber(n) || n === '$')) {
	              out.push('$');
	            } else if (n !== '/' && n !== '\\') {
	              out.push('\\');
	            }
	          } else {
	            if (c === '$') {
	              out.push('$');
	            }
	            out.push(c);
	            if (n === '/') {
	              out.push('\\');
	            }
	          }
	        }
	      }
	      return out.join('');
	    }
	
	    // Unescape \ and / in the replace part, for PCRE mode.
	    var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'};
	    function unescapeRegexReplace(str) {
	      var stream = new CodeMirror.StringStream(str);
	      var output = [];
	      while (!stream.eol()) {
	        // Search for \.
	        while (stream.peek() && stream.peek() != '\\') {
	          output.push(stream.next());
	        }
	        var matched = false;
	        for (var matcher in unescapes) {
	          if (stream.match(matcher, true)) {
	            matched = true;
	            output.push(unescapes[matcher]);
	            break;
	          }
	        }
	        if (!matched) {
	          // Don't change anything
	          output.push(stream.next());
	        }
	      }
	      return output.join('');
	    }
	
	    /**
	     * Extract the regular expression from the query and return a Regexp object.
	     * Returns null if the query is blank.
	     * If ignoreCase is passed in, the Regexp object will have the 'i' flag set.
	     * If smartCase is passed in, and the query contains upper case letters,
	     *   then ignoreCase is overridden, and the 'i' flag will not be set.
	     * If the query contains the /i in the flag part of the regular expression,
	     *   then both ignoreCase and smartCase are ignored, and 'i' will be passed
	     *   through to the Regex object.
	     */
	    function parseQuery(query, ignoreCase, smartCase) {
	      // First update the last search register
	      var lastSearchRegister = vimGlobalState.registerController.getRegister('/');
	      lastSearchRegister.setText(query);
	      // Check if the query is already a regex.
	      if (query instanceof RegExp) { return query; }
	      // First try to extract regex + flags from the input. If no flags found,
	      // extract just the regex. IE does not accept flags directly defined in
	      // the regex string in the form /regex/flags
	      var slashes = findUnescapedSlashes(query);
	      var regexPart;
	      var forceIgnoreCase;
	      if (!slashes.length) {
	        // Query looks like 'regexp'
	        regexPart = query;
	      } else {
	        // Query looks like 'regexp/...'
	        regexPart = query.substring(0, slashes[0]);
	        var flagsPart = query.substring(slashes[0]);
	        forceIgnoreCase = (flagsPart.indexOf('i') != -1);
	      }
	      if (!regexPart) {
	        return null;
	      }
	      if (!getOption('pcre')) {
	        regexPart = translateRegex(regexPart);
	      }
	      if (smartCase) {
	        ignoreCase = (/^[^A-Z]*$/).test(regexPart);
	      }
	      var regexp = new RegExp(regexPart,
	          (ignoreCase || forceIgnoreCase) ? 'i' : undefined);
	      return regexp;
	    }
	    function showConfirm(cm, text) {
	      if (cm.openNotification) {
	        cm.openNotification('<span style="color: red">' + text + '</span>',
	                            {bottom: true, duration: 5000});
	      } else {
	        alert(text);
	      }
	    }
	    function makePrompt(prefix, desc) {
	      var raw = '<span style="font-family: monospace; white-space: pre">' +
	          (prefix || "") + '<input type="text"></span>';
	      if (desc)
	        raw += ' <span style="color: #888">' + desc + '</span>';
	      return raw;
	    }
	    var searchPromptDesc = '(Javascript regexp)';
	    function showPrompt(cm, options) {
	      var shortText = (options.prefix || '') + ' ' + (options.desc || '');
	      var prompt = makePrompt(options.prefix, options.desc);
	      dialog(cm, prompt, shortText, options.onClose, options);
	    }
	    function regexEqual(r1, r2) {
	      if (r1 instanceof RegExp && r2 instanceof RegExp) {
	          var props = ['global', 'multiline', 'ignoreCase', 'source'];
	          for (var i = 0; i < props.length; i++) {
	              var prop = props[i];
	              if (r1[prop] !== r2[prop]) {
	                  return false;
	              }
	          }
	          return true;
	      }
	      return false;
	    }
	    // Returns true if the query is valid.
	    function updateSearchQuery(cm, rawQuery, ignoreCase, smartCase) {
	      if (!rawQuery) {
	        return;
	      }
	      var state = getSearchState(cm);
	      var query = parseQuery(rawQuery, !!ignoreCase, !!smartCase);
	      if (!query) {
	        return;
	      }
	      highlightSearchMatches(cm, query);
	      if (regexEqual(query, state.getQuery())) {
	        return query;
	      }
	      state.setQuery(query);
	      return query;
	    }
	    function searchOverlay(query) {
	      if (query.source.charAt(0) == '^') {
	        var matchSol = true;
	      }
	      return {
	        token: function(stream) {
	          if (matchSol && !stream.sol()) {
	            stream.skipToEnd();
	            return;
	          }
	          var match = stream.match(query, false);
	          if (match) {
	            if (match[0].length == 0) {
	              // Matched empty string, skip to next.
	              stream.next();
	              return 'searching';
	            }
	            if (!stream.sol()) {
	              // Backtrack 1 to match \b
	              stream.backUp(1);
	              if (!query.exec(stream.next() + match[0])) {
	                stream.next();
	                return null;
	              }
	            }
	            stream.match(query);
	            return 'searching';
	          }
	          while (!stream.eol()) {
	            stream.next();
	            if (stream.match(query, false)) break;
	          }
	        },
	        query: query
	      };
	    }
	    function highlightSearchMatches(cm, query) {
	      var searchState = getSearchState(cm);
	      var overlay = searchState.getOverlay();
	      if (!overlay || query != overlay.query) {
	        if (overlay) {
	          cm.removeOverlay(overlay);
	        }
	        overlay = searchOverlay(query);
	        cm.addOverlay(overlay);
	        if (cm.showMatchesOnScrollbar) {
	          if (searchState.getScrollbarAnnotate()) {
	            searchState.getScrollbarAnnotate().clear();
	          }
	          searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));
	        }
	        searchState.setOverlay(overlay);
	      }
	    }
	    function findNext(cm, prev, query, repeat) {
	      if (repeat === undefined) { repeat = 1; }
	      return cm.operation(function() {
	        var pos = cm.getCursor();
	        var cursor = cm.getSearchCursor(query, pos);
	        for (var i = 0; i < repeat; i++) {
	          var found = cursor.find(prev);
	          if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); }
	          if (!found) {
	            // SearchCursor may have returned null because it hit EOF, wrap
	            // around and try again.
	            cursor = cm.getSearchCursor(query,
	                (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) );
	            if (!cursor.find(prev)) {
	              return;
	            }
	          }
	        }
	        return cursor.from();
	      });
	    }
	    function clearSearchHighlight(cm) {
	      var state = getSearchState(cm);
	      cm.removeOverlay(getSearchState(cm).getOverlay());
	      state.setOverlay(null);
	      if (state.getScrollbarAnnotate()) {
	        state.getScrollbarAnnotate().clear();
	        state.setScrollbarAnnotate(null);
	      }
	    }
	    /**
	     * Check if pos is in the specified range, INCLUSIVE.
	     * Range can be specified with 1 or 2 arguments.
	     * If the first range argument is an array, treat it as an array of line
	     * numbers. Match pos against any of the lines.
	     * If the first range argument is a number,
	     *   if there is only 1 range argument, check if pos has the same line
	     *       number
	     *   if there are 2 range arguments, then check if pos is in between the two
	     *       range arguments.
	     */
	    function isInRange(pos, start, end) {
	      if (typeof pos != 'number') {
	        // Assume it is a cursor position. Get the line number.
	        pos = pos.line;
	      }
	      if (start instanceof Array) {
	        return inArray(pos, start);
	      } else {
	        if (end) {
	          return (pos >= start && pos <= end);
	        } else {
	          return pos == start;
	        }
	      }
	    }
	    function getUserVisibleLines(cm) {
	      var scrollInfo = cm.getScrollInfo();
	      var occludeToleranceTop = 6;
	      var occludeToleranceBottom = 10;
	      var from = cm.coordsChar({left:0, top: occludeToleranceTop + scrollInfo.top}, 'local');
	      var bottomY = scrollInfo.clientHeight - occludeToleranceBottom + scrollInfo.top;
	      var to = cm.coordsChar({left:0, top: bottomY}, 'local');
	      return {top: from.line, bottom: to.line};
	    }
	
	    function getMarkPos(cm, vim, markName) {
	      if (markName == '\'') {
	        var history = cm.doc.history.done;
	        var event = history[history.length - 2];
	        return event && event.ranges && event.ranges[0].head;
	      }
	
	      var mark = vim.marks[markName];
	      return mark && mark.find();
	    }
	
	    var ExCommandDispatcher = function() {
	      this.buildCommandMap_();
	    };
	    ExCommandDispatcher.prototype = {
	      processCommand: function(cm, input, opt_params) {
	        var that = this;
	        cm.operation(function () {
	          cm.curOp.isVimOp = true;
	          that._processCommand(cm, input, opt_params);
	        });
	      },
	      _processCommand: function(cm, input, opt_params) {
	        var vim = cm.state.vim;
	        var commandHistoryRegister = vimGlobalState.registerController.getRegister(':');
	        var previousCommand = commandHistoryRegister.toString();
	        if (vim.visualMode) {
	          exitVisualMode(cm);
	        }
	        var inputStream = new CodeMirror.StringStream(input);
	        // update ": with the latest command whether valid or invalid
	        commandHistoryRegister.setText(input);
	        var params = opt_params || {};
	        params.input = input;
	        try {
	          this.parseInput_(cm, inputStream, params);
	        } catch(e) {
	          showConfirm(cm, e);
	          throw e;
	        }
	        var command;
	        var commandName;
	        if (!params.commandName) {
	          // If only a line range is defined, move to the line.
	          if (params.line !== undefined) {
	            commandName = 'move';
	          }
	        } else {
	          command = this.matchCommand_(params.commandName);
	          if (command) {
	            commandName = command.name;
	            if (command.excludeFromCommandHistory) {
	              commandHistoryRegister.setText(previousCommand);
	            }
	            this.parseCommandArgs_(inputStream, params, command);
	            if (command.type == 'exToKey') {
	              // Handle Ex to Key mapping.
	              for (var i = 0; i < command.toKeys.length; i++) {
	                CodeMirror.Vim.handleKey(cm, command.toKeys[i], 'mapping');
	              }
	              return;
	            } else if (command.type == 'exToEx') {
	              // Handle Ex to Ex mapping.
	              this.processCommand(cm, command.toInput);
	              return;
	            }
	          }
	        }
	        if (!commandName) {
	          showConfirm(cm, 'Not an editor command ":' + input + '"');
	          return;
	        }
	        try {
	          exCommands[commandName](cm, params);
	          // Possibly asynchronous commands (e.g. substitute, which might have a
	          // user confirmation), are responsible for calling the callback when
	          // done. All others have it taken care of for them here.
	          if ((!command || !command.possiblyAsync) && params.callback) {
	            params.callback();
	          }
	        } catch(e) {
	          showConfirm(cm, e);
	          throw e;
	        }
	      },
	      parseInput_: function(cm, inputStream, result) {
	        inputStream.eatWhile(':');
	        // Parse range.
	        if (inputStream.eat('%')) {
	          result.line = cm.firstLine();
	          result.lineEnd = cm.lastLine();
	        } else {
	          result.line = this.parseLineSpec_(cm, inputStream);
	          if (result.line !== undefined && inputStream.eat(',')) {
	            result.lineEnd = this.parseLineSpec_(cm, inputStream);
	          }
	        }
	
	        // Parse command name.
	        var commandMatch = inputStream.match(/^(\w+)/);
	        if (commandMatch) {
	          result.commandName = commandMatch[1];
	        } else {
	          result.commandName = inputStream.match(/.*/)[0];
	        }
	
	        return result;
	      },
	      parseLineSpec_: function(cm, inputStream) {
	        var numberMatch = inputStream.match(/^(\d+)/);
	        if (numberMatch) {
	          // Absolute line number plus offset (N+M or N-M) is probably a typo,
	          // not something the user actually wanted. (NB: vim does allow this.)
	          return parseInt(numberMatch[1], 10) - 1;
	        }
	        switch (inputStream.next()) {
	          case '.':
	            return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);
	          case '$':
	            return this.parseLineSpecOffset_(inputStream, cm.lastLine());
	          case '\'':
	            var markName = inputStream.next();
	            var markPos = getMarkPos(cm, cm.state.vim, markName);
	            if (!markPos) throw new Error('Mark not set');
	            return this.parseLineSpecOffset_(inputStream, markPos.line);
	          case '-':
	          case '+':
	            inputStream.backUp(1);
	            // Offset is relative to current line if not otherwise specified.
	            return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);
	          default:
	            inputStream.backUp(1);
	            return undefined;
	        }
	      },
	      parseLineSpecOffset_: function(inputStream, line) {
	        var offsetMatch = inputStream.match(/^([+-])?(\d+)/);
	        if (offsetMatch) {
	          var offset = parseInt(offsetMatch[2], 10);
	          if (offsetMatch[1] == "-") {
	            line -= offset;
	          } else {
	            line += offset;
	          }
	        }
	        return line;
	      },
	      parseCommandArgs_: function(inputStream, params, command) {
	        if (inputStream.eol()) {
	          return;
	        }
	        params.argString = inputStream.match(/.*/)[0];
	        // Parse command-line arguments
	        var delim = command.argDelimiter || /\s+/;
	        var args = trim(params.argString).split(delim);
	        if (args.length && args[0]) {
	          params.args = args;
	        }
	      },
	      matchCommand_: function(commandName) {
	        // Return the command in the command map that matches the shortest
	        // prefix of the passed in command name. The match is guaranteed to be
	        // unambiguous if the defaultExCommandMap's shortNames are set up
	        // correctly. (see @code{defaultExCommandMap}).
	        for (var i = commandName.length; i > 0; i--) {
	          var prefix = commandName.substring(0, i);
	          if (this.commandMap_[prefix]) {
	            var command = this.commandMap_[prefix];
	            if (command.name.indexOf(commandName) === 0) {
	              return command;
	            }
	          }
	        }
	        return null;
	      },
	      buildCommandMap_: function() {
	        this.commandMap_ = {};
	        for (var i = 0; i < defaultExCommandMap.length; i++) {
	          var command = defaultExCommandMap[i];
	          var key = command.shortName || command.name;
	          this.commandMap_[key] = command;
	        }
	      },
	      map: function(lhs, rhs, ctx) {
	        if (lhs != ':' && lhs.charAt(0) == ':') {
	          if (ctx) { throw Error('Mode not supported for ex mappings'); }
	          var commandName = lhs.substring(1);
	          if (rhs != ':' && rhs.charAt(0) == ':') {
	            // Ex to Ex mapping
	            this.commandMap_[commandName] = {
	              name: commandName,
	              type: 'exToEx',
	              toInput: rhs.substring(1),
	              user: true
	            };
	          } else {
	            // Ex to key mapping
	            this.commandMap_[commandName] = {
	              name: commandName,
	              type: 'exToKey',
	              toKeys: rhs,
	              user: true
	            };
	          }
	        } else {
	          if (rhs != ':' && rhs.charAt(0) == ':') {
	            // Key to Ex mapping.
	            var mapping = {
	              keys: lhs,
	              type: 'keyToEx',
	              exArgs: { input: rhs.substring(1) }
	            };
	            if (ctx) { mapping.context = ctx; }
	            defaultKeymap.unshift(mapping);
	          } else {
	            // Key to key mapping
	            var mapping = {
	              keys: lhs,
	              type: 'keyToKey',
	              toKeys: rhs
	            };
	            if (ctx) { mapping.context = ctx; }
	            defaultKeymap.unshift(mapping);
	          }
	        }
	      },
	      unmap: function(lhs, ctx) {
	        if (lhs != ':' && lhs.charAt(0) == ':') {
	          // Ex to Ex or Ex to key mapping
	          if (ctx) { throw Error('Mode not supported for ex mappings'); }
	          var commandName = lhs.substring(1);
	          if (this.commandMap_[commandName] && this.commandMap_[commandName].user) {
	            delete this.commandMap_[commandName];
	            return;
	          }
	        } else {
	          // Key to Ex or key to key mapping
	          var keys = lhs;
	          for (var i = 0; i < defaultKeymap.length; i++) {
	            if (keys == defaultKeymap[i].keys
	                && defaultKeymap[i].context === ctx) {
	              defaultKeymap.splice(i, 1);
	              return;
	            }
	          }
	        }
	        throw Error('No such mapping.');
	      }
	    };
	
	    var exCommands = {
	      colorscheme: function(cm, params) {
	        if (!params.args || params.args.length < 1) {
	          showConfirm(cm, cm.getOption('theme'));
	          return;
	        }
	        cm.setOption('theme', params.args[0]);
	      },
	      map: function(cm, params, ctx) {
	        var mapArgs = params.args;
	        if (!mapArgs || mapArgs.length < 2) {
	          if (cm) {
	            showConfirm(cm, 'Invalid mapping: ' + params.input);
	          }
	          return;
	        }
	        exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx);
	      },
	      imap: function(cm, params) { this.map(cm, params, 'insert'); },
	      nmap: function(cm, params) { this.map(cm, params, 'normal'); },
	      vmap: function(cm, params) { this.map(cm, params, 'visual'); },
	      unmap: function(cm, params, ctx) {
	        var mapArgs = params.args;
	        if (!mapArgs || mapArgs.length < 1) {
	          if (cm) {
	            showConfirm(cm, 'No such mapping: ' + params.input);
	          }
	          return;
	        }
	        exCommandDispatcher.unmap(mapArgs[0], ctx);
	      },
	      move: function(cm, params) {
	        commandDispatcher.processCommand(cm, cm.state.vim, {
	            type: 'motion',
	            motion: 'moveToLineOrEdgeOfDocument',
	            motionArgs: { forward: false, explicitRepeat: true,
	              linewise: true },
	            repeatOverride: params.line+1});
	      },
	      set: function(cm, params) {
	        var setArgs = params.args;
	        // Options passed through to the setOption/getOption calls. May be passed in by the
	        // local/global versions of the set command
	        var setCfg = params.setCfg || {};
	        if (!setArgs || setArgs.length < 1) {
	          if (cm) {
	            showConfirm(cm, 'Invalid mapping: ' + params.input);
	          }
	          return;
	        }
	        var expr = setArgs[0].split('=');
	        var optionName = expr[0];
	        var value = expr[1];
	        var forceGet = false;
	
	        if (optionName.charAt(optionName.length - 1) == '?') {
	          // If post-fixed with ?, then the set is actually a get.
	          if (value) { throw Error('Trailing characters: ' + params.argString); }
	          optionName = optionName.substring(0, optionName.length - 1);
	          forceGet = true;
	        }
	        if (value === undefined && optionName.substring(0, 2) == 'no') {
	          // To set boolean options to false, the option name is prefixed with
	          // 'no'.
	          optionName = optionName.substring(2);
	          value = false;
	        }
	
	        var optionIsBoolean = options[optionName] && options[optionName].type == 'boolean';
	        if (optionIsBoolean && value == undefined) {
	          // Calling set with a boolean option sets it to true.
	          value = true;
	        }
	        // If no value is provided, then we assume this is a get.
	        if (!optionIsBoolean && value === undefined || forceGet) {
	          var oldValue = getOption(optionName, cm, setCfg);
	          if (oldValue instanceof Error) {
	            showConfirm(cm, oldValue.message);
	          } else if (oldValue === true || oldValue === false) {
	            showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName);
	          } else {
	            showConfirm(cm, '  ' + optionName + '=' + oldValue);
	          }
	        } else {
	          var setOptionReturn = setOption(optionName, value, cm, setCfg);
	          if (setOptionReturn instanceof Error) {
	            showConfirm(cm, setOptionReturn.message);
	          }
	        }
	      },
	      setlocal: function (cm, params) {
	        // setCfg is passed through to setOption
	        params.setCfg = {scope: 'local'};
	        this.set(cm, params);
	      },
	      setglobal: function (cm, params) {
	        // setCfg is passed through to setOption
	        params.setCfg = {scope: 'global'};
	        this.set(cm, params);
	      },
	      registers: function(cm, params) {
	        var regArgs = params.args;
	        var registers = vimGlobalState.registerController.registers;
	        var regInfo = '----------Registers----------<br><br>';
	        if (!regArgs) {
	          for (var registerName in registers) {
	            var text = registers[registerName].toString();
	            if (text.length) {
	              regInfo += '"' + registerName + '    ' + text + '<br>';
	            }
	          }
	        } else {
	          var registerName;
	          regArgs = regArgs.join('');
	          for (var i = 0; i < regArgs.length; i++) {
	            registerName = regArgs.charAt(i);
	            if (!vimGlobalState.registerController.isValidRegister(registerName)) {
	              continue;
	            }
	            var register = registers[registerName] || new Register();
	            regInfo += '"' + registerName + '    ' + register.toString() + '<br>';
	          }
	        }
	        showConfirm(cm, regInfo);
	      },
	      sort: function(cm, params) {
	        var reverse, ignoreCase, unique, number, pattern;
	        function parseArgs() {
	          if (params.argString) {
	            var args = new CodeMirror.StringStream(params.argString);
	            if (args.eat('!')) { reverse = true; }
	            if (args.eol()) { return; }
	            if (!args.eatSpace()) { return 'Invalid arguments'; }
	            var opts = args.match(/([dinuox]+)?\s*(\/.+\/)?\s*/);
	            if (!opts && !args.eol()) { return 'Invalid arguments'; }
	            if (opts[1]) {
	              ignoreCase = opts[1].indexOf('i') != -1;
	              unique = opts[1].indexOf('u') != -1;
	              var decimal = opts[1].indexOf('d') != -1 || opts[1].indexOf('n') != -1 && 1;
	              var hex = opts[1].indexOf('x') != -1 && 1;
	              var octal = opts[1].indexOf('o') != -1 && 1;
	              if (decimal + hex + octal > 1) { return 'Invalid arguments'; }
	              number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';
	            }
	            if (opts[2]) {
	              pattern = new RegExp(opts[2].substr(1, opts[2].length - 2), ignoreCase ? 'i' : '');
	            }
	          }
	        }
	        var err = parseArgs();
	        if (err) {
	          showConfirm(cm, err + ': ' + params.argString);
	          return;
	        }
	        var lineStart = params.line || cm.firstLine();
	        var lineEnd = params.lineEnd || params.line || cm.lastLine();
	        if (lineStart == lineEnd) { return; }
	        var curStart = Pos(lineStart, 0);
	        var curEnd = Pos(lineEnd, lineLength(cm, lineEnd));
	        var text = cm.getRange(curStart, curEnd).split('\n');
	        var numberRegex = pattern ? pattern :
	           (number == 'decimal') ? /(-?)([\d]+)/ :
	           (number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i :
	           (number == 'octal') ? /([0-7]+)/ : null;
	        var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null;
	        var numPart = [], textPart = [];
	        if (number || pattern) {
	          for (var i = 0; i < text.length; i++) {
	            var matchPart = pattern ? text[i].match(pattern) : null;
	            if (matchPart && matchPart[0] != '') {
	              numPart.push(matchPart);
	            } else if (!pattern && numberRegex.exec(text[i])) {
	              numPart.push(text[i]);
	            } else {
	              textPart.push(text[i]);
	            }
	          }
	        } else {
	          textPart = text;
	        }
	        function compareFn(a, b) {
	          if (reverse) { var tmp; tmp = a; a = b; b = tmp; }
	          if (ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); }
	          var anum = number && numberRegex.exec(a);
	          var bnum = number && numberRegex.exec(b);
	          if (!anum) { return a < b ? -1 : 1; }
	          anum = parseInt((anum[1] + anum[2]).toLowerCase(), radix);
	          bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix);
	          return anum - bnum;
	        }
	        function comparePatternFn(a, b) {
	          if (reverse) { var tmp; tmp = a; a = b; b = tmp; }
	          if (ignoreCase) { a[0] = a[0].toLowerCase(); b[0] = b[0].toLowerCase(); }
	          return (a[0] < b[0]) ? -1 : 1;
	        }
	        numPart.sort(pattern ? comparePatternFn : compareFn);
	        if (pattern) {
	          for (var i = 0; i < numPart.length; i++) {
	            numPart[i] = numPart[i].input;
	          }
	        } else if (!number) { textPart.sort(compareFn); }
	        text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart);
	        if (unique) { // Remove duplicate lines
	          var textOld = text;
	          var lastLine;
	          text = [];
	          for (var i = 0; i < textOld.length; i++) {
	            if (textOld[i] != lastLine) {
	              text.push(textOld[i]);
	            }
	            lastLine = textOld[i];
	          }
	        }
	        cm.replaceRange(text.join('\n'), curStart, curEnd);
	      },
	      global: function(cm, params) {
	        // a global command is of the form
	        // :[range]g/pattern/[cmd]
	        // argString holds the string /pattern/[cmd]
	        var argString = params.argString;
	        if (!argString) {
	          showConfirm(cm, 'Regular Expression missing from global');
	          return;
	        }
	        // range is specified here
	        var lineStart = (params.line !== undefined) ? params.line : cm.firstLine();
	        var lineEnd = params.lineEnd || params.line || cm.lastLine();
	        // get the tokens from argString
	        var tokens = splitBySlash(argString);
	        var regexPart = argString, cmd;
	        if (tokens.length) {
	          regexPart = tokens[0];
	          cmd = tokens.slice(1, tokens.length).join('/');
	        }
	        if (regexPart) {
	          // If regex part is empty, then use the previous query. Otherwise
	          // use the regex part as the new query.
	          try {
	           updateSearchQuery(cm, regexPart, true /** ignoreCase */,
	             true /** smartCase */);
	          } catch (e) {
	           showConfirm(cm, 'Invalid regex: ' + regexPart);
	           return;
	          }
	        }
	        // now that we have the regexPart, search for regex matches in the
	        // specified range of lines
	        var query = getSearchState(cm).getQuery();
	        var matchedLines = [], content = '';
	        for (var i = lineStart; i <= lineEnd; i++) {
	          var matched = query.test(cm.getLine(i));
	          if (matched) {
	            matchedLines.push(i+1);
	            content+= cm.getLine(i) + '<br>';
	          }
	        }
	        // if there is no [cmd], just display the list of matched lines
	        if (!cmd) {
	          showConfirm(cm, content);
	          return;
	        }
	        var index = 0;
	        var nextCommand = function() {
	          if (index < matchedLines.length) {
	            var command = matchedLines[index] + cmd;
	            exCommandDispatcher.processCommand(cm, command, {
	              callback: nextCommand
	            });
	          }
	          index++;
	        };
	        nextCommand();
	      },
	      substitute: function(cm, params) {
	        if (!cm.getSearchCursor) {
	          throw new Error('Search feature not available. Requires searchcursor.js or ' +
	              'any other getSearchCursor implementation.');
	        }
	        var argString = params.argString;
	        var tokens = argString ? splitBySlash(argString) : [];
	        var regexPart, replacePart = '', trailing, flagsPart, count;
	        var confirm = false; // Whether to confirm each replace.
	        var global = false; // True to replace all instances on a line, false to replace only 1.
	        if (tokens.length) {
	          regexPart = tokens[0];
	          replacePart = tokens[1];
	          if (regexPart && regexPart[regexPart.length - 1] === '$') {
	            regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n';
	            replacePart = replacePart ? replacePart + '\n' : '\n';
	          }
	          if (replacePart !== undefined) {
	            if (getOption('pcre')) {
	              replacePart = unescapeRegexReplace(replacePart);
	            } else {
	              replacePart = translateRegexReplace(replacePart);
	            }
	            vimGlobalState.lastSubstituteReplacePart = replacePart;
	          }
	          trailing = tokens[2] ? tokens[2].split(' ') : [];
	        } else {
	          // either the argString is empty or its of the form ' hello/world'
	          // actually splitBySlash returns a list of tokens
	          // only if the string starts with a '/'
	          if (argString && argString.length) {
	            showConfirm(cm, 'Substitutions should be of the form ' +
	                ':s/pattern/replace/');
	            return;
	          }
	        }
	        // After the 3rd slash, we can have flags followed by a space followed
	        // by count.
	        if (trailing) {
	          flagsPart = trailing[0];
	          count = parseInt(trailing[1]);
	          if (flagsPart) {
	            if (flagsPart.indexOf('c') != -1) {
	              confirm = true;
	              flagsPart.replace('c', '');
	            }
	            if (flagsPart.indexOf('g') != -1) {
	              global = true;
	              flagsPart.replace('g', '');
	            }
	            regexPart = regexPart + '/' + flagsPart;
	          }
	        }
	        if (regexPart) {
	          // If regex part is empty, then use the previous query. Otherwise use
	          // the regex part as the new query.
	          try {
	            updateSearchQuery(cm, regexPart, true /** ignoreCase */,
	              true /** smartCase */);
	          } catch (e) {
	            showConfirm(cm, 'Invalid regex: ' + regexPart);
	            return;
	          }
	        }
	        replacePart = replacePart || vimGlobalState.lastSubstituteReplacePart;
	        if (replacePart === undefined) {
	          showConfirm(cm, 'No previous substitute regular expression');
	          return;
	        }
	        var state = getSearchState(cm);
	        var query = state.getQuery();
	        var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;
	        var lineEnd = params.lineEnd || lineStart;
	        if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) {
	          lineEnd = Infinity;
	        }
	        if (count) {
	          lineStart = lineEnd;
	          lineEnd = lineStart + count - 1;
	        }
	        var startPos = clipCursorToContent(cm, Pos(lineStart, 0));
	        var cursor = cm.getSearchCursor(query, startPos);
	        doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback);
	      },
	      redo: CodeMirror.commands.redo,
	      undo: CodeMirror.commands.undo,
	      write: function(cm) {
	        if (CodeMirror.commands.save) {
	          // If a save command is defined, call it.
	          CodeMirror.commands.save(cm);
	        } else if (cm.save) {
	          // Saves to text area if no save command is defined and cm.save() is available.
	          cm.save();
	        }
	      },
	      nohlsearch: function(cm) {
	        clearSearchHighlight(cm);
	      },
	      yank: function (cm) {
	        var cur = copyCursor(cm.getCursor());
	        var line = cur.line;
	        var lineText = cm.getLine(line);
	        vimGlobalState.registerController.pushText(
	          '0', 'yank', lineText, true, true);
	      },
	      delmarks: function(cm, params) {
	        if (!params.argString || !trim(params.argString)) {
	          showConfirm(cm, 'Argument required');
	          return;
	        }
	
	        var state = cm.state.vim;
	        var stream = new CodeMirror.StringStream(trim(params.argString));
	        while (!stream.eol()) {
	          stream.eatSpace();
	
	          // Record the streams position at the beginning of the loop for use
	          // in error messages.
	          var count = stream.pos;
	
	          if (!stream.match(/[a-zA-Z]/, false)) {
	            showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));
	            return;
	          }
	
	          var sym = stream.next();
	          // Check if this symbol is part of a range
	          if (stream.match('-', true)) {
	            // This symbol is part of a range.
	
	            // The range must terminate at an alphabetic character.
	            if (!stream.match(/[a-zA-Z]/, false)) {
	              showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));
	              return;
	            }
	
	            var startMark = sym;
	            var finishMark = stream.next();
	            // The range must terminate at an alphabetic character which
	            // shares the same case as the start of the range.
	            if (isLowerCase(startMark) && isLowerCase(finishMark) ||
	                isUpperCase(startMark) && isUpperCase(finishMark)) {
	              var start = startMark.charCodeAt(0);
	              var finish = finishMark.charCodeAt(0);
	              if (start >= finish) {
	                showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));
	                return;
	              }
	
	              // Because marks are always ASCII values, and we have
	              // determined that they are the same case, we can use
	              // their char codes to iterate through the defined range.
	              for (var j = 0; j <= finish - start; j++) {
	                var mark = String.fromCharCode(start + j);
	                delete state.marks[mark];
	              }
	            } else {
	              showConfirm(cm, 'Invalid argument: ' + startMark + '-');
	              return;
	            }
	          } else {
	            // This symbol is a valid mark, and is not part of a range.
	            delete state.marks[sym];
	          }
	        }
	      }
	    };
	
	    var exCommandDispatcher = new ExCommandDispatcher();
	
	    /**
	    * @param {CodeMirror} cm CodeMirror instance we are in.
	    * @param {boolean} confirm Whether to confirm each replace.
	    * @param {Cursor} lineStart Line to start replacing from.
	    * @param {Cursor} lineEnd Line to stop replacing at.
	    * @param {RegExp} query Query for performing matches with.
	    * @param {string} replaceWith Text to replace matches with. May contain $1,
	    *     $2, etc for replacing captured groups using Javascript replace.
	    * @param {function()} callback A callback for when the replace is done.
	    */
	    function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query,
	        replaceWith, callback) {
	      // Set up all the functions.
	      cm.state.vim.exMode = true;
	      var done = false;
	      var lastPos = searchCursor.from();
	      function replaceAll() {
	        cm.operation(function() {
	          while (!done) {
	            replace();
	            next();
	          }
	          stop();
	        });
	      }
	      function replace() {
	        var text = cm.getRange(searchCursor.from(), searchCursor.to());
	        var newText = text.replace(query, replaceWith);
	        searchCursor.replace(newText);
	      }
	      function next() {
	        // The below only loops to skip over multiple occurrences on the same
	        // line when 'global' is not true.
	        while(searchCursor.findNext() &&
	              isInRange(searchCursor.from(), lineStart, lineEnd)) {
	          if (!global && lastPos && searchCursor.from().line == lastPos.line) {
	            continue;
	          }
	          cm.scrollIntoView(searchCursor.from(), 30);
	          cm.setSelection(searchCursor.from(), searchCursor.to());
	          lastPos = searchCursor.from();
	          done = false;
	          return;
	        }
	        done = true;
	      }
	      function stop(close) {
	        if (close) { close(); }
	        cm.focus();
	        if (lastPos) {
	          cm.setCursor(lastPos);
	          var vim = cm.state.vim;
	          vim.exMode = false;
	          vim.lastHPos = vim.lastHSPos = lastPos.ch;
	        }
	        if (callback) { callback(); }
	      }
	      function onPromptKeyDown(e, _value, close) {
	        // Swallow all keys.
	        CodeMirror.e_stop(e);
	        var keyName = CodeMirror.keyName(e);
	        switch (keyName) {
	          case 'Y':
	            replace(); next(); break;
	          case 'N':
	            next(); break;
	          case 'A':
	            // replaceAll contains a call to close of its own. We don't want it
	            // to fire too early or multiple times.
	            var savedCallback = callback;
	            callback = undefined;
	            cm.operation(replaceAll);
	            callback = savedCallback;
	            break;
	          case 'L':
	            replace();
	            // fall through and exit.
	          case 'Q':
	          case 'Esc':
	          case 'Ctrl-C':
	          case 'Ctrl-[':
	            stop(close);
	            break;
	        }
	        if (done) { stop(close); }
	        return true;
	      }
	
	      // Actually do replace.
	      next();
	      if (done) {
	        showConfirm(cm, 'No matches for ' + query.source);
	        return;
	      }
	      if (!confirm) {
	        replaceAll();
	        if (callback) { callback(); };
	        return;
	      }
	      showPrompt(cm, {
	        prefix: 'replace with <strong>' + replaceWith + '</strong> (y/n/a/q/l)',
	        onKeyDown: onPromptKeyDown
	      });
	    }
	
	    CodeMirror.keyMap.vim = {
	      attach: attachVimMap,
	      detach: detachVimMap,
	      call: cmKey
	    };
	
	    function exitInsertMode(cm) {
	      var vim = cm.state.vim;
	      var macroModeState = vimGlobalState.macroModeState;
	      var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.');
	      var isPlaying = macroModeState.isPlaying;
	      var lastChange = macroModeState.lastInsertModeChanges;
	      // In case of visual block, the insertModeChanges are not saved as a
	      // single word, so we convert them to a single word
	      // so as to update the ". register as expected in real vim.
	      var text = [];
	      if (!isPlaying) {
	        var selLength = lastChange.inVisualBlock ? vim.lastSelection.visualBlock.height : 1;
	        var changes = lastChange.changes;
	        var text = [];
	        var i = 0;
	        // In case of multiple selections in blockwise visual,
	        // the inserted text, for example: 'f<Backspace>oo', is stored as
	        // 'f', 'f', InsertModeKey 'o', 'o', 'o', 'o'. (if you have a block with 2 lines).
	        // We push the contents of the changes array as per the following:
	        // 1. In case of InsertModeKey, just increment by 1.
	        // 2. In case of a character, jump by selLength (2 in the example).
	        while (i < changes.length) {
	          // This loop will convert 'ff<bs>oooo' to 'f<bs>oo'.
	          text.push(changes[i]);
	          if (changes[i] instanceof InsertModeKey) {
	             i++;
	          } else {
	             i+= selLength;
	          }
	        }
	        lastChange.changes = text;
	        cm.off('change', onChange);
	        CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);
	      }
	      if (!isPlaying && vim.insertModeRepeat > 1) {
	        // Perform insert mode repeat for commands like 3,a and 3,o.
	        repeatLastEdit(cm, vim, vim.insertModeRepeat - 1,
	            true /** repeatForInsert */);
	        vim.lastEditInputState.repeatOverride = vim.insertModeRepeat;
	      }
	      delete vim.insertModeRepeat;
	      vim.insertMode = false;
	      cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1);
	      cm.setOption('keyMap', 'vim');
	      cm.setOption('disableInput', true);
	      cm.toggleOverwrite(false); // exit replace mode if we were in it.
	      // update the ". register before exiting insert mode
	      insertModeChangeRegister.setText(lastChange.changes.join(''));
	      CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
	      if (macroModeState.isRecording) {
	        logInsertModeChange(macroModeState);
	      }
	    }
	
	    function _mapCommand(command) {
	      defaultKeymap.unshift(command);
	    }
	
	    function mapCommand(keys, type, name, args, extra) {
	      var command = {keys: keys, type: type};
	      command[type] = name;
	      command[type + "Args"] = args;
	      for (var key in extra)
	        command[key] = extra[key];
	      _mapCommand(command);
	    }
	
	    // The timeout in milliseconds for the two-character ESC keymap should be
	    // adjusted according to your typing speed to prevent false positives.
	    defineOption('insertModeEscKeysTimeout', 200, 'number');
	
	    CodeMirror.keyMap['vim-insert'] = {
	      // TODO: override navigation keys so that Esc will cancel automatic
	      // indentation from o, O, i_<CR>
	      fallthrough: ['default'],
	      attach: attachVimMap,
	      detach: detachVimMap,
	      call: cmKey
	    };
	
	    CodeMirror.keyMap['vim-replace'] = {
	      'Backspace': 'goCharLeft',
	      fallthrough: ['vim-insert'],
	      attach: attachVimMap,
	      detach: detachVimMap,
	      call: cmKey
	    };
	
	    function executeMacroRegister(cm, vim, macroModeState, registerName) {
	      var register = vimGlobalState.registerController.getRegister(registerName);
	      if (registerName == ':') {
	        // Read-only register containing last Ex command.
	        if (register.keyBuffer[0]) {
	          exCommandDispatcher.processCommand(cm, register.keyBuffer[0]);
	        }
	        macroModeState.isPlaying = false;
	        return;
	      }
	      var keyBuffer = register.keyBuffer;
	      var imc = 0;
	      macroModeState.isPlaying = true;
	      macroModeState.replaySearchQueries = register.searchQueries.slice(0);
	      for (var i = 0; i < keyBuffer.length; i++) {
	        var text = keyBuffer[i];
	        var match, key;
	        while (text) {
	          // Pull off one command key, which is either a single character
	          // or a special sequence wrapped in '<' and '>', e.g. '<Space>'.
	          match = (/<\w+-.+?>|<\w+>|./).exec(text);
	          key = match[0];
	          text = text.substring(match.index + key.length);
	          CodeMirror.Vim.handleKey(cm, key, 'macro');
	          if (vim.insertMode) {
	            var changes = register.insertModeChanges[imc++].changes;
	            vimGlobalState.macroModeState.lastInsertModeChanges.changes =
	                changes;
	            repeatInsertModeChanges(cm, changes, 1);
	            exitInsertMode(cm);
	          }
	        }
	      };
	      macroModeState.isPlaying = false;
	    }
	
	    function logKey(macroModeState, key) {
	      if (macroModeState.isPlaying) { return; }
	      var registerName = macroModeState.latestRegister;
	      var register = vimGlobalState.registerController.getRegister(registerName);
	      if (register) {
	        register.pushText(key);
	      }
	    }
	
	    function logInsertModeChange(macroModeState) {
	      if (macroModeState.isPlaying) { return; }
	      var registerName = macroModeState.latestRegister;
	      var register = vimGlobalState.registerController.getRegister(registerName);
	      if (register && register.pushInsertModeChanges) {
	        register.pushInsertModeChanges(macroModeState.lastInsertModeChanges);
	      }
	    }
	
	    function logSearchQuery(macroModeState, query) {
	      if (macroModeState.isPlaying) { return; }
	      var registerName = macroModeState.latestRegister;
	      var register = vimGlobalState.registerController.getRegister(registerName);
	      if (register && register.pushSearchQuery) {
	        register.pushSearchQuery(query);
	      }
	    }
	
	    /**
	     * Listens for changes made in insert mode.
	     * Should only be active in insert mode.
	     */
	    function onChange(cm, changeObj) {
	      var macroModeState = vimGlobalState.macroModeState;
	      var lastChange = macroModeState.lastInsertModeChanges;
	      if (!macroModeState.isPlaying) {
	        while(changeObj) {
	          lastChange.expectCursorActivityForChange = true;
	          if (changeObj.origin == '+input' || changeObj.origin == 'paste'
	              || changeObj.origin === undefined /* only in testing */) {
	            var text = changeObj.text.join('\n');
	            if (lastChange.maybeReset) {
	              lastChange.changes = [];
	              lastChange.maybeReset = false;
	            }
	            if (cm.state.overwrite && !/\n/.test(text)) {
	                lastChange.changes.push([text]);
	            } else {
	                lastChange.changes.push(text);
	            }
	          }
	          // Change objects may be chained with next.
	          changeObj = changeObj.next;
	        }
	      }
	    }
	
	    /**
	    * Listens for any kind of cursor activity on CodeMirror.
	    */
	    function onCursorActivity(cm) {
	      var vim = cm.state.vim;
	      if (vim.insertMode) {
	        // Tracking cursor activity in insert mode (for macro support).
	        var macroModeState = vimGlobalState.macroModeState;
	        if (macroModeState.isPlaying) { return; }
	        var lastChange = macroModeState.lastInsertModeChanges;
	        if (lastChange.expectCursorActivityForChange) {
	          lastChange.expectCursorActivityForChange = false;
	        } else {
	          // Cursor moved outside the context of an edit. Reset the change.
	          lastChange.maybeReset = true;
	        }
	      } else if (!cm.curOp.isVimOp) {
	        handleExternalSelection(cm, vim);
	      }
	      if (vim.visualMode) {
	        updateFakeCursor(cm);
	      }
	    }
	    function updateFakeCursor(cm) {
	      var vim = cm.state.vim;
	      var from = clipCursorToContent(cm, copyCursor(vim.sel.head));
	      var to = offsetCursor(from, 0, 1);
	      if (vim.fakeCursor) {
	        vim.fakeCursor.clear();
	      }
	      vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'});
	    }
	    function handleExternalSelection(cm, vim) {
	      var anchor = cm.getCursor('anchor');
	      var head = cm.getCursor('head');
	      // Enter or exit visual mode to match mouse selection.
	      if (vim.visualMode && !cm.somethingSelected()) {
	        exitVisualMode(cm, false);
	      } else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) {
	        vim.visualMode = true;
	        vim.visualLine = false;
	        CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"});
	      }
	      if (vim.visualMode) {
	        // Bind CodeMirror selection model to vim selection model.
	        // Mouse selections are considered visual characterwise.
	        var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0;
	        var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0;
	        head = offsetCursor(head, 0, headOffset);
	        anchor = offsetCursor(anchor, 0, anchorOffset);
	        vim.sel = {
	          anchor: anchor,
	          head: head
	        };
	        updateMark(cm, vim, '<', cursorMin(head, anchor));
	        updateMark(cm, vim, '>', cursorMax(head, anchor));
	      } else if (!vim.insertMode) {
	        // Reset lastHPos if selection was modified by something outside of vim mode e.g. by mouse.
	        vim.lastHPos = cm.getCursor().ch;
	      }
	    }
	
	    /** Wrapper for special keys pressed in insert mode */
	    function InsertModeKey(keyName) {
	      this.keyName = keyName;
	    }
	
	    /**
	    * Handles raw key down events from the text area.
	    * - Should only be active in insert mode.
	    * - For recording deletes in insert mode.
	    */
	    function onKeyEventTargetKeyDown(e) {
	      var macroModeState = vimGlobalState.macroModeState;
	      var lastChange = macroModeState.lastInsertModeChanges;
	      var keyName = CodeMirror.keyName(e);
	      if (!keyName) { return; }
	      function onKeyFound() {
	        if (lastChange.maybeReset) {
	          lastChange.changes = [];
	          lastChange.maybeReset = false;
	        }
	        lastChange.changes.push(new InsertModeKey(keyName));
	        return true;
	      }
	      if (keyName.indexOf('Delete') != -1 || keyName.indexOf('Backspace') != -1) {
	        CodeMirror.lookupKey(keyName, 'vim-insert', onKeyFound);
	      }
	    }
	
	    /**
	     * Repeats the last edit, which includes exactly 1 command and at most 1
	     * insert. Operator and motion commands are read from lastEditInputState,
	     * while action commands are read from lastEditActionCommand.
	     *
	     * If repeatForInsert is true, then the function was called by
	     * exitInsertMode to repeat the insert mode changes the user just made. The
	     * corresponding enterInsertMode call was made with a count.
	     */
	    function repeatLastEdit(cm, vim, repeat, repeatForInsert) {
	      var macroModeState = vimGlobalState.macroModeState;
	      macroModeState.isPlaying = true;
	      var isAction = !!vim.lastEditActionCommand;
	      var cachedInputState = vim.inputState;
	      function repeatCommand() {
	        if (isAction) {
	          commandDispatcher.processAction(cm, vim, vim.lastEditActionCommand);
	        } else {
	          commandDispatcher.evalInput(cm, vim);
	        }
	      }
	      function repeatInsert(repeat) {
	        if (macroModeState.lastInsertModeChanges.changes.length > 0) {
	          // For some reason, repeat cw in desktop VIM does not repeat
	          // insert mode changes. Will conform to that behavior.
	          repeat = !vim.lastEditActionCommand ? 1 : repeat;
	          var changeObject = macroModeState.lastInsertModeChanges;
	          repeatInsertModeChanges(cm, changeObject.changes, repeat);
	        }
	      }
	      vim.inputState = vim.lastEditInputState;
	      if (isAction && vim.lastEditActionCommand.interlaceInsertRepeat) {
	        // o and O repeat have to be interlaced with insert repeats so that the
	        // insertions appear on separate lines instead of the last line.
	        for (var i = 0; i < repeat; i++) {
	          repeatCommand();
	          repeatInsert(1);
	        }
	      } else {
	        if (!repeatForInsert) {
	          // Hack to get the cursor to end up at the right place. If I is
	          // repeated in insert mode repeat, cursor will be 1 insert
	          // change set left of where it should be.
	          repeatCommand();
	        }
	        repeatInsert(repeat);
	      }
	      vim.inputState = cachedInputState;
	      if (vim.insertMode && !repeatForInsert) {
	        // Don't exit insert mode twice. If repeatForInsert is set, then we
	        // were called by an exitInsertMode call lower on the stack.
	        exitInsertMode(cm);
	      }
	      macroModeState.isPlaying = false;
	    };
	
	    function repeatInsertModeChanges(cm, changes, repeat) {
	      function keyHandler(binding) {
	        if (typeof binding == 'string') {
	          CodeMirror.commands[binding](cm);
	        } else {
	          binding(cm);
	        }
	        return true;
	      }
	      var head = cm.getCursor('head');
	      var inVisualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock;
	      if (inVisualBlock) {
	        // Set up block selection again for repeating the changes.
	        var vim = cm.state.vim;
	        var lastSel = vim.lastSelection;
	        var offset = getOffset(lastSel.anchor, lastSel.head);
	        selectForInsert(cm, head, offset.line + 1);
	        repeat = cm.listSelections().length;
	        cm.setCursor(head);
	      }
	      for (var i = 0; i < repeat; i++) {
	        if (inVisualBlock) {
	          cm.setCursor(offsetCursor(head, i, 0));
	        }
	        for (var j = 0; j < changes.length; j++) {
	          var change = changes[j];
	          if (change instanceof InsertModeKey) {
	            CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler);
	          } else if (typeof change == "string") {
	            var cur = cm.getCursor();
	            cm.replaceRange(change, cur, cur);
	          } else {
	            var start = cm.getCursor();
	            var end = offsetCursor(start, 0, change[0].length);
	            cm.replaceRange(change[0], start, end);
	          }
	        }
	      }
	      if (inVisualBlock) {
	        cm.setCursor(offsetCursor(head, 0, 1));
	      }
	    }
	
	    resetVimGlobalState();
	    return vimApi;
	  };
	  // Initialize Vim and make it available as an API.
	  CodeMirror.Vim = Vim();
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/keymap/vim.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/search/searchcursor.js **/
jupyter.define('codemirror@5.27.2/addon/search/searchcursor.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'))
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod)
	  else // Plain browser env
	    mod(CodeMirror)
	})(function(CodeMirror) {
	  "use strict"
	  var Pos = CodeMirror.Pos
	
	  function regexpFlags(regexp) {
	    var flags = regexp.flags
	    return flags != null ? flags : (regexp.ignoreCase ? "i" : "")
	      + (regexp.global ? "g" : "")
	      + (regexp.multiline ? "m" : "")
	  }
	
	  function ensureGlobal(regexp) {
	    return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g")
	  }
	
	  function maybeMultiline(regexp) {
	    return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)
	  }
	
	  function searchRegexpForward(doc, regexp, start) {
	    regexp = ensureGlobal(regexp)
	    for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) {
	      regexp.lastIndex = ch
	      var string = doc.getLine(line), match = regexp.exec(string)
	      if (match)
	        return {from: Pos(line, match.index),
	                to: Pos(line, match.index + match[0].length),
	                match: match}
	    }
	  }
	
	  function searchRegexpForwardMultiline(doc, regexp, start) {
	    if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start)
	
	    regexp = ensureGlobal(regexp)
	    var string, chunk = 1
	    for (var line = start.line, last = doc.lastLine(); line <= last;) {
	      // This grows the search buffer in exponentially-sized chunks
	      // between matches, so that nearby matches are fast and don't
	      // require concatenating the whole document (in case we're
	      // searching for something that has tons of matches), but at the
	      // same time, the amount of retries is limited.
	      for (var i = 0; i < chunk; i++) {
	        var curLine = doc.getLine(line++)
	        string = string == null ? curLine : string + "\n" + curLine
	      }
	      chunk = chunk * 2
	      regexp.lastIndex = start.ch
	      var match = regexp.exec(string)
	      if (match) {
	        var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
	        var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length
	        return {from: Pos(startLine, startCh),
	                to: Pos(startLine + inside.length - 1,
	                        inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
	                match: match}
	      }
	    }
	  }
	
	  function lastMatchIn(string, regexp) {
	    var cutOff = 0, match
	    for (;;) {
	      regexp.lastIndex = cutOff
	      var newMatch = regexp.exec(string)
	      if (!newMatch) return match
	      match = newMatch
	      cutOff = match.index + (match[0].length || 1)
	      if (cutOff == string.length) return match
	    }
	  }
	
	  function searchRegexpBackward(doc, regexp, start) {
	    regexp = ensureGlobal(regexp)
	    for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
	      var string = doc.getLine(line)
	      if (ch > -1) string = string.slice(0, ch)
	      var match = lastMatchIn(string, regexp)
	      if (match)
	        return {from: Pos(line, match.index),
	                to: Pos(line, match.index + match[0].length),
	                match: match}
	    }
	  }
	
	  function searchRegexpBackwardMultiline(doc, regexp, start) {
	    regexp = ensureGlobal(regexp)
	    var string, chunk = 1
	    for (var line = start.line, first = doc.firstLine(); line >= first;) {
	      for (var i = 0; i < chunk; i++) {
	        var curLine = doc.getLine(line--)
	        string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
	      }
	      chunk *= 2
	
	      var match = lastMatchIn(string, regexp)
	      if (match) {
	        var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
	        var startLine = line + before.length, startCh = before[before.length - 1].length
	        return {from: Pos(startLine, startCh),
	                to: Pos(startLine + inside.length - 1,
	                        inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
	                match: match}
	      }
	    }
	  }
	
	  var doFold, noFold
	  if (String.prototype.normalize) {
	    doFold = function(str) { return str.normalize("NFD").toLowerCase() }
	    noFold = function(str) { return str.normalize("NFD") }
	  } else {
	    doFold = function(str) { return str.toLowerCase() }
	    noFold = function(str) { return str }
	  }
	
	  // Maps a position in a case-folded line back to a position in the original line
	  // (compensating for codepoints increasing in number during folding)
	  function adjustPos(orig, folded, pos) {
	    if (orig.length == folded.length) return pos
	    for (var pos1 = Math.min(pos, orig.length);;) {
	      var len1 = orig.slice(0, pos1).toLowerCase().length
	      if (len1 < pos) ++pos1
	      else if (len1 > pos) --pos1
	      else return pos1
	    }
	  }
	
	  function searchStringForward(doc, query, start, caseFold) {
	    // Empty string would match anything and never progress, so we
	    // define it to match nothing instead.
	    if (!query.length) return null
	    var fold = caseFold ? doFold : noFold
	    var lines = fold(query).split(/\r|\n\r?/)
	
	    search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) {
	      var orig = doc.getLine(line).slice(ch), string = fold(orig)
	      if (lines.length == 1) {
	        var found = string.indexOf(lines[0])
	        if (found == -1) continue search
	        var start = adjustPos(orig, string, found) + ch
	        return {from: Pos(line, adjustPos(orig, string, found) + ch),
	                to: Pos(line, adjustPos(orig, string, found + lines[0].length) + ch)}
	      } else {
	        var cutFrom = string.length - lines[0].length
	        if (string.slice(cutFrom) != lines[0]) continue search
	        for (var i = 1; i < lines.length - 1; i++)
	          if (fold(doc.getLine(line + i)) != lines[i]) continue search
	        var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]
	        if (end.slice(0, lastLine.length) != lastLine) continue search
	        return {from: Pos(line, adjustPos(orig, string, cutFrom) + ch),
	                to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length))}
	      }
	    }
	  }
	
	  function searchStringBackward(doc, query, start, caseFold) {
	    if (!query.length) return null
	    var fold = caseFold ? doFold : noFold
	    var lines = fold(query).split(/\r|\n\r?/)
	
	    search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) {
	      var orig = doc.getLine(line)
	      if (ch > -1) orig = orig.slice(0, ch)
	      var string = fold(orig)
	      if (lines.length == 1) {
	        var found = string.lastIndexOf(lines[0])
	        if (found == -1) continue search
	        return {from: Pos(line, adjustPos(orig, string, found)),
	                to: Pos(line, adjustPos(orig, string, found + lines[0].length))}
	      } else {
	        var lastLine = lines[lines.length - 1]
	        if (string.slice(0, lastLine.length) != lastLine) continue search
	        for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++)
	          if (fold(doc.getLine(start + i)) != lines[i]) continue search
	        var top = doc.getLine(line + 1 - lines.length), topString = fold(top)
	        if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search
	        return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length)),
	                to: Pos(line, adjustPos(orig, string, lastLine.length))}
	      }
	    }
	  }
	
	  function SearchCursor(doc, query, pos, options) {
	    this.atOccurrence = false
	    this.doc = doc
	    pos = pos ? doc.clipPos(pos) : Pos(0, 0)
	    this.pos = {from: pos, to: pos}
	
	    var caseFold
	    if (typeof options == "object") {
	      caseFold = options.caseFold
	    } else { // Backwards compat for when caseFold was the 4th argument
	      caseFold = options
	      options = null
	    }
	
	    if (typeof query == "string") {
	      if (caseFold == null) caseFold = false
	      this.matches = function(reverse, pos) {
	        return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold)
	      }
	    } else {
	      query = ensureGlobal(query)
	      if (!options || options.multiline !== false)
	        this.matches = function(reverse, pos) {
	          return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos)
	        }
	      else
	        this.matches = function(reverse, pos) {
	          return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos)
	        }
	    }
	  }
	
	  SearchCursor.prototype = {
	    findNext: function() {return this.find(false)},
	    findPrevious: function() {return this.find(true)},
	
	    find: function(reverse) {
	      var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
	
	      // Implements weird auto-growing behavior on null-matches for
	      // backwards-compatiblity with the vim code (unfortunately)
	      while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
	        if (reverse) {
	          if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
	          else if (result.from.line == this.doc.firstLine()) result = null
	          else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1)))
	        } else {
	          if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1)
	          else if (result.to.line == this.doc.lastLine()) result = null
	          else result = this.matches(reverse, Pos(result.to.line + 1, 0))
	        }
	      }
	
	      if (result) {
	        this.pos = result
	        this.atOccurrence = true
	        return this.pos.match || true
	      } else {
	        var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0)
	        this.pos = {from: end, to: end}
	        return this.atOccurrence = false
	      }
	    },
	
	    from: function() {if (this.atOccurrence) return this.pos.from},
	    to: function() {if (this.atOccurrence) return this.pos.to},
	
	    replace: function(newText, origin) {
	      if (!this.atOccurrence) return
	      var lines = CodeMirror.splitLines(newText)
	      this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin)
	      this.pos.to = Pos(this.pos.from.line + lines.length - 1,
	                        lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0))
	    }
	  }
	
	  CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
	    return new SearchCursor(this.doc, query, pos, caseFold)
	  })
	  CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
	    return new SearchCursor(this, query, pos, caseFold)
	  })
	
	  CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
	    var ranges = []
	    var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold)
	    while (cur.findNext()) {
	      if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break
	      ranges.push({anchor: cur.from(), head: cur.to()})
	    }
	    if (ranges.length)
	      this.setSelections(ranges, 0)
	  })
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/search/searchcursor.js **/


/** START DEFINE BLOCK for codemirror@5.27.2/addon/dialog/dialog.js **/
jupyter.define('codemirror@5.27.2/addon/dialog/dialog.js', function (module, exports, __jupyter_require__) {
	// CodeMirror, copyright (c) by Marijn Haverbeke and others
	// Distributed under an MIT license: http://codemirror.net/LICENSE
	
	// Open simple dialogs on top of an editor. Relies on dialog.css.
	
	(function(mod) {
	  if (true) // CommonJS
	    mod(__jupyter_require__('codemirror@5.27.2/lib/codemirror.js'));
	  else if (typeof define == "function" && define.amd) // AMD
	    define(["../../lib/codemirror"], mod);
	  else // Plain browser env
	    mod(CodeMirror);
	})(function(CodeMirror) {
	  function dialogDiv(cm, template, bottom) {
	    var wrap = cm.getWrapperElement();
	    var dialog;
	    dialog = wrap.appendChild(document.createElement("div"));
	    if (bottom)
	      dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
	    else
	      dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
	
	    if (typeof template == "string") {
	      dialog.innerHTML = template;
	    } else { // Assuming it's a detached DOM element.
	      dialog.appendChild(template);
	    }
	    return dialog;
	  }
	
	  function closeNotification(cm, newVal) {
	    if (cm.state.currentNotificationClose)
	      cm.state.currentNotificationClose();
	    cm.state.currentNotificationClose = newVal;
	  }
	
	  CodeMirror.defineExtension("openDialog", function(template, callback, options) {
	    if (!options) options = {};
	
	    closeNotification(this, null);
	
	    var dialog = dialogDiv(this, template, options.bottom);
	    var closed = false, me = this;
	    function close(newVal) {
	      if (typeof newVal == 'string') {
	        inp.value = newVal;
	      } else {
	        if (closed) return;
	        closed = true;
	        dialog.parentNode.removeChild(dialog);
	        me.focus();
	
	        if (options.onClose) options.onClose(dialog);
	      }
	    }
	
	    var inp = dialog.getElementsByTagName("input")[0], button;
	    if (inp) {
	      inp.focus();
	
	      if (options.value) {
	        inp.value = options.value;
	        if (options.selectValueOnOpen !== false) {
	          inp.select();
	        }
	      }
	
	      if (options.onInput)
	        CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
	      if (options.onKeyUp)
	        CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
	
	      CodeMirror.on(inp, "keydown", function(e) {
	        if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
	        if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
	          inp.blur();
	          CodeMirror.e_stop(e);
	          close();
	        }
	        if (e.keyCode == 13) callback(inp.value, e);
	      });
	
	      if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
	    } else if (button = dialog.getElementsByTagName("button")[0]) {
	      CodeMirror.on(button, "click", function() {
	        close();
	        me.focus();
	      });
	
	      if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
	
	      button.focus();
	    }
	    return close;
	  });
	
	  CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
	    closeNotification(this, null);
	    var dialog = dialogDiv(this, template, options && options.bottom);
	    var buttons = dialog.getElementsByTagName("button");
	    var closed = false, me = this, blurring = 1;
	    function close() {
	      if (closed) return;
	      closed = true;
	      dialog.parentNode.removeChild(dialog);
	      me.focus();
	    }
	    buttons[0].focus();
	    for (var i = 0; i < buttons.length; ++i) {
	      var b = buttons[i];
	      (function(callback) {
	        CodeMirror.on(b, "click", function(e) {
	          CodeMirror.e_preventDefault(e);
	          close();
	          if (callback) callback(me);
	        });
	      })(callbacks[i]);
	      CodeMirror.on(b, "blur", function() {
	        --blurring;
	        setTimeout(function() { if (blurring <= 0) close(); }, 200);
	      });
	      CodeMirror.on(b, "focus", function() { ++blurring; });
	    }
	  });
	
	  /*
	   * openNotification
	   * Opens a notification, that can be closed with an optional timer
	   * (default 5000ms timer) and always closes on click.
	   *
	   * If a notification is opened while another is opened, it will close the
	   * currently opened one and open the new one immediately.
	   */
	  CodeMirror.defineExtension("openNotification", function(template, options) {
	    closeNotification(this, close);
	    var dialog = dialogDiv(this, template, options && options.bottom);
	    var closed = false, doneTimer;
	    var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
	
	    function close() {
	      if (closed) return;
	      closed = true;
	      clearTimeout(doneTimer);
	      dialog.parentNode.removeChild(dialog);
	    }
	
	    CodeMirror.on(dialog, 'click', function(e) {
	      CodeMirror.e_preventDefault(e);
	      close();
	    });
	
	    if (duration)
	      doneTimer = setTimeout(close, duration);
	
	    return close;
	  });
	});
	
})
/** END DEFINE BLOCK for codemirror@5.27.2/addon/dialog/dialog.js **/


/** START DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/mimetype.js **/
jupyter.define('@jupyterlab/codemirror@0.3.1/lib/mimetype.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var CodeMirror = __jupyter_require__('codemirror@^5.24.2/lib/codemirror.js');
	var codeeditor_1 = __jupyter_require__('@jupyterlab/codeeditor@^0.3.1/lib/index.js');
	var coreutils_1 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	var _1 = __jupyter_require__('@jupyterlab/codemirror@0.3.1/lib/index.js');
	/**
	 * The mime type service for CodeMirror.
	 */
	var CodeMirrorMimeTypeService = (function () {
	    function CodeMirrorMimeTypeService() {
	    }
	    /**
	     * Returns a mime type for the given language info.
	     *
	     * #### Notes
	     * If a mime type cannot be found returns the defaul mime type `text/plain`, never `null`.
	     */
	    CodeMirrorMimeTypeService.prototype.getMimeTypeByLanguage = function (info) {
	        if (info.codemirror_mode) {
	            return _1.findMode(info.codemirror_mode).mime;
	        }
	        var mode = CodeMirror.findModeByMIME(info.mimetype || '');
	        if (mode) {
	            return info.mimetype;
	        }
	        var ext = info.file_extension || '';
	        ext = ext.split('.').slice(-1)[0];
	        mode = CodeMirror.findModeByExtension(ext || '');
	        if (mode) {
	            return mode.mime;
	        }
	        mode = CodeMirror.findModeByName(info.name || '');
	        return mode ? mode.mime : codeeditor_1.IEditorMimeTypeService.defaultMimeType;
	    };
	    /**
	     * Returns a mime type for the given file path.
	     *
	     * #### Notes
	     * If a mime type cannot be found returns the defaul mime type `text/plain`, never `null`.
	     */
	    CodeMirrorMimeTypeService.prototype.getMimeTypeByFilePath = function (path) {
	        if (coreutils_1.PathExt.extname(path) === '.ipy') {
	            return 'text/x-python';
	        }
	        var mode = CodeMirror.findModeByFileName(path);
	        return mode ? mode.mime : codeeditor_1.IEditorMimeTypeService.defaultMimeType;
	    };
	    return CodeMirrorMimeTypeService;
	}());
	exports.CodeMirrorMimeTypeService = CodeMirrorMimeTypeService;
	
})
/** END DEFINE BLOCK for @jupyterlab/codemirror@0.3.1/lib/mimetype.js **/


/** START DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/index.js **/
jupyter.define('@jupyterlab/codeeditor@0.3.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	__export(__jupyter_require__('@jupyterlab/codeeditor@0.3.1/lib/editor.js'));
	__export(__jupyter_require__('@jupyterlab/codeeditor@0.3.1/lib/jsoneditor.js'));
	__export(__jupyter_require__('@jupyterlab/codeeditor@0.3.1/lib/widget.js'));
	__export(__jupyter_require__('@jupyterlab/codeeditor@0.3.1/lib/mimetype.js'));
	/* tslint:disable */
	/**
	 * Code editor services token.
	 */
	exports.IEditorServices = new coreutils_1.Token('jupyter.services.editorservices');
	
})
/** END DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/editor.js **/
jupyter.define('@jupyterlab/codeeditor@0.3.1/lib/editor.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	/**
	 * A namespace for code editors.
	 *
	 * #### Notes
	 * - A code editor is a set of common assumptions which hold for all concrete editors.
	 * - Changes in implementations of the code editor should only be caused by changes in concrete editors.
	 * - Common JLab services which are based on the code editor should belong to `IEditorServices`.
	 */
	var CodeEditor;
	(function (CodeEditor) {
	    /**
	     * The default implementation of the editor model.
	     */
	    var Model = (function () {
	        /**
	         * Construct a new Model.
	         */
	        function Model(options) {
	            this.modelDB = null;
	            this._isDisposed = false;
	            this._mimeTypeChanged = new signaling_1.Signal(this);
	            options = options || {};
	            if (options.modelDB) {
	                this.modelDB = options.modelDB;
	            }
	            else {
	                this.modelDB = new coreutils_1.ModelDB();
	            }
	            var value = this.modelDB.createString('value');
	            value.text = value.text || options.value || '';
	            var mimeType = this.modelDB.createValue('mimeType');
	            mimeType.set(options.mimeType || 'text/plain');
	            mimeType.changed.connect(this._onMimeTypeChanged, this);
	            this.modelDB.createMap('selections');
	        }
	        Object.defineProperty(Model.prototype, "mimeTypeChanged", {
	            /**
	             * A signal emitted when a mimetype changes.
	             */
	            get: function () {
	                return this._mimeTypeChanged;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(Model.prototype, "value", {
	            /**
	             * Get the value of the model.
	             */
	            get: function () {
	                return this.modelDB.get('value');
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(Model.prototype, "selections", {
	            /**
	             * Get the selections for the model.
	             */
	            get: function () {
	                return this.modelDB.get('selections');
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(Model.prototype, "mimeType", {
	            /**
	             * A mime type of the model.
	             */
	            get: function () {
	                return this.modelDB.getValue('mimeType');
	            },
	            set: function (newValue) {
	                var oldValue = this.mimeType;
	                if (oldValue === newValue) {
	                    return;
	                }
	                this.modelDB.setValue('mimeType', newValue);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        Object.defineProperty(Model.prototype, "isDisposed", {
	            /**
	             * Whether the model is disposed.
	             */
	            get: function () {
	                return this._isDisposed;
	            },
	            enumerable: true,
	            configurable: true
	        });
	        /**
	         * Dipose of the resources used by the model.
	         */
	        Model.prototype.dispose = function () {
	            if (this._isDisposed) {
	                return;
	            }
	            this._isDisposed = true;
	            signaling_1.Signal.clearData(this);
	        };
	        Model.prototype._onMimeTypeChanged = function (mimeType, args) {
	            this._mimeTypeChanged.emit({
	                name: 'mimeType',
	                oldValue: args.oldValue,
	                newValue: args.newValue
	            });
	        };
	        return Model;
	    }());
	    CodeEditor.Model = Model;
	})(CodeEditor = exports.CodeEditor || (exports.CodeEditor = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/editor.js **/


/** START DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/jsoneditor.js **/
jupyter.define('@jupyterlab/codeeditor@0.3.1/lib/jsoneditor.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	var virtualdom_1 = __jupyter_require__('@phosphor/virtualdom@1.1.1/lib/index.js');
	var _1 = __jupyter_require__('@jupyterlab/codeeditor@0.3.1/lib/index.js');
	/**
	 * The class name added to a JSONEditorWidget instance.
	 */
	var METADATA_CLASS = 'jp-JSONEditorWidget';
	/**
	 * The class name added when the Metadata editor contains invalid JSON.
	 */
	var ERROR_CLASS = 'jp-mod-error';
	/**
	 * The class name added to the editor host node.
	 */
	var HOST_CLASS = 'jp-JSONEditorWidget-host';
	/**
	 * The class name added to the button area.
	 */
	var BUTTON_AREA_CLASS = 'jp-JSONEditorWidget-buttons';
	/**
	 * The class name added to the revert button.
	 */
	var REVERT_CLASS = 'jp-JSONEditorWidget-revertButton';
	/**
	 * The class name added to the commit button.
	 */
	var COMMIT_CLASS = 'jp-JSONEditorWidget-commitButton';
	/**
	 * A widget for editing observable JSON.
	 */
	var JSONEditorWidget = (function (_super) {
	    __extends(JSONEditorWidget, _super);
	    /**
	     * Construct a new metadata editor.
	     */
	    function JSONEditorWidget(options) {
	        var _this = _super.call(this, { node: Private.createEditorNode() }) || this;
	        _this._dataDirty = false;
	        _this._inputDirty = false;
	        _this._source = null;
	        _this._originalValue = null;
	        _this._changeGuard = false;
	        _this.addClass(METADATA_CLASS);
	        var host = _this.editorHostNode;
	        var model = new _1.CodeEditor.Model();
	        model.value.text = 'No data!';
	        model.mimeType = 'application/json';
	        model.value.changed.connect(_this._onValueChanged, _this);
	        _this.model = model;
	        _this.editor = options.editorFactory({ host: host, model: model });
	        _this.editor.readOnly = true;
	        return _this;
	    }
	    Object.defineProperty(JSONEditorWidget.prototype, "editorHostNode", {
	        /**
	         * Get the editor host node used by the metadata editor.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(HOST_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(JSONEditorWidget.prototype, "revertButtonNode", {
	        /**
	         * Get the revert button used by the metadata editor.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(REVERT_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(JSONEditorWidget.prototype, "commitButtonNode", {
	        /**
	         * Get the commit button used by the metadata editor.
	         */
	        get: function () {
	            return this.node.getElementsByClassName(COMMIT_CLASS)[0];
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(JSONEditorWidget.prototype, "source", {
	        /**
	         * The observable source.
	         */
	        get: function () {
	            return this._source;
	        },
	        set: function (value) {
	            if (this._source === value) {
	                return;
	            }
	            if (this._source) {
	                this._source.changed.disconnect(this._onSourceChanged, this);
	            }
	            this._source = value;
	            this.editor.readOnly = !value;
	            if (value) {
	                value.changed.connect(this._onSourceChanged, this);
	            }
	            this._setValue();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(JSONEditorWidget.prototype, "isDirty", {
	        /**
	         * Get whether the editor is dirty.
	         */
	        get: function () {
	            return this._dataDirty || this._inputDirty;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Handle the DOM events for the widget.
	     *
	     * @param event - The DOM event sent to the widget.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the notebook panel's node. It should
	     * not be called directly by user code.
	     */
	    JSONEditorWidget.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'blur':
	                this._evtBlur(event);
	                break;
	            case 'click':
	                this._evtClick(event);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `after-attach` messages for the widget.
	     */
	    JSONEditorWidget.prototype.onAfterAttach = function (msg) {
	        var node = this.editorHostNode;
	        node.addEventListener('blur', this, true);
	        this.revertButtonNode.hidden = true;
	        this.commitButtonNode.hidden = true;
	        this.revertButtonNode.addEventListener('click', this);
	        this.commitButtonNode.addEventListener('click', this);
	    };
	    /**
	     * Handle `before-detach` messages for the widget.
	     */
	    JSONEditorWidget.prototype.onBeforeDetach = function (msg) {
	        var node = this.editorHostNode;
	        node.removeEventListener('blur', this, true);
	        this.revertButtonNode.removeEventListener('click', this);
	        this.commitButtonNode.removeEventListener('click', this);
	    };
	    /**
	     * Handle a change to the metadata of the source.
	     */
	    JSONEditorWidget.prototype._onSourceChanged = function (sender, args) {
	        if (this._changeGuard) {
	            return;
	        }
	        if (this._inputDirty || this.editor.hasFocus()) {
	            this._dataDirty = true;
	            return;
	        }
	        this._setValue();
	    };
	    /**
	     * Handle change events.
	     */
	    JSONEditorWidget.prototype._onValueChanged = function () {
	        var valid = true;
	        try {
	            var value = JSON.parse(this.editor.model.value.text);
	            this.removeClass(ERROR_CLASS);
	            this._inputDirty = (!this._changeGuard && !coreutils_1.JSONExt.deepEqual(value, this._originalValue));
	        }
	        catch (err) {
	            this.addClass(ERROR_CLASS);
	            this._inputDirty = true;
	            valid = false;
	        }
	        this.revertButtonNode.hidden = !this._inputDirty;
	        this.commitButtonNode.hidden = !valid || !this._inputDirty;
	    };
	    /**
	     * Handle blur events for the text area.
	     */
	    JSONEditorWidget.prototype._evtBlur = function (event) {
	        // Update the metadata if necessary.
	        if (!this._inputDirty && this._dataDirty) {
	            this._setValue();
	        }
	    };
	    /**
	     * Handle click events for the buttons.
	     */
	    JSONEditorWidget.prototype._evtClick = function (event) {
	        var target = event.target;
	        if (target === this.revertButtonNode) {
	            this._setValue();
	        }
	        else if (target === this.commitButtonNode) {
	            if (!this.commitButtonNode.hidden && !this.hasClass(ERROR_CLASS)) {
	                this._changeGuard = true;
	                this._mergeContent();
	                this._changeGuard = false;
	                this._setValue();
	            }
	        }
	    };
	    /**
	     * Merge the user content.
	     */
	    JSONEditorWidget.prototype._mergeContent = function () {
	        var model = this.editor.model;
	        var current = this._getContent() || {};
	        var old = this._originalValue;
	        var user = JSON.parse(model.value.text);
	        var source = this.source;
	        // If it is in user and has changed from old, set in current.
	        for (var key in user) {
	            if (!coreutils_1.JSONExt.deepEqual(user[key], old[key])) {
	                current[key] = user[key];
	            }
	        }
	        // If it was in old and is not in user, remove from current.
	        for (var key in old) {
	            if (!(key in user)) {
	                delete current[key];
	                source.delete(key);
	            }
	        }
	        // Set the values.
	        for (var key in current) {
	            source.set(key, current[key]);
	        }
	    };
	    /**
	     * Get the metadata from the owner.
	     */
	    JSONEditorWidget.prototype._getContent = function () {
	        var source = this._source;
	        if (!source) {
	            return void 0;
	        }
	        var content = {};
	        for (var _i = 0, _a = source.keys(); _i < _a.length; _i++) {
	            var key = _a[_i];
	            content[key] = source.get(key);
	        }
	        return content;
	    };
	    /**
	     * Set the value given the owner contents.
	     */
	    JSONEditorWidget.prototype._setValue = function () {
	        this._dataDirty = false;
	        this._inputDirty = false;
	        this.revertButtonNode.hidden = true;
	        this.commitButtonNode.hidden = true;
	        this.removeClass(ERROR_CLASS);
	        var model = this.editor.model;
	        var content = this._getContent();
	        this._changeGuard = true;
	        if (content === void 0) {
	            model.value.text = 'No data!';
	            this._originalValue = null;
	        }
	        else {
	            var value = JSON.stringify(content, null, 2);
	            model.value.text = value;
	            this._originalValue = content;
	        }
	        this.editor.refresh();
	        this._changeGuard = false;
	        this.commitButtonNode.hidden = true;
	        this.revertButtonNode.hidden = true;
	    };
	    return JSONEditorWidget;
	}(widgets_1.Widget));
	exports.JSONEditorWidget = JSONEditorWidget;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the node for the EditorWdiget.
	     */
	    function createEditorNode() {
	        var cancelTitle = 'Revert changes to data';
	        var confirmTitle = 'Commit changes to data';
	        return virtualdom_1.VirtualDOM.realize(virtualdom_1.h.div({ className: METADATA_CLASS }, virtualdom_1.h.div({ className: BUTTON_AREA_CLASS }, virtualdom_1.h.span({ className: REVERT_CLASS, title: cancelTitle }), virtualdom_1.h.span({ className: COMMIT_CLASS, title: confirmTitle })), virtualdom_1.h.div({ className: HOST_CLASS })));
	    }
	    Private.createEditorNode = createEditorNode;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/jsoneditor.js **/


/** START DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/widget.js **/
jupyter.define('@jupyterlab/codeeditor@0.3.1/lib/widget.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	/**
	 * The class name added to an editor widget that has a primary selection.
	 */
	var HAS_SELECTION_CLASS = 'jp-mod-has-primary-selection';
	/**
	 * A widget which hosts a code editor.
	 */
	var CodeEditorWidget = (function (_super) {
	    __extends(CodeEditorWidget, _super);
	    /**
	     * Construct a new code editor widget.
	     */
	    function CodeEditorWidget(options) {
	        var _this = _super.call(this) || this;
	        _this._editor = null;
	        _this._needsRefresh = false;
	        var editor = _this._editor = options.factory({
	            host: _this.node,
	            model: options.model,
	            uuid: options.uuid,
	            wordWrap: options.wordWrap,
	            readOnly: options.readOnly,
	            selectionStyle: options.selectionStyle
	        });
	        editor.model.selections.changed.connect(_this._onSelectionsChanged, _this);
	        return _this;
	    }
	    Object.defineProperty(CodeEditorWidget.prototype, "editor", {
	        /**
	         * Get the editor wrapped by the widget.
	         */
	        get: function () {
	            return this._editor;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CodeEditorWidget.prototype, "model", {
	        /**
	         * Get the model used by the widget.
	         */
	        get: function () {
	            return this._editor.model;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the widget.
	     */
	    CodeEditorWidget.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        _super.prototype.dispose.call(this);
	        this._editor.dispose();
	        this._editor = null;
	    };
	    /**
	     * Handle the DOM events for the widget.
	     *
	     * @param event - The DOM event sent to the widget.
	     *
	     * #### Notes
	     * This method implements the DOM `EventListener` interface and is
	     * called in response to events on the panel's DOM node. It should
	     * not be called directly by user code.
	     */
	    CodeEditorWidget.prototype.handleEvent = function (event) {
	        switch (event.type) {
	            case 'focus':
	                this._evtFocus(event);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle `'activate-request'` messages.
	     */
	    CodeEditorWidget.prototype.onActivateRequest = function (msg) {
	        this._editor.focus();
	    };
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    CodeEditorWidget.prototype.onAfterAttach = function (msg) {
	        _super.prototype.onAfterAttach.call(this, msg);
	        this.node.addEventListener('focus', this, true);
	        if (this.isVisible) {
	            this._editor.refresh();
	            this._needsRefresh = false;
	        }
	    };
	    /**
	     * A message handler invoked on an `'after-show'` message.
	     */
	    CodeEditorWidget.prototype.onAfterShow = function (msg) {
	        this._editor.refresh();
	        this._needsRefresh = false;
	    };
	    /**
	     * Handle `before-detach` messages for the widget.
	     */
	    CodeEditorWidget.prototype.onBeforeDetach = function (msg) {
	        this.node.removeEventListener('focus', this, true);
	    };
	    /**
	     * A message handler invoked on a `'resize'` message.
	     */
	    CodeEditorWidget.prototype.onResize = function (msg) {
	        if (msg.width >= 0 && msg.height >= 0) {
	            this._editor.setSize(msg);
	            this._needsRefresh = false;
	        }
	        else if (this._editor.hasFocus()) {
	            this._editor.refresh();
	            this._needsRefresh = false;
	        }
	        else {
	            this._needsRefresh = true;
	        }
	    };
	    /**
	     * Handle `focus` events for the widget.
	     */
	    CodeEditorWidget.prototype._evtFocus = function (event) {
	        if (this._needsRefresh) {
	            this._editor.refresh();
	            this._needsRefresh = false;
	        }
	    };
	    /**
	     * Handle a change in model selections.
	     */
	    CodeEditorWidget.prototype._onSelectionsChanged = function () {
	        var _a = this._editor.getSelection(), start = _a.start, end = _a.end;
	        if (start.column !== end.column || start.line !== end.line) {
	            this.addClass(HAS_SELECTION_CLASS);
	        }
	        else {
	            this.removeClass(HAS_SELECTION_CLASS);
	        }
	    };
	    return CodeEditorWidget;
	}(widgets_1.Widget));
	exports.CodeEditorWidget = CodeEditorWidget;
	
})
/** END DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/widget.js **/


/** START DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/mimetype.js **/
jupyter.define('@jupyterlab/codeeditor@0.3.1/lib/mimetype.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * A namespace for `IEditorMimeTypeService`.
	 */
	var IEditorMimeTypeService;
	(function (IEditorMimeTypeService) {
	    /**
	     * The default mime type.
	     */
	    IEditorMimeTypeService.defaultMimeType = 'text/plain';
	})(IEditorMimeTypeService = exports.IEditorMimeTypeService || (exports.IEditorMimeTypeService = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/codeeditor@0.3.1/lib/mimetype.js **/


/** START DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/registry.js **/
jupyter.define('@jupyterlab/docregistry@0.3.1/lib/registry.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var coreutils_2 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	/* tslint:disable */
	/**
	 * The document registry token.
	 */
	exports.IDocumentRegistry = new coreutils_1.Token('jupyter.services.document-registry');
	/**
	 * The document registry.
	 */
	var DocumentRegistry = (function () {
	    function DocumentRegistry() {
	        this._modelFactories = Object.create(null);
	        this._widgetFactories = Object.create(null);
	        this._defaultWidgetFactory = '';
	        this._defaultWidgetFactories = Object.create(null);
	        this._widgetFactoryExtensions = Object.create(null);
	        this._fileTypes = [];
	        this._creators = [];
	        this._extenders = Object.create(null);
	        this._changed = new signaling_1.Signal(this);
	    }
	    Object.defineProperty(DocumentRegistry.prototype, "changed", {
	        /**
	         * A signal emitted when the registry has changed.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DocumentRegistry.prototype, "isDisposed", {
	        /**
	         * Get whether the document registry has been disposed.
	         */
	        get: function () {
	            return this._widgetFactories === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the document registery.
	     */
	    DocumentRegistry.prototype.dispose = function () {
	        if (this._widgetFactories === null) {
	            return;
	        }
	        var widgetFactories = this._widgetFactories;
	        var modelFactories = this._modelFactories;
	        var extenders = this._extenders;
	        this._widgetFactories = null;
	        this._modelFactories = null;
	        this._extenders = null;
	        for (var modelName in modelFactories) {
	            modelFactories[modelName].dispose();
	        }
	        for (var widgetName in widgetFactories) {
	            widgetFactories[widgetName].dispose();
	        }
	        for (var widgetName in extenders) {
	            extenders[widgetName].length = 0;
	        }
	        this._fileTypes.length = 0;
	        this._creators.length = 0;
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * Add a widget factory to the registry.
	     *
	     * @param factory - The factory instance to register.
	     *
	     * @returns A disposable which will unregister the factory.
	     *
	     * #### Notes
	     * If a factory with the given `'displayName'` is already registered,
	     * a warning will be logged, and this will be a no-op.
	     * If `'*'` is given as a default extension, the factory will be registered
	     * as the global default.
	     * If an extension or global default is already registered, this factory
	     * will override the existing default.
	     */
	    DocumentRegistry.prototype.addWidgetFactory = function (factory) {
	        var _this = this;
	        var name = factory.name.toLowerCase();
	        if (this._widgetFactories[name]) {
	            console.warn("Duplicate registered factory " + name);
	            return new disposable_1.DisposableDelegate(null);
	        }
	        this._widgetFactories[name] = factory;
	        for (var _i = 0, _a = factory.defaultFor; _i < _a.length; _i++) {
	            var ext = _a[_i];
	            if (factory.fileExtensions.indexOf(ext) === -1) {
	                continue;
	            }
	            if (ext === '*') {
	                this._defaultWidgetFactory = name;
	            }
	            else {
	                this._defaultWidgetFactories[ext] = name;
	            }
	        }
	        // For convenience, store a mapping of ext -> name
	        for (var _b = 0, _c = factory.fileExtensions; _b < _c.length; _b++) {
	            var ext = _c[_b];
	            if (!this._widgetFactoryExtensions[ext]) {
	                this._widgetFactoryExtensions[ext] = [];
	            }
	            this._widgetFactoryExtensions[ext].push(name);
	        }
	        this._changed.emit({
	            type: 'widgetFactory',
	            name: name,
	            change: 'added'
	        });
	        return new disposable_1.DisposableDelegate(function () {
	            delete _this._widgetFactories[name];
	            if (_this._defaultWidgetFactory === name) {
	                _this._defaultWidgetFactory = '';
	            }
	            for (var _i = 0, _a = Object.keys(_this._defaultWidgetFactories); _i < _a.length; _i++) {
	                var ext = _a[_i];
	                if (_this._defaultWidgetFactories[ext] === name) {
	                    delete _this._defaultWidgetFactories[ext];
	                }
	            }
	            for (var _b = 0, _c = Object.keys(_this._widgetFactoryExtensions); _b < _c.length; _b++) {
	                var ext = _c[_b];
	                algorithm_1.ArrayExt.removeFirstOf(_this._widgetFactoryExtensions[ext], name);
	                if (_this._widgetFactoryExtensions[ext].length === 0) {
	                    delete _this._widgetFactoryExtensions[ext];
	                }
	            }
	            _this._changed.emit({
	                type: 'widgetFactory',
	                name: name,
	                change: 'removed'
	            });
	        });
	    };
	    /**
	     * Add a model factory to the registry.
	     *
	     * @param factory - The factory instance.
	     *
	     * @returns A disposable which will unregister the factory.
	     *
	     * #### Notes
	     * If a factory with the given `name` is already registered, or
	     * the given factory is already registered, a warning will be logged
	     * and this will be a no-op.
	     */
	    DocumentRegistry.prototype.addModelFactory = function (factory) {
	        var _this = this;
	        var name = factory.name.toLowerCase();
	        if (this._modelFactories[name]) {
	            console.warn("Duplicate registered factory " + name);
	            return new disposable_1.DisposableDelegate(null);
	        }
	        this._modelFactories[name] = factory;
	        this._changed.emit({
	            type: 'modelFactory',
	            name: name,
	            change: 'added'
	        });
	        return new disposable_1.DisposableDelegate(function () {
	            delete _this._modelFactories[name];
	            _this._changed.emit({
	                type: 'modelFactory',
	                name: name,
	                change: 'removed'
	            });
	        });
	    };
	    /**
	     * Add a widget extension to the registry.
	     *
	     * @param widgetName - The name of the widget factory.
	     *
	     * @param extension - A widget extension.
	     *
	     * @returns A disposable which will unregister the extension.
	     *
	     * #### Notes
	     * If the extension is already registered for the given
	     * widget name, a warning will be logged and this will be a no-op.
	     */
	    DocumentRegistry.prototype.addWidgetExtension = function (widgetName, extension) {
	        var _this = this;
	        widgetName = widgetName.toLowerCase();
	        if (!(widgetName in this._extenders)) {
	            this._extenders[widgetName] = [];
	        }
	        var extenders = this._extenders[widgetName];
	        var index = algorithm_1.ArrayExt.firstIndexOf(extenders, extension);
	        if (index !== -1) {
	            console.warn("Duplicate registered extension for " + widgetName);
	            return new disposable_1.DisposableDelegate(null);
	        }
	        this._extenders[widgetName].push(extension);
	        this._changed.emit({
	            type: 'widgetExtension',
	            name: null,
	            change: 'added'
	        });
	        return new disposable_1.DisposableDelegate(function () {
	            algorithm_1.ArrayExt.removeFirstOf(_this._extenders[widgetName], extension);
	            _this._changed.emit({
	                type: 'widgetExtension',
	                name: null,
	                change: 'removed'
	            });
	        });
	    };
	    /**
	     * Add a file type to the document registry.
	     *
	     * @params fileType - The file type object to register.
	     *
	     * @returns A disposable which will unregister the command.
	     *
	     * #### Notes
	     * These are used to populate the "Create New" dialog.
	     */
	    DocumentRegistry.prototype.addFileType = function (fileType) {
	        var _this = this;
	        this._fileTypes.push(fileType);
	        this._changed.emit({
	            type: 'fileType',
	            name: fileType.name,
	            change: 'added'
	        });
	        return new disposable_1.DisposableDelegate(function () {
	            algorithm_1.ArrayExt.removeFirstOf(_this._fileTypes, fileType);
	            _this._changed.emit({
	                type: 'fileType',
	                name: fileType.name,
	                change: 'removed'
	            });
	        });
	    };
	    /**
	     * Add a creator to the registry.
	     *
	     * @params creator - The file creator object to register.
	     *
	     * @returns A disposable which will unregister the creator.
	     */
	    DocumentRegistry.prototype.addCreator = function (creator) {
	        var _this = this;
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._creators, function (value) {
	            return value.name.localeCompare(creator.name) > 0;
	        });
	        if (index !== -1) {
	            algorithm_1.ArrayExt.insert(this._creators, index, creator);
	        }
	        else {
	            this._creators.push(creator);
	        }
	        this._changed.emit({
	            type: 'fileCreator',
	            name: creator.name,
	            change: 'added'
	        });
	        return new disposable_1.DisposableDelegate(function () {
	            algorithm_1.ArrayExt.removeFirstOf(_this._creators, creator);
	            _this._changed.emit({
	                type: 'fileCreator',
	                name: creator.name,
	                change: 'removed'
	            });
	        });
	    };
	    /**
	     * Get a list of the preferred widget factories.
	     *
	     * @param ext - An optional file extension to filter the results.
	     *
	     * @returns A new array of widget factories.
	     *
	     * #### Notes
	     * Only the widget factories whose associated model factory have
	     * been registered will be returned.
	     * The first item is considered the default. The returned iterator
	     * has widget factories in the following order:
	     * - extension-specific default factory
	     * - global default factory
	     * - all other extension-specific factories
	     * - all other global factories
	     */
	    DocumentRegistry.prototype.preferredWidgetFactories = function (ext) {
	        var _this = this;
	        if (ext === void 0) { ext = '*'; }
	        var factories = new Set();
	        ext = Private.normalizeExtension(ext);
	        var last = '.' + ext.split('.').pop();
	        // Start with the extension-specific default factory.
	        if (ext.length > 1) {
	            if (ext in this._defaultWidgetFactories) {
	                factories.add(this._defaultWidgetFactories[ext]);
	            }
	        }
	        // Handle multi-part extension default factories.
	        if (last !== ext) {
	            if (last in this._defaultWidgetFactories) {
	                factories.add(this._defaultWidgetFactories[last]);
	            }
	        }
	        // Add the global default factory.
	        if (this._defaultWidgetFactory) {
	            factories.add(this._defaultWidgetFactory);
	        }
	        // Add the extension-specific factories in registration order.
	        if (ext.length > 1) {
	            if (ext in this._widgetFactoryExtensions) {
	                algorithm_1.each(this._widgetFactoryExtensions[ext], function (n) {
	                    factories.add(n);
	                });
	            }
	        }
	        // Handle multi-part extension-specific factories.
	        if (last !== ext) {
	            if (last in this._widgetFactoryExtensions) {
	                algorithm_1.each(this._widgetFactoryExtensions[last], function (n) {
	                    factories.add(n);
	                });
	            }
	        }
	        // Add the rest of the global factories, in registration order.
	        if ('*' in this._widgetFactoryExtensions) {
	            algorithm_1.each(this._widgetFactoryExtensions['*'], function (n) {
	                factories.add(n);
	            });
	        }
	        // Construct the return list, checking to make sure the corresponding
	        // model factories are registered.
	        var factoryList = [];
	        factories.forEach(function (name) {
	            if (_this._widgetFactories[name].modelName in _this._modelFactories) {
	                factoryList.push(_this._widgetFactories[name]);
	            }
	        });
	        return factoryList;
	    };
	    /**
	     * Get the default widget factory for an extension.
	     *
	     * @param ext - An optional file extension to filter the results.
	     *
	     * @returns The default widget factory for an extension.
	     *
	     * #### Notes
	     * This is equivalent to the first value in [[preferredWidgetFactories]].
	     */
	    DocumentRegistry.prototype.defaultWidgetFactory = function (ext) {
	        if (ext === void 0) { ext = '*'; }
	        return this.preferredWidgetFactories(ext)[0];
	    };
	    /**
	     * Create an iterator over the widget factories that have been registered.
	     *
	     * @returns A new iterator of widget factories.
	     */
	    DocumentRegistry.prototype.widgetFactories = function () {
	        var _this = this;
	        return algorithm_1.map(Object.keys(this._widgetFactories), function (name) {
	            return _this._widgetFactories[name];
	        });
	    };
	    /**
	     * Create an iterator over the model factories that have been registered.
	     *
	     * @returns A new iterator of model factories.
	     */
	    DocumentRegistry.prototype.modelFactories = function () {
	        var _this = this;
	        return algorithm_1.map(Object.keys(this._modelFactories), function (name) {
	            return _this._modelFactories[name];
	        });
	    };
	    /**
	     * Create an iterator over the registered extensions for a given widget.
	     *
	     * @param widgetName - The name of the widget factory.
	     *
	     * @returns A new iterator over the widget extensions.
	     */
	    DocumentRegistry.prototype.widgetExtensions = function (widgetName) {
	        widgetName = widgetName.toLowerCase();
	        if (!(widgetName in this._extenders)) {
	            return algorithm_1.empty();
	        }
	        return new algorithm_1.ArrayIterator(this._extenders[widgetName]);
	    };
	    /**
	     * Create an iterator over the file types that have been registered.
	     *
	     * @returns A new iterator of file types.
	     */
	    DocumentRegistry.prototype.fileTypes = function () {
	        return new algorithm_1.ArrayIterator(this._fileTypes);
	    };
	    /**
	     * Create an iterator over the file creators that have been registered.
	     *
	     * @returns A new iterator of file creatores.
	     */
	    DocumentRegistry.prototype.creators = function () {
	        return new algorithm_1.ArrayIterator(this._creators);
	    };
	    /**
	     * Get a widget factory by name.
	     *
	     * @param widgetName - The name of the widget factory.
	     *
	     * @returns A widget factory instance.
	     */
	    DocumentRegistry.prototype.getWidgetFactory = function (widgetName) {
	        return this._widgetFactories[widgetName.toLowerCase()];
	    };
	    /**
	     * Get a model factory by name.
	     *
	     * @param name - The name of the model factory.
	     *
	     * @returns A model factory instance.
	     */
	    DocumentRegistry.prototype.getModelFactory = function (name) {
	        return this._modelFactories[name.toLowerCase()];
	    };
	    /**
	     * Get a file type by name.
	     */
	    DocumentRegistry.prototype.getFileType = function (name) {
	        name = name.toLowerCase();
	        return algorithm_1.find(this._fileTypes, function (fileType) {
	            return fileType.name.toLowerCase() === name;
	        });
	    };
	    /**
	     * Get a creator by name.
	     */
	    DocumentRegistry.prototype.getCreator = function (name) {
	        name = name.toLowerCase();
	        return algorithm_1.find(this._creators, function (creator) {
	            return creator.name.toLowerCase() === name;
	        });
	    };
	    /**
	     * Get a kernel preference.
	     *
	     * @param ext - The file extension.
	     *
	     * @param widgetName - The name of the widget factory.
	     *
	     * @param kernel - An optional existing kernel model.
	     *
	     * @returns A kernel preference.
	     */
	    DocumentRegistry.prototype.getKernelPreference = function (ext, widgetName, kernel) {
	        ext = Private.normalizeExtension(ext);
	        widgetName = widgetName.toLowerCase();
	        var widgetFactory = this._widgetFactories[widgetName];
	        if (!widgetFactory) {
	            return void 0;
	        }
	        var modelFactory = this.getModelFactory(widgetFactory.modelName);
	        if (!modelFactory) {
	            return void 0;
	        }
	        var language = modelFactory.preferredLanguage(ext);
	        var name = kernel && kernel.name;
	        var id = kernel && kernel.id;
	        return {
	            id: id,
	            name: name,
	            language: language,
	            shouldStart: widgetFactory.preferKernel,
	            canStart: widgetFactory.canStartKernel
	        };
	    };
	    return DocumentRegistry;
	}());
	exports.DocumentRegistry = DocumentRegistry;
	/**
	 * The namespace for the `DocumentRegistry` class statics.
	 */
	(function (DocumentRegistry) {
	    /**
	     * Get the extension name of a path.
	     *
	     * @param file - string.
	     *
	     * #### Notes
	     * Dotted filenames (e.g. `".table.json"` are allowed.
	     */
	    function extname(path) {
	        var parts = coreutils_2.PathExt.basename(path).split('.');
	        parts.shift();
	        return '.' + parts.join('.');
	    }
	    DocumentRegistry.extname = extname;
	})(DocumentRegistry = exports.DocumentRegistry || (exports.DocumentRegistry = {}));
	exports.DocumentRegistry = DocumentRegistry;
	/**
	 * A private namespace for DocumentRegistry data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Normalize a file extension to be of the type `'.foo'`.
	     *
	     * Adds a leading dot if not present and converts to lower case.
	     */
	    function normalizeExtension(extension) {
	        if (extension === '*') {
	            return extension;
	        }
	        if (extension === '.*') {
	            return '*';
	        }
	        if (extension.indexOf('.') !== 0) {
	            extension = "." + extension;
	        }
	        return extension.toLowerCase();
	    }
	    Private.normalizeExtension = normalizeExtension;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/docregistry@0.3.1/lib/registry.js **/


/** START DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/output.js **/
jupyter.define('@jupyterlab/nbwidgets@0.6.17/lib/output.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	"use strict";
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var jupyter_js_widgets_1 = __jupyter_require__('jupyter-js-widgets@3.0.0-alpha.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.1.0/lib/index.js');
	var outputarea_1 = __jupyter_require__('@jupyterlab/outputarea@^0.3.0/lib/index.js');
	var _ = __jupyter_require__('underscore@1.8.3/underscore.js');
	var $ = __jupyter_require__('jquery@3.2.1/dist/jquery.js');
	var OutputModel = (function (_super) {
	    __extends(OutputModel, _super);
	    function OutputModel() {
	        var _this = _super !== null && _super.apply(this, arguments) || this;
	        _this._msgHook = null;
	        return _this;
	    }
	    OutputModel.prototype.defaults = function () {
	        return _.extend(_super.prototype.defaults.call(this), {
	            _model_name: 'OutputModel',
	            _view_name: 'OutputView',
	            msg_id: ''
	        });
	    };
	    OutputModel.prototype.initialize = function (attributes, options) {
	        var _this = this;
	        _super.prototype.initialize.call(this, attributes, options);
	        this._outputs = new outputarea_1.OutputAreaModel();
	        this.listenTo(this, 'change:msg_id', this.reset_msg_id);
	        this.widget_manager.context.session.kernelChanged.connect(function (sender, kernel) {
	            _this._msgHook.dispose();
	        });
	        this.reset_msg_id();
	    };
	    OutputModel.prototype.reset_msg_id = function () {
	        var _this = this;
	        if (this._msgHook) {
	            this._msgHook.dispose();
	        }
	        this._msgHook = null;
	        var kernel = this.widget_manager.context.session.kernel;
	        var msgId = this.get('msg_id');
	        if (msgId && kernel) {
	            this._msgHook = kernel.registerMessageHook(this.get('msg_id'), function (msg) {
	                _this.add(msg);
	                return false;
	            });
	        }
	    };
	    OutputModel.prototype.add = function (msg) {
	        var msgType = msg.header.msg_type;
	        switch (msgType) {
	            case 'execute_result':
	            case 'display_data':
	            case 'stream':
	            case 'error':
	                var model = msg.content;
	                model.output_type = msgType;
	                this._outputs.add(model);
	                break;
	            case 'clear_output':
	                this.clear_output(msg.content.wait);
	                break;
	            default:
	                break;
	        }
	    };
	    OutputModel.prototype.clear_output = function (wait) {
	        if (wait === void 0) { wait = false; }
	        this._outputs.clear(wait);
	    };
	    Object.defineProperty(OutputModel.prototype, "outputs", {
	        get: function () {
	            return this._outputs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return OutputModel;
	}(jupyter_js_widgets_1.DOMWidgetModel));
	exports.OutputModel = OutputModel;
	var OutputView = (function (_super) {
	    __extends(OutputView, _super);
	    function OutputView() {
	        return _super !== null && _super.apply(this, arguments) || this;
	    }
	    OutputView.prototype._createElement = function (tagName) {
	        this.pWidget = new widgets_1.Panel();
	        return this.pWidget.node;
	    };
	    OutputView.prototype._setElement = function (el) {
	        if (this.el || el !== this.pWidget.node) {
	            // Boxes don't allow setting the element beyond the initial creation.
	            throw new Error('Cannot reset the DOM element.');
	        }
	        this.el = this.pWidget.node;
	        this.$el = $(this.pWidget.node);
	    };
	    /**
	     * Called when view is rendered.
	     */
	    OutputView.prototype.render = function () {
	        this._outputView = new outputarea_1.OutputAreaWidget({
	            rendermime: this.model.widget_manager.rendermime,
	            contentFactory: outputarea_1.OutputAreaWidget.defaultContentFactory,
	            model: this.model.outputs
	        });
	        // TODO: why is this a readonly property now?
	        //this._outputView.model = this.model.outputs;
	        // TODO: why is this on the model now?
	        //this._outputView.trusted = true;
	        this.pWidget.insertWidget(0, this._outputView);
	        this.pWidget.addClass('jupyter-widgets');
	        this.pWidget.addClass('widget-output');
	        this.update(); // Set defaults.
	    };
	    /**
	     * Update the contents of this view
	     *
	     * Called when the model is changed.  The model may have been
	     * changed by another view or by a state update from the back-end.
	     */
	    OutputView.prototype.update = function () {
	        return _super.prototype.update.call(this);
	    };
	    OutputView.prototype.remove = function () {
	        this._outputView.dispose();
	        return _super.prototype.remove.call(this);
	    };
	    return OutputView;
	}(jupyter_js_widgets_1.DOMWidgetView));
	exports.OutputView = OutputView;
	
})
/** END DEFINE BLOCK for @jupyterlab/nbwidgets@0.6.17/lib/output.js **/


/** START DEFINE BLOCK for @jupyterlab/outputarea@0.3.2/lib/index.js **/
jupyter.define('@jupyterlab/outputarea@0.3.2/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('@jupyterlab/outputarea@0.3.2/lib/model.js'));
	__export(__jupyter_require__('@jupyterlab/outputarea@0.3.2/lib/widget.js'));
	
})
/** END DEFINE BLOCK for @jupyterlab/outputarea@0.3.2/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/outputarea@0.3.2/lib/model.js **/
jupyter.define('@jupyterlab/outputarea@0.3.2/lib/model.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	var rendermime_1 = __jupyter_require__('@jupyterlab/rendermime@^0.3.2/lib/index.js');
	/**
	 * The default implementation of the IOutputAreaModel.
	 */
	var OutputAreaModel = (function () {
	    /**
	     * Construct a new observable outputs instance.
	     */
	    function OutputAreaModel(options) {
	        if (options === void 0) { options = {}; }
	        var _this = this;
	        this.clearNext = false;
	        this.list = null;
	        this._trusted = false;
	        this._isDisposed = false;
	        this._stateChanged = new signaling_1.Signal(this);
	        this._changed = new signaling_1.Signal(this);
	        this._modelDB = null;
	        this._serialized = null;
	        this._changeGuard = false;
	        this._trusted = !!options.trusted;
	        this.contentFactory = (options.contentFactory ||
	            OutputAreaModel.defaultContentFactory);
	        this.list = new coreutils_1.ObservableVector();
	        if (options.values) {
	            algorithm_1.each(options.values, function (value) { _this._add(value); });
	        }
	        this.list.changed.connect(this._onListChanged, this);
	        // If we are given a IModelDB, keep an up-to-date
	        // serialized copy of the OutputAreaModel in it.
	        if (options.modelDB) {
	            this._modelDB = options.modelDB;
	            this._serialized = this._modelDB.createValue('outputs');
	            if (this._serialized.get()) {
	                this.fromJSON(this._serialized.get());
	            }
	            else {
	                this._serialized.set(this.toJSON());
	            }
	            this._serialized.changed.connect(this._onSerializedChanged, this);
	        }
	    }
	    Object.defineProperty(OutputAreaModel.prototype, "stateChanged", {
	        /**
	         * A signal emitted when the model state changes.
	         */
	        get: function () {
	            return this._stateChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OutputAreaModel.prototype, "changed", {
	        /**
	         * A signal emitted when the model changes.
	         */
	        get: function () {
	            return this._changed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OutputAreaModel.prototype, "length", {
	        /**
	         * Get the length of the items in the model.
	         */
	        get: function () {
	            return this.list ? this.list.length : 0;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OutputAreaModel.prototype, "trusted", {
	        /**
	         * Get whether the model is trusted.
	         */
	        get: function () {
	            return this._trusted;
	        },
	        /**
	         * Set whether the model is trusted.
	         *
	         * #### Notes
	         * Changing the value will cause all of the models to re-set.
	         */
	        set: function (value) {
	            if (value === this._trusted) {
	                return;
	            }
	            var trusted = this._trusted = value;
	            for (var i = 0; i < this.list.length; i++) {
	                var item = this.list.at(i);
	                var value_1 = item.toJSON();
	                item.dispose();
	                item = this._createItem({ value: value_1, trusted: trusted });
	                this.list.set(i, item);
	            }
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OutputAreaModel.prototype, "isDisposed", {
	        /**
	         * Test whether the model is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the model.
	     */
	    OutputAreaModel.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        this.list.dispose();
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * Get an item at the specified index.
	     */
	    OutputAreaModel.prototype.get = function (index) {
	        return this.list.at(index);
	    };
	    /**
	     * Add an output, which may be combined with previous output.
	     *
	     * #### Notes
	     * The output bundle is copied.
	     * Contiguous stream outputs of the same `name` are combined.
	     */
	    OutputAreaModel.prototype.add = function (output) {
	        // If we received a delayed clear message, then clear now.
	        if (this.clearNext) {
	            this.clear();
	            this.clearNext = false;
	        }
	        return this._add(output);
	    };
	    /**
	     * Clear all of the output.
	     *
	     * @param wait Delay clearing the output until the next message is added.
	     */
	    OutputAreaModel.prototype.clear = function (wait) {
	        if (wait === void 0) { wait = false; }
	        this._lastStream = '';
	        if (wait) {
	            this.clearNext = true;
	            return;
	        }
	        algorithm_1.each(this.list, function (item) { item.dispose(); });
	        this.list.clear();
	    };
	    /**
	     * Deserialize the model from JSON.
	     *
	     * #### Notes
	     * This will clear any existing data.
	     */
	    OutputAreaModel.prototype.fromJSON = function (values) {
	        var _this = this;
	        this.clear();
	        algorithm_1.each(values, function (value) { _this._add(value); });
	    };
	    /**
	     * Serialize the model to JSON.
	     */
	    OutputAreaModel.prototype.toJSON = function () {
	        return algorithm_1.toArray(algorithm_1.map(this.list, function (output) { return output.toJSON(); }));
	    };
	    /**
	     * Add an item to the list.
	     */
	    OutputAreaModel.prototype._add = function (value) {
	        var trusted = this._trusted;
	        // Normalize stream data.
	        if (coreutils_1.nbformat.isStream(value)) {
	            if (Array.isArray(value.text)) {
	                value.text = value.text.join('\n');
	            }
	        }
	        // Consolidate outputs if they are stream outputs of the same kind.
	        if (coreutils_1.nbformat.isStream(value) && this._lastStream &&
	            value.name === this._lastName) {
	            // In order to get a list change event, we add the previous
	            // text to the current item and replace the previous item.
	            // This also replaces the metadata of the last item.
	            this._lastStream += value.text;
	            value.text = this._lastStream;
	            var item_1 = this._createItem({ value: value, trusted: trusted });
	            var index = this.length - 1;
	            var prev = this.list.at(index);
	            prev.dispose();
	            this.list.set(index, item_1);
	            return index;
	        }
	        // Create the new item.
	        var item = this._createItem({ value: value, trusted: trusted });
	        // Update the stream information.
	        if (coreutils_1.nbformat.isStream(value)) {
	            this._lastStream = value.text;
	            this._lastName = value.name;
	        }
	        else {
	            this._lastStream = '';
	        }
	        // Add the item to our list and return the new length.
	        return this.list.pushBack(item);
	    };
	    /**
	     * Create an output item and hook up its signals.
	     */
	    OutputAreaModel.prototype._createItem = function (options) {
	        var factory = this.contentFactory;
	        var item = factory.createOutputModel(options);
	        item.data.changed.connect(this._onGenericChange, this);
	        item.metadata.changed.connect(this._onGenericChange, this);
	        return item;
	    };
	    /**
	     * Handle a change to the list.
	     */
	    OutputAreaModel.prototype._onListChanged = function (sender, args) {
	        if (this._serialized && !this._changeGuard) {
	            this._changeGuard = true;
	            this._serialized.set(this.toJSON());
	            this._changeGuard = false;
	        }
	        this._changed.emit(args);
	        this._stateChanged.emit(void 0);
	    };
	    /**
	     * If the serialized version of the outputs have changed due to a remote
	     * action, then update the model accordingly.
	     */
	    OutputAreaModel.prototype._onSerializedChanged = function (sender, args) {
	        if (!this._changeGuard) {
	            this._changeGuard = true;
	            this.fromJSON(args.newValue);
	            this._changeGuard = false;
	        }
	    };
	    /**
	     * Handle a change to an item.
	     */
	    OutputAreaModel.prototype._onGenericChange = function () {
	        this._stateChanged.emit(void 0);
	    };
	    return OutputAreaModel;
	}());
	exports.OutputAreaModel = OutputAreaModel;
	/**
	 * The namespace for OutputAreaModel class statics.
	 */
	(function (OutputAreaModel) {
	    /**
	     * The default implementation of a `IModelOutputFactory`.
	     */
	    var ContentFactory = (function () {
	        function ContentFactory() {
	        }
	        /**
	         * Create an output model.
	         */
	        ContentFactory.prototype.createOutputModel = function (options) {
	            return new rendermime_1.OutputModel(options);
	        };
	        return ContentFactory;
	    }());
	    OutputAreaModel.ContentFactory = ContentFactory;
	    /**
	     * The default output model factory.
	     */
	    OutputAreaModel.defaultContentFactory = new ContentFactory();
	})(OutputAreaModel = exports.OutputAreaModel || (exports.OutputAreaModel = {}));
	exports.OutputAreaModel = OutputAreaModel;
	
})
/** END DEFINE BLOCK for @jupyterlab/outputarea@0.3.2/lib/model.js **/


/** START DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/index.js **/
jupyter.define('@jupyterlab/rendermime@0.3.2/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	__export(__jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/latex.js'));
	__export(__jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/mimemodel.js'));
	__export(__jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/outputmodel.js'));
	__export(__jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/rendermime.js'));
	__export(__jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/renderers.js'));
	__export(__jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/widgets.js'));
	/* tslint:disable */
	/**
	 * The rendermime token.
	 */
	exports.IRenderMime = new coreutils_1.Token('jupyter.services.rendermime');
	
})
/** END DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/latex.js **/
jupyter.define('@jupyterlab/rendermime@0.3.2/lib/latex.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	// Some magic for deferring mathematical expressions to MathJax
	// by hiding them from the Markdown parser.
	// Some of the code here is adapted with permission from Davide Cervone
	// under the terms of the Apache2 license governing the MathJax project.
	// Other minor modifications are also due to StackExchange and are used with
	// permission.
	var inline = '$'; // the inline math delimiter
	// MATHSPLIT contains the pattern for math delimiters and special symbols
	// needed for searching for math in the text input.
	var MATHSPLIT = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[{}$]|[{}]|(?:\n\s*)+|@@\d+@@|\\\\(?:\(|\)|\[|\]))/i;
	// A module-level initialization flag.
	var initialized = false;
	/**
	 *  Break up the text into its component parts and search
	 *    through them for math delimiters, braces, linebreaks, etc.
	 *  Math delimiters must match and braces must balance.
	 *  Don't allow math to pass through a double linebreak
	 *    (which will be a paragraph).
	 */
	function removeMath(text) {
	    var math = []; // stores math strings for later
	    var start;
	    var end;
	    var last;
	    var braces;
	    var deTilde;
	    if (!initialized) {
	        init();
	        initialized = true;
	    }
	    // Except for extreme edge cases, this should catch precisely those pieces of the markdown
	    // source that will later be turned into code spans. While MathJax will not TeXify code spans,
	    // we still have to consider them at this point; the following issue has happened several times:
	    //
	    //     `$foo` and `$bar` are variables.  -->  <code>$foo ` and `$bar</code> are variables.
	    var hasCodeSpans = /`/.test(text);
	    if (hasCodeSpans) {
	        text = text.replace(/~/g, '~T').replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function (wholematch) { return wholematch.replace(/\$/g, '~D'); });
	        deTilde = function (text) {
	            return text.replace(/~([TD])/g, function (wholematch, character) { return (character === 'T') ? '~' : inline; });
	        };
	    }
	    else {
	        deTilde = function (text) { return text; };
	    }
	    var blocks = text.replace(/\r\n?/g, '\n').split(MATHSPLIT);
	    for (var i = 1, m = blocks.length; i < m; i += 2) {
	        var block = blocks[i];
	        if (block.charAt(0) === '@') {
	            //
	            //  Things that look like our math markers will get
	            //  stored and then retrieved along with the math.
	            //
	            blocks[i] = '@@' + math.length + '@@';
	            math.push(block);
	        }
	        else if (start) {
	            //
	            //  If we are in math, look for the end delimiter,
	            //    but don't go past double line breaks, and
	            //    and balance braces within the math.
	            //
	            if (block === end) {
	                if (braces) {
	                    last = i;
	                }
	                else {
	                    blocks = processMath(start, i, deTilde, math, blocks);
	                    start = null;
	                    end = null;
	                    last = null;
	                }
	            }
	            else if (block.match(/\n.*\n/)) {
	                if (last) {
	                    i = last;
	                    blocks = processMath(start, i, deTilde, math, blocks);
	                }
	                start = null;
	                end = null;
	                last = null;
	                braces = 0;
	            }
	            else if (block === '{') {
	                braces++;
	            }
	            else if (block === '}' && braces) {
	                braces--;
	            }
	        }
	        else {
	            //
	            //  Look for math start delimiters and when
	            //    found, set up the end delimiter.
	            //
	            if (block === inline || block === '$$') {
	                start = i;
	                end = block;
	                braces = 0;
	            }
	            else if (block === '\\\\\(' || block === '\\\\\[') {
	                start = i;
	                end = block.slice(-1) === '(' ? '\\\\\)' : '\\\\\]';
	                braces = 0;
	            }
	            else if (block.substr(1, 5) === 'begin') {
	                start = i;
	                end = '\\end' + block.substr(6);
	                braces = 0;
	            }
	        }
	    }
	    if (last) {
	        blocks = processMath(start, last, deTilde, math, blocks);
	        start = null;
	        end = null;
	        last = null;
	    }
	    return { text: deTilde(blocks.join('')), math: math };
	}
	exports.removeMath = removeMath;
	;
	/**
	 * Put back the math strings that were saved,
	 * and clear the math array (no need to keep it around).
	 */
	function replaceMath(text, math) {
	    /**
	     * Replace a math placeholder with its corresponding group.
	     * The math delimiters "\\(", "\\[", "\\)" and "\\]" are replaced
	     * removing one backslash in order to be interpreted correctly by MathJax.
	     */
	    var process = function (match, n) {
	        var group = math[n];
	        if (group.substr(0, 3) === "\\\\\(" &&
	            group.substr(group.length - 3) === "\\\\\)") {
	            group = "\\\(" + group.substring(3, group.length - 3) + "\\\)";
	        }
	        else if (group.substr(0, 3) === "\\\\\[" &&
	            group.substr(group.length - 3) === "\\\\\]") {
	            group = "\\\[" + group.substring(3, group.length - 3) + "\\\]";
	        }
	        return group;
	    };
	    // Replace all the math group placeholders in the text
	    // with the saved strings.
	    return text.replace(/@@(\d+)@@/g, process);
	}
	exports.replaceMath = replaceMath;
	;
	/**
	 * Typeset the math in a node.
	 */
	function typeset(node) {
	    if (!initialized) {
	        init();
	        initialized = true;
	    }
	    if (window.MathJax) {
	        MathJax.Hub.Queue(['Typeset', MathJax.Hub, node]);
	    }
	}
	exports.typeset = typeset;
	/**
	 * Initialize latex handling.
	 */
	function init() {
	    if (!window.MathJax) {
	        return;
	    }
	    MathJax.Hub.Config({
	        tex2jax: {
	            inlineMath: [['$', '$'], ['\\(', '\\)']],
	            displayMath: [['$$', '$$'], ['\\[', '\\]']],
	            processEscapes: true,
	            processEnvironments: true
	        },
	        // Center justify equations in code and markdown cells. Elsewhere
	        // we use CSS to left justify single line equations in code cells.
	        displayAlign: 'center',
	        CommonHTML: {
	            linebreaks: { automatic: true }
	        },
	        'HTML-CSS': {
	            availableFonts: [],
	            imageFont: null,
	            preferredFont: null,
	            webFont: 'STIX-Web',
	            styles: { '.MathJax_Display': { 'margin': 0 } },
	            linebreaks: { automatic: true }
	        },
	    });
	    MathJax.Hub.Configured();
	}
	/**
	 * Process math blocks.
	 *
	 * The math is in blocks i through j, so
	 *   collect it into one block and clear the others.
	 *  Replace &, <, and > by named entities.
	 *  For IE, put <br> at the ends of comments since IE removes \n.
	 *  Clear the current math positions and store the index of the
	 *   math, then push the math string onto the storage array.
	 *  The preProcess function is called on all blocks if it has been passed in
	 */
	function processMath(i, j, preProcess, math, blocks) {
	    var block = blocks.slice(i, j + 1).join('').replace(/&/g, '&amp;') // use HTML entity for &
	        .replace(/</g, '&lt;') // use HTML entity for <
	        .replace(/>/g, '&gt;') // use HTML entity for >
	    ;
	    if (navigator && navigator.appName === 'Microsoft Internet Explorer') {
	        block = block.replace(/(%[^\n]*)\n/g, '$1<br/>\n');
	    }
	    while (j > i) {
	        blocks[j] = '';
	        j--;
	    }
	    blocks[i] = '@@' + math.length + '@@'; // replace the current block text with a unique tag to find later
	    if (preProcess) {
	        block = preProcess(block);
	    }
	    math.push(block);
	    return blocks;
	}
	;
	
})
/** END DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/latex.js **/


/** START DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/mimemodel.js **/
jupyter.define('@jupyterlab/rendermime@0.3.2/lib/mimemodel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	/**
	 * The default mime model implementation.
	 */
	var MimeModel = (function () {
	    /**
	     * Construct a new mime model.
	     */
	    function MimeModel(options) {
	        if (options === void 0) { options = {}; }
	        this.trusted = !!options.trusted;
	        this.data = new coreutils_1.ObservableJSON({ values: options.data });
	        this.metadata = new coreutils_1.ObservableJSON({ values: options.metadata });
	    }
	    Object.defineProperty(MimeModel.prototype, "isDisposed", {
	        /**
	         * Test whether the model is disposed.
	         */
	        get: function () {
	            return this.data.isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the mime model.
	     */
	    MimeModel.prototype.dispose = function () {
	        this.data.dispose();
	        this.metadata.dispose();
	    };
	    /**
	     * Serialize the model as JSON data.
	     */
	    MimeModel.prototype.toJSON = function () {
	        return {
	            trusted: this.trusted,
	            data: this.data.toJSON(),
	            metadata: this.metadata.toJSON()
	        };
	    };
	    return MimeModel;
	}());
	exports.MimeModel = MimeModel;
	
})
/** END DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/mimemodel.js **/


/** START DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/outputmodel.js **/
jupyter.define('@jupyterlab/rendermime@0.3.2/lib/outputmodel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var coreutils_2 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	var mimemodel_1 = __jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/mimemodel.js');
	/**
	 * The default implementation of a notebook output model.
	 */
	var OutputModel = (function (_super) {
	    __extends(OutputModel, _super);
	    /**
	     * Construct a new output model.
	     */
	    function OutputModel(options) {
	        var _this = _super.call(this, Private.getBundleOptions(options)) || this;
	        _this._raw = {};
	        // Make a copy of the data.
	        var value = options.value;
	        for (var key in value) {
	            // Ignore data and metadata that were stripped.
	            switch (key) {
	                case 'data':
	                case 'metadata':
	                    break;
	                default:
	                    _this._raw[key] = Private.extract(value, key);
	            }
	        }
	        _this.type = value.output_type;
	        if (coreutils_2.nbformat.isExecuteResult(value)) {
	            _this.executionCount = value.execution_count;
	        }
	        else {
	            _this.executionCount = null;
	        }
	        return _this;
	    }
	    /**
	     * Serialize the model to JSON.
	     */
	    OutputModel.prototype.toJSON = function () {
	        var output = {};
	        for (var key in this._raw) {
	            output[key] = Private.extract(this._raw, key);
	        }
	        switch (this.type) {
	            case 'display_data':
	            case 'execute_result':
	                output['data'] = this.data.toJSON();
	                output['metadata'] = this.metadata.toJSON();
	                break;
	            default:
	                break;
	        }
	        // Remove transient data.
	        delete output['transient'];
	        return output;
	    };
	    return OutputModel;
	}(mimemodel_1.MimeModel));
	exports.OutputModel = OutputModel;
	/**
	 * The namespace for OutputModel statics.
	 */
	(function (OutputModel) {
	    /**
	     * Get the data for an output.
	     *
	     * @params output - A kernel output message payload.
	     *
	     * @returns - The data for the payload.
	     */
	    function getData(output) {
	        return Private.getData(output);
	    }
	    OutputModel.getData = getData;
	    /**
	     * Get the metadata from an output message.
	     *
	     * @params output - A kernel output message payload.
	     *
	     * @returns - The metadata for the payload.
	     */
	    function getMetadata(output) {
	        return Private.getMetadata(output);
	    }
	    OutputModel.getMetadata = getMetadata;
	})(OutputModel = exports.OutputModel || (exports.OutputModel = {}));
	exports.OutputModel = OutputModel;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Get the data from a notebook output.
	     */
	    function getData(output) {
	        var bundle = {};
	        if (coreutils_2.nbformat.isExecuteResult(output) || coreutils_2.nbformat.isDisplayData(output)) {
	            bundle = output.data;
	        }
	        else if (coreutils_2.nbformat.isStream(output)) {
	            if (output.name === 'stderr') {
	                bundle['application/vnd.jupyter.stderr'] = output.text;
	            }
	            else {
	                bundle['application/vnd.jupyter.stdout'] = output.text;
	            }
	        }
	        else if (coreutils_2.nbformat.isError(output)) {
	            var traceback = output.traceback.join('\n');
	            bundle['application/vnd.jupyter.stderr'] = (traceback || output.ename + ": " + output.evalue);
	        }
	        return convertBundle(bundle);
	    }
	    Private.getData = getData;
	    /**
	     * Get the metadata from an output message.
	     */
	    function getMetadata(output) {
	        var value = Object.create(null);
	        if (coreutils_2.nbformat.isExecuteResult(output) || coreutils_2.nbformat.isDisplayData(output)) {
	            for (var key in output.metadata) {
	                value[key] = extract(output.metadata, key);
	            }
	        }
	        return value;
	    }
	    Private.getMetadata = getMetadata;
	    /**
	     * Get the bundle options given output model options.
	     */
	    function getBundleOptions(options) {
	        var data = getData(options.value);
	        var metadata = getMetadata(options.value);
	        var trusted = !!options.trusted;
	        return { data: data, trusted: trusted, metadata: metadata };
	    }
	    Private.getBundleOptions = getBundleOptions;
	    /**
	     * Extract a value from a JSONObject.
	     */
	    function extract(value, key) {
	        var item = value[key];
	        if (coreutils_1.JSONExt.isPrimitive(item)) {
	            return item;
	        }
	        return JSON.parse(JSON.stringify(item));
	    }
	    Private.extract = extract;
	    /**
	     * Convert a mime bundle to mime data.
	     */
	    function convertBundle(bundle) {
	        var map = Object.create(null);
	        for (var mimeType in bundle) {
	            var item = bundle[mimeType];
	            // Convert multi-line strings to strings.
	            if (coreutils_1.JSONExt.isArray(item)) {
	                item = item.join('\n');
	            }
	            else if (!coreutils_1.JSONExt.isPrimitive(item)) {
	                item = JSON.parse(JSON.stringify(item));
	            }
	            map[mimeType] = item;
	        }
	        return map;
	    }
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/outputmodel.js **/


/** START DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/rendermime.js **/
jupyter.define('@jupyterlab/rendermime@0.3.2/lib/rendermime.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@jupyterlab/coreutils@^0.3.1/lib/index.js');
	var apputils_1 = __jupyter_require__('@jupyterlab/apputils@^0.3.1/lib/index.js');
	var mimemodel_1 = __jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/mimemodel.js');
	var renderers_1 = __jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/renderers.js');
	var widgets_1 = __jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/widgets.js');
	/**
	 * A composite renderer.
	 *
	 * The renderer is used to render mime models using registered
	 * mime renderers, selecting the preferred mime renderer to
	 * render the model into a widget.
	 */
	var RenderMime = (function () {
	    /**
	     * Construct a renderer.
	     */
	    function RenderMime(options) {
	        if (options === void 0) { options = {}; }
	        this._renderers = Object.create(null);
	        this._order = [];
	        if (options.items) {
	            for (var _i = 0, _a = options.items; _i < _a.length; _i++) {
	                var item = _a[_i];
	                this._order.push(item.mimeType);
	                this._renderers[item.mimeType] = item.renderer;
	            }
	        }
	        this.sanitizer = options.sanitizer || apputils_1.defaultSanitizer;
	        this._resolver = options.resolver || null;
	        this._handler = options.linkHandler || null;
	    }
	    Object.defineProperty(RenderMime.prototype, "resolver", {
	        /**
	         * The object used to resolve relative urls for the rendermime instance.
	         */
	        get: function () {
	            return this._resolver;
	        },
	        set: function (value) {
	            this._resolver = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(RenderMime.prototype, "linkHandler", {
	        /**
	         * The object used to handle path opening links.
	         */
	        get: function () {
	            return this._handler;
	        },
	        set: function (value) {
	            this._handler = value;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get an iterator over the ordered list of mimeTypes.
	     *
	     * #### Notes
	     * These mimeTypes are searched from beginning to end, and the first matching
	     * mimeType is used.
	     */
	    RenderMime.prototype.mimeTypes = function () {
	        return new algorithm_1.ArrayIterator(this._order);
	    };
	    /**
	     * Render a mime model.
	     *
	     * @param model - the mime model to render.
	     *
	     * #### Notes
	     * Renders the model using the preferred mime type.  See
	     * [[preferredMimeType]].
	     */
	    RenderMime.prototype.render = function (model) {
	        var mimeType = this.preferredMimeType(model);
	        if (!mimeType) {
	            return this._handleError(model);
	        }
	        var rendererOptions = {
	            mimeType: mimeType,
	            model: model,
	            resolver: this._resolver,
	            sanitizer: this.sanitizer,
	            linkHandler: this._handler
	        };
	        return this._renderers[mimeType].render(rendererOptions);
	    };
	    /**
	     * Find the preferred mimeType for a model.
	     *
	     * @param model - the mime model of interest.
	     *
	     * #### Notes
	     * The mimeTypes in the model are checked in preference order
	     * until a renderer returns `true` for `.canRender`.
	     */
	    RenderMime.prototype.preferredMimeType = function (model) {
	        var _this = this;
	        var sanitizer = this.sanitizer;
	        return algorithm_1.find(this._order, function (mimeType) {
	            if (model.data.has(mimeType)) {
	                var options = { mimeType: mimeType, model: model, sanitizer: sanitizer };
	                var renderer = _this._renderers[mimeType];
	                var canRender = false;
	                try {
	                    canRender = renderer.canRender(options);
	                }
	                catch (err) {
	                    console.error("Got an error when checking the renderer for the mimeType '" + mimeType + "'\n", err);
	                }
	                if (canRender) {
	                    return true;
	                }
	            }
	        });
	    };
	    /**
	     * Clone the rendermime instance with shallow copies of data.
	     *
	     * #### Notes
	     * The resolver is explicitly not cloned in this operation.
	     */
	    RenderMime.prototype.clone = function () {
	        var _this = this;
	        var items = algorithm_1.toArray(algorithm_1.map(this._order, function (mimeType) {
	            return { mimeType: mimeType, renderer: _this._renderers[mimeType] };
	        }));
	        return new RenderMime({
	            items: items,
	            sanitizer: this.sanitizer,
	            linkHandler: this._handler
	        });
	    };
	    /**
	     * Add a renderer by mimeType.
	     *
	     * @param item - A renderer item.
	     *
	     * @param index - The optional order index.
	     *
	     * ####Notes
	     * Negative indices count from the end, so -1 refers to the last index.
	     * Use the index of `.order.length` to add to the end of the render precedence list,
	     * which would make the new renderer the last choice.
	     * The renderer will replace an existing renderer for the given
	     * mimeType.
	     */
	    RenderMime.prototype.addRenderer = function (item, index) {
	        if (index === void 0) { index = 0; }
	        var mimeType = item.mimeType, renderer = item.renderer;
	        var orig = algorithm_1.ArrayExt.removeFirstOf(this._order, mimeType);
	        if (orig !== -1 && orig < index) {
	            index -= 1;
	        }
	        this._renderers[mimeType] = renderer;
	        algorithm_1.ArrayExt.insert(this._order, index, mimeType);
	    };
	    /**
	     * Remove a renderer by mimeType.
	     *
	     * @param mimeType - The mimeType of the renderer.
	     */
	    RenderMime.prototype.removeRenderer = function (mimeType) {
	        delete this._renderers[mimeType];
	        algorithm_1.ArrayExt.removeFirstOf(this._order, mimeType);
	    };
	    /**
	     * Get a renderer by mimeType.
	     *
	     * @param mimeType - The mimeType of the renderer.
	     *
	     * @returns The renderer for the given mimeType, or undefined if the mimeType is unknown.
	     */
	    RenderMime.prototype.getRenderer = function (mimeType) {
	        return this._renderers[mimeType];
	    };
	    /**
	     * Return a widget for an error.
	     */
	    RenderMime.prototype._handleError = function (model) {
	        var errModel = new mimemodel_1.MimeModel({
	            data: {
	                'application/vnd.jupyter.stderr': 'Unable to render data'
	            }
	        });
	        var options = {
	            mimeType: 'application/vnd.jupyter.stderr',
	            model: errModel,
	            sanitizer: this.sanitizer,
	        };
	        return new widgets_1.RenderedText(options);
	    };
	    return RenderMime;
	}());
	exports.RenderMime = RenderMime;
	/**
	 * The namespace for RenderMime statics.
	 */
	(function (RenderMime) {
	    /**
	     * Get an array of the default renderer items.
	     */
	    function getDefaultItems() {
	        var renderers = Private.defaultRenderers;
	        var items = [];
	        var mimes = {};
	        for (var _i = 0, renderers_2 = renderers; _i < renderers_2.length; _i++) {
	            var renderer = renderers_2[_i];
	            for (var _a = 0, _b = renderer.mimeTypes; _a < _b.length; _a++) {
	                var mime = _b[_a];
	                if (mime in mimes) {
	                    continue;
	                }
	                mimes[mime] = true;
	                items.push({ mimeType: mime, renderer: renderer });
	            }
	        }
	        return items;
	    }
	    RenderMime.getDefaultItems = getDefaultItems;
	    /**
	     * A default resolver that uses a session and a contents manager.
	     */
	    var UrlResolver = (function () {
	        /**
	         * Create a new url resolver for a console.
	         */
	        function UrlResolver(options) {
	            this._session = options.session;
	            this._contents = options.contents;
	        }
	        /**
	         * Resolve a relative url to a correct server path.
	         */
	        UrlResolver.prototype.resolveUrl = function (url) {
	            if (coreutils_1.URLExt.isLocal(url)) {
	                var cwd = coreutils_1.PathExt.dirname(this._session.path);
	                url = coreutils_1.PathExt.resolve(cwd, url);
	            }
	            return Promise.resolve(url);
	        };
	        /**
	         * Get the download url of a given absolute server path.
	         */
	        UrlResolver.prototype.getDownloadUrl = function (path) {
	            if (coreutils_1.URLExt.isLocal(path)) {
	                return this._contents.getDownloadUrl(path);
	            }
	            return Promise.resolve(path);
	        };
	        return UrlResolver;
	    }());
	    RenderMime.UrlResolver = UrlResolver;
	})(RenderMime = exports.RenderMime || (exports.RenderMime = {}));
	exports.RenderMime = RenderMime;
	/**
	 * The namespace for private module data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The default renderer instances.
	     */
	    Private.defaultRenderers = [
	        new renderers_1.JavaScriptRenderer(),
	        new renderers_1.HTMLRenderer(),
	        new renderers_1.MarkdownRenderer(),
	        new renderers_1.LatexRenderer(),
	        new renderers_1.SVGRenderer(),
	        new renderers_1.ImageRenderer(),
	        new renderers_1.PDFRenderer(),
	        new renderers_1.TextRenderer()
	    ];
	})(Private = exports.Private || (exports.Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/rendermime.js **/


/** START DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/renderers.js **/
jupyter.define('@jupyterlab/rendermime@0.3.2/lib/renderers.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var _1 = __jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/index.js');
	/**
	 * A renderer for raw html.
	 */
	var HTMLRenderer = (function () {
	    function HTMLRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['text/html'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    HTMLRenderer.prototype.canRender = function (options) {
	        return this.mimeTypes.indexOf(options.mimeType) !== -1;
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    HTMLRenderer.prototype.render = function (options) {
	        return new _1.RenderedHTML(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    HTMLRenderer.prototype.wouldSanitize = function (options) {
	        return !options.model.trusted;
	    };
	    return HTMLRenderer;
	}());
	exports.HTMLRenderer = HTMLRenderer;
	/**
	 * A renderer for `<img>` data.
	 */
	var ImageRenderer = (function () {
	    function ImageRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['image/png', 'image/jpeg', 'image/gif'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    ImageRenderer.prototype.canRender = function (options) {
	        return this.mimeTypes.indexOf(options.mimeType) !== -1;
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    ImageRenderer.prototype.render = function (options) {
	        return new _1.RenderedImage(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    ImageRenderer.prototype.wouldSanitize = function (options) {
	        return false;
	    };
	    return ImageRenderer;
	}());
	exports.ImageRenderer = ImageRenderer;
	/**
	 * A renderer for plain text and Jupyter console text data.
	 */
	var TextRenderer = (function () {
	    function TextRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['text/plain', 'application/vnd.jupyter.stdout',
	            'application/vnd.jupyter.stderr'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    TextRenderer.prototype.canRender = function (options) {
	        return this.mimeTypes.indexOf(options.mimeType) !== -1;
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    TextRenderer.prototype.render = function (options) {
	        return new _1.RenderedText(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    TextRenderer.prototype.wouldSanitize = function (options) {
	        return false;
	    };
	    return TextRenderer;
	}());
	exports.TextRenderer = TextRenderer;
	/**
	 * A renderer for raw `<script>` data.
	 */
	var JavaScriptRenderer = (function () {
	    function JavaScriptRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['text/javascript', 'application/javascript'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    JavaScriptRenderer.prototype.canRender = function (options) {
	        return (options.model.trusted &&
	            this.mimeTypes.indexOf(options.mimeType) !== -1);
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    JavaScriptRenderer.prototype.render = function (options) {
	        return new _1.RenderedJavaScript(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    JavaScriptRenderer.prototype.wouldSanitize = function (options) {
	        return false;
	    };
	    return JavaScriptRenderer;
	}());
	exports.JavaScriptRenderer = JavaScriptRenderer;
	/**
	 * A renderer for `<svg>` data.
	 */
	var SVGRenderer = (function () {
	    function SVGRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['image/svg+xml'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    SVGRenderer.prototype.canRender = function (options) {
	        return (options.model.trusted &&
	            this.mimeTypes.indexOf(options.mimeType) !== -1);
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    SVGRenderer.prototype.render = function (options) {
	        return new _1.RenderedSVG(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    SVGRenderer.prototype.wouldSanitize = function (options) {
	        return false;
	    };
	    return SVGRenderer;
	}());
	exports.SVGRenderer = SVGRenderer;
	/**
	 * A renderer for PDF data.
	 */
	var PDFRenderer = (function () {
	    function PDFRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['application/pdf'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    PDFRenderer.prototype.canRender = function (options) {
	        return (options.model.trusted &&
	            this.mimeTypes.indexOf(options.mimeType) !== -1);
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    PDFRenderer.prototype.render = function (options) {
	        return new _1.RenderedPDF(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    PDFRenderer.prototype.wouldSanitize = function (options) {
	        return false;
	    };
	    return PDFRenderer;
	}());
	exports.PDFRenderer = PDFRenderer;
	/**
	 * A renderer for LateX data.
	 */
	var LatexRenderer = (function () {
	    function LatexRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['text/latex'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    LatexRenderer.prototype.canRender = function (options) {
	        return this.mimeTypes.indexOf(options.mimeType) !== -1;
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    LatexRenderer.prototype.render = function (options) {
	        return new _1.RenderedLatex(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    LatexRenderer.prototype.wouldSanitize = function (options) {
	        return false;
	    };
	    return LatexRenderer;
	}());
	exports.LatexRenderer = LatexRenderer;
	/**
	 * A renderer for Jupyter Markdown data.
	 */
	var MarkdownRenderer = (function () {
	    function MarkdownRenderer() {
	        /**
	         * The mimeTypes this renderer accepts.
	         */
	        this.mimeTypes = ['text/markdown'];
	    }
	    /**
	     * Whether the renderer can render given the render options.
	     */
	    MarkdownRenderer.prototype.canRender = function (options) {
	        return this.mimeTypes.indexOf(options.mimeType) !== -1;
	    };
	    /**
	     * Render the transformed mime bundle.
	     */
	    MarkdownRenderer.prototype.render = function (options) {
	        return new _1.RenderedMarkdown(options);
	    };
	    /**
	     * Whether the renderer will sanitize the data given the render options.
	     */
	    MarkdownRenderer.prototype.wouldSanitize = function (options) {
	        return !options.model.trusted;
	    };
	    return MarkdownRenderer;
	}());
	exports.MarkdownRenderer = MarkdownRenderer;
	
})
/** END DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/renderers.js **/


/** START DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/widgets.js **/
jupyter.define('@jupyterlab/rendermime@0.3.2/lib/widgets.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var ansi_up_1 = __jupyter_require__('ansi_up@^1.3.0/ansi_up.js');
	var codemirror_1 = __jupyter_require__('@jupyterlab/codemirror@^0.3.1/lib/index.js');
	var marked = __jupyter_require__('marked@^0.3.6/lib/marked.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	var _1 = __jupyter_require__('@jupyterlab/rendermime@0.3.2/lib/index.js');
	/*
	 * The class name added to common rendered HTML.
	 */
	exports.HTML_COMMON_CLASS = 'jp-RenderedHTMLCommon';
	/*
	 * The class name added to rendered HTML.
	 */
	var HTML_CLASS = 'jp-RenderedHTML';
	/*
	 * The class name added to rendered markdown.
	 */
	var MARKDOWN_CLASS = 'jp-RenderedMarkdown';
	/*
	 * The class name added to rendered Latex.
	 */
	var LATEX_CLASS = 'jp-RenderedLatex';
	/*
	 * The class name added to rendered images.
	 */
	var IMAGE_CLASS = 'jp-RenderedImage';
	/*
	 * The class name added to rendered text.
	 */
	var TEXT_CLASS = 'jp-RenderedText';
	/**
	 * The class name added to an error output.
	 */
	var ERROR_CLASS = 'jp-mod-error';
	/*
	 * The class name added to rendered javascript.
	 */
	var JAVASCRIPT_CLASS = 'jp-RenderedJavascript';
	/*
	 * The class name added to rendered SVG.
	 */
	var SVG_CLASS = 'jp-RenderedSVG';
	/*
	 * The class name added to rendered PDF.
	 */
	var PDF_CLASS = 'jp-RenderedPDF';
	/*
	 * A widget for displaying any widget whoes representation is rendered HTML
	 * */
	var RenderedHTMLCommon = (function (_super) {
	    __extends(RenderedHTMLCommon, _super);
	    /* Construct a new rendered HTML common widget.*/
	    function RenderedHTMLCommon(options) {
	        var _this = _super.call(this) || this;
	        _this.addClass(exports.HTML_COMMON_CLASS);
	        return _this;
	    }
	    return RenderedHTMLCommon;
	}(widgets_1.Widget));
	exports.RenderedHTMLCommon = RenderedHTMLCommon;
	/**
	 * A widget for displaying HTML and rendering math.
	 */
	var RenderedHTML = (function (_super) {
	    __extends(RenderedHTML, _super);
	    /**
	     * Construct a new html widget.
	     */
	    function RenderedHTML(options) {
	        var _this = _super.call(this, options) || this;
	        _this._urlResolved = null;
	        _this.addClass(HTML_CLASS);
	        var source = Private.getSource(options);
	        if (!options.model.trusted) {
	            source = options.sanitizer.sanitize(source);
	        }
	        Private.appendHtml(_this.node, source);
	        if (options.resolver) {
	            _this._urlResolved = Private.handleUrls(_this.node, options.resolver, options.linkHandler);
	        }
	        return _this;
	    }
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    RenderedHTML.prototype.onAfterAttach = function (msg) {
	        var _this = this;
	        if (this._urlResolved) {
	            this._urlResolved.then(function () { _1.typeset(_this.node); });
	        }
	        else {
	            _1.typeset(this.node);
	        }
	    };
	    return RenderedHTML;
	}(RenderedHTMLCommon));
	exports.RenderedHTML = RenderedHTML;
	/**
	 * A widget for displaying Markdown with embeded latex.
	 */
	var RenderedMarkdown = (function (_super) {
	    __extends(RenderedMarkdown, _super);
	    /**
	     * Construct a new markdown widget.
	     */
	    function RenderedMarkdown(options) {
	        var _this = _super.call(this, options) || this;
	        _this._rendered = false;
	        _this._urlResolved = null;
	        _this.addClass(MARKDOWN_CLASS);
	        // Initialize the marked library if necessary.
	        Private.initializeMarked();
	        var source = Private.getSource(options);
	        var parts = _1.removeMath(source);
	        // Add the markdown content asynchronously.
	        marked(parts['text'], function (err, content) {
	            if (err) {
	                console.error(err);
	                return;
	            }
	            content = _1.replaceMath(content, parts['math']);
	            if (!options.model.trusted) {
	                content = options.sanitizer.sanitize(content);
	            }
	            Private.appendHtml(_this.node, content);
	            if (options.resolver) {
	                _this._urlResolved = Private.handleUrls(_this.node, options.resolver, options.linkHandler);
	            }
	            Private.headerAnchors(_this.node);
	            _this.fit();
	            _this._rendered = true;
	            if (_this.isAttached) {
	                if (_this._urlResolved) {
	                    _this._urlResolved.then(function () { _1.typeset(_this.node); });
	                }
	                else {
	                    _1.typeset(_this.node);
	                }
	            }
	        });
	        return _this;
	    }
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    RenderedMarkdown.prototype.onAfterAttach = function (msg) {
	        if (this._rendered) {
	            _1.typeset(this.node);
	        }
	    };
	    return RenderedMarkdown;
	}(RenderedHTMLCommon));
	exports.RenderedMarkdown = RenderedMarkdown;
	/**
	 * A widget for displaying LaTeX output.
	 */
	var RenderedLatex = (function (_super) {
	    __extends(RenderedLatex, _super);
	    /**
	     * Construct a new latex widget.
	     */
	    function RenderedLatex(options) {
	        var _this = _super.call(this) || this;
	        var source = Private.getSource(options);
	        _this.node.textContent = source;
	        _this.addClass(LATEX_CLASS);
	        return _this;
	    }
	    /**
	     * A message handler invoked on an `'after-attach'` message.
	     */
	    RenderedLatex.prototype.onAfterAttach = function (msg) {
	        _1.typeset(this.node);
	    };
	    return RenderedLatex;
	}(widgets_1.Widget));
	exports.RenderedLatex = RenderedLatex;
	/**
	 * A widget for displaying rendered images.
	 */
	var RenderedImage = (function (_super) {
	    __extends(RenderedImage, _super);
	    /**
	     * Construct a new rendered image widget.
	     */
	    function RenderedImage(options) {
	        var _this = _super.call(this) || this;
	        var img = document.createElement('img');
	        var source = Private.getSource(options);
	        img.src = "data:" + options.mimeType + ";base64," + source;
	        var metadata = options.model.metadata.get(options.mimeType);
	        if (metadata) {
	            var metaJSON = metadata;
	            if (typeof metaJSON['height'] === 'number') {
	                img.height = metaJSON['height'];
	            }
	            if (typeof metaJSON['width'] === 'number') {
	                img.width = metaJSON['width'];
	            }
	        }
	        _this.node.appendChild(img);
	        _this.addClass(IMAGE_CLASS);
	        return _this;
	    }
	    return RenderedImage;
	}(widgets_1.Widget));
	exports.RenderedImage = RenderedImage;
	/**
	 * A widget for displaying rendered text.
	 */
	var RenderedText = (function (_super) {
	    __extends(RenderedText, _super);
	    /**
	     * Construct a new rendered text widget.
	     */
	    function RenderedText(options) {
	        var _this = _super.call(this) || this;
	        var source = Private.getSource(options);
	        var data = ansi_up_1.escape_for_html(source);
	        var pre = document.createElement('pre');
	        pre.innerHTML = ansi_up_1.ansi_to_html(data);
	        _this.node.appendChild(pre);
	        _this.addClass(TEXT_CLASS);
	        if (options.mimeType === 'application/vnd.jupyter.stderr') {
	            _this.addClass(ERROR_CLASS);
	        }
	        return _this;
	    }
	    return RenderedText;
	}(widgets_1.Widget));
	exports.RenderedText = RenderedText;
	/**
	 * A widget for displaying rendered JavaScript.
	 */
	var RenderedJavaScript = (function (_super) {
	    __extends(RenderedJavaScript, _super);
	    /**
	     * Construct a new rendered JavaScript widget.
	     */
	    function RenderedJavaScript(options) {
	        var _this = _super.call(this) || this;
	        var s = document.createElement('script');
	        s.type = options.mimeType;
	        var source = Private.getSource(options);
	        s.textContent = source;
	        _this.node.appendChild(s);
	        _this.addClass(JAVASCRIPT_CLASS);
	        return _this;
	    }
	    return RenderedJavaScript;
	}(widgets_1.Widget));
	exports.RenderedJavaScript = RenderedJavaScript;
	/**
	 * A widget for displaying rendered SVG content.
	 */
	var RenderedSVG = (function (_super) {
	    __extends(RenderedSVG, _super);
	    /**
	     * Construct a new rendered SVG widget.
	     */
	    function RenderedSVG(options) {
	        var _this = _super.call(this) || this;
	        _this._urlResolved = null;
	        var source = Private.getSource(options);
	        _this.node.innerHTML = source;
	        var svgElement = _this.node.getElementsByTagName('svg')[0];
	        if (!svgElement) {
	            throw new Error('SVGRender: Error: Failed to create <svg> element');
	        }
	        if (options.resolver) {
	            _this._urlResolved = Private.handleUrls(_this.node, options.resolver, options.linkHandler);
	        }
	        _this.addClass(SVG_CLASS);
	        return _this;
	    }
	    return RenderedSVG;
	}(widgets_1.Widget));
	exports.RenderedSVG = RenderedSVG;
	/**
	 * A widget for displaying rendered PDF content.
	 */
	var RenderedPDF = (function (_super) {
	    __extends(RenderedPDF, _super);
	    /**
	     * Construct a new rendered PDF widget.
	     */
	    function RenderedPDF(options) {
	        var _this = _super.call(this) || this;
	        var source = Private.getSource(options);
	        var a = document.createElement('a');
	        a.target = '_blank';
	        a.textContent = 'View PDF';
	        a.href = "data:application/pdf;base64," + source;
	        _this.node.appendChild(a);
	        _this.addClass(PDF_CLASS);
	        return _this;
	    }
	    return RenderedPDF;
	}(widgets_1.Widget));
	exports.RenderedPDF = RenderedPDF;
	/**
	 * The namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Extract the source text from render options.
	     */
	    function getSource(options) {
	        return String(options.model.data.get(options.mimeType));
	    }
	    Private.getSource = getSource;
	    /**
	     * Append trusted html to a node.
	     */
	    function appendHtml(node, html) {
	        try {
	            var range = document.createRange();
	            node.appendChild(range.createContextualFragment(html));
	        }
	        catch (error) {
	            console.warn('Environment does not support Range ' +
	                'createContextualFragment, falling back on innerHTML');
	            node.innerHTML = html;
	        }
	    }
	    Private.appendHtml = appendHtml;
	    /**
	     * Resolve the relative urls in element `src` and `href` attributes.
	     *
	     * @param node - The head html element.
	     *
	     * @param resolver - A url resolver.
	     *
	     * @param linkHandler - An optional link handler for nodes.
	     *
	     * @returns a promise fulfilled when the relative urls have been resolved.
	     */
	    function handleUrls(node, resolver, linkHandler) {
	        var promises = [];
	        // Handle HTML Elements with src attributes.
	        var nodes = node.querySelectorAll('*[src]');
	        for (var i = 0; i < nodes.length; i++) {
	            promises.push(handleAttr(nodes[i], 'src', resolver));
	        }
	        var anchors = node.getElementsByTagName('a');
	        for (var i = 0; i < anchors.length; i++) {
	            promises.push(handleAnchor(anchors[i], resolver, linkHandler || null));
	        }
	        var links = node.getElementsByTagName('link');
	        for (var i = 0; i < links.length; i++) {
	            promises.push(handleAttr(links[i], 'href', resolver));
	        }
	        return Promise.all(promises).then(function () { return void 0; });
	    }
	    Private.handleUrls = handleUrls;
	    /**
	     * Handle a node with a `src` or `href` attribute.
	     */
	    function handleAttr(node, name, resolver) {
	        var source = node.getAttribute(name);
	        if (!source) {
	            return Promise.resolve(void 0);
	        }
	        node.setAttribute(name, '');
	        return resolver.resolveUrl(source).then(function (path) {
	            return resolver.getDownloadUrl(path);
	        }).then(function (url) {
	            node.setAttribute(name, url);
	        });
	    }
	    /**
	     * Apply ids to headers.
	     */
	    function headerAnchors(node) {
	        var headerNames = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
	        for (var _i = 0, headerNames_1 = headerNames; _i < headerNames_1.length; _i++) {
	            var headerType = headerNames_1[_i];
	            var headers = node.getElementsByTagName(headerType);
	            for (var i = 0; i < headers.length; i++) {
	                var header = headers[i];
	                header.id = header.innerHTML.replace(/ /g, '-');
	                var anchor = document.createElement('a');
	                anchor.target = '_self';
	                anchor.textContent = '¶';
	                anchor.href = '#' + header.id;
	                anchor.classList.add('jp-InternalAnchorLink');
	                header.appendChild(anchor);
	            }
	        }
	    }
	    Private.headerAnchors = headerAnchors;
	    /**
	     * Handle an anchor node.
	     */
	    function handleAnchor(anchor, resolver, linkHandler) {
	        anchor.target = '_blank';
	        var href = anchor.getAttribute('href');
	        if (!href) {
	            return Promise.resolve(void 0);
	        }
	        return resolver.resolveUrl(href).then(function (path) {
	            if (linkHandler) {
	                linkHandler.handleLink(anchor, path);
	            }
	            return resolver.getDownloadUrl(path);
	        }).then(function (url) {
	            anchor.href = url;
	        });
	    }
	})(Private || (Private = {}));
	/**
	 * A namespace for private module data.
	 */
	(function (Private) {
	    var initialized = false;
	    /**
	     * Support GitHub flavored Markdown, leave sanitizing to external library.
	     */
	    function initializeMarked() {
	        if (initialized) {
	            return;
	        }
	        initialized = true;
	        marked.setOptions({
	            gfm: true,
	            sanitize: false,
	            tables: true,
	            // breaks: true; We can't use GFM breaks as it causes problems with tables
	            langPrefix: "cm-s-" + codemirror_1.CodeMirrorEditor.DEFAULT_THEME + " language-",
	            highlight: function (code, lang, callback) {
	                if (!lang) {
	                    // no language, no highlight
	                    if (callback) {
	                        callback(null, code);
	                        return;
	                    }
	                    else {
	                        return code;
	                    }
	                }
	                codemirror_1.requireMode(lang).then(function (spec) {
	                    var el = document.createElement('div');
	                    if (!spec) {
	                        console.log("No CodeMirror mode: " + lang);
	                        callback(null, code);
	                        return;
	                    }
	                    try {
	                        codemirror_1.runMode(code, spec.mime, el);
	                        callback(null, el.innerHTML);
	                    }
	                    catch (err) {
	                        console.log("Failed to highlight " + lang + " code", err);
	                        callback(err, code);
	                    }
	                }).catch(function (err) {
	                    console.log("No CodeMirror mode: " + lang);
	                    console.log("Require CodeMirror mode error: " + err);
	                    callback(null, code);
	                });
	            }
	        });
	    }
	    Private.initializeMarked = initializeMarked;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/rendermime@0.3.2/lib/widgets.js **/


/** START DEFINE BLOCK for ansi_up@1.3.0/ansi_up.js **/
jupyter.define('ansi_up@1.3.0/ansi_up.js', function (module, exports, __jupyter_require__) {
	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// ansi_up.js
	// version : 1.3.0
	// author : Dru Nelson
	// license : MIT
	// http://github.com/drudru/ansi_up
	
	(function (Date, undefined) {
	
	    var ansi_up,
	        VERSION = "1.3.0",
	
	        // check for nodeJS
	        hasModule = (typeof module !== 'undefined'),
	
	        // Normal and then Bright
	        ANSI_COLORS = [
	          [
	            { color: "0, 0, 0",        'class': "ansi-black"   },
	            { color: "187, 0, 0",      'class': "ansi-red"     },
	            { color: "0, 187, 0",      'class': "ansi-green"   },
	            { color: "187, 187, 0",    'class': "ansi-yellow"  },
	            { color: "0, 0, 187",      'class': "ansi-blue"    },
	            { color: "187, 0, 187",    'class': "ansi-magenta" },
	            { color: "0, 187, 187",    'class': "ansi-cyan"    },
	            { color: "255,255,255",    'class': "ansi-white"   }
	          ],
	          [
	            { color: "85, 85, 85",     'class': "ansi-bright-black"   },
	            { color: "255, 85, 85",    'class': "ansi-bright-red"     },
	            { color: "0, 255, 0",      'class': "ansi-bright-green"   },
	            { color: "255, 255, 85",   'class': "ansi-bright-yellow"  },
	            { color: "85, 85, 255",    'class': "ansi-bright-blue"    },
	            { color: "255, 85, 255",   'class': "ansi-bright-magenta" },
	            { color: "85, 255, 255",   'class': "ansi-bright-cyan"    },
	            { color: "255, 255, 255",  'class': "ansi-bright-white"   }
	          ]
	        ],
	
	        // 256 Colors Palette
	        PALETTE_COLORS;
	
	    function Ansi_Up() {
	      this.fg = this.bg = this.fg_truecolor = this.bg_truecolor = null;
	      this.bright = 0;
	    }
	
	    Ansi_Up.prototype.setup_palette = function() {
	      PALETTE_COLORS = [];
	      // Index 0..15 : System color
	      (function() {
	        var i, j;
	        for (i = 0; i < 2; ++i) {
	          for (j = 0; j < 8; ++j) {
	            PALETTE_COLORS.push(ANSI_COLORS[i][j]['color']);
	          }
	        }
	      })();
	
	      // Index 16..231 : RGB 6x6x6
	      // https://gist.github.com/jasonm23/2868981#file-xterm-256color-yaml
	      (function() {
	        var levels = [0, 95, 135, 175, 215, 255];
	        var format = function (r, g, b) { return levels[r] + ', ' + levels[g] + ', ' + levels[b] };
	        var r, g, b;
	        for (r = 0; r < 6; ++r) {
	          for (g = 0; g < 6; ++g) {
	            for (b = 0; b < 6; ++b) {
	              PALETTE_COLORS.push(format.call(this, r, g, b));
	            }
	          }
	        }
	      })();
	
	      // Index 232..255 : Grayscale
	      (function() {
	        var level = 8;
	        var format = function(level) { return level + ', ' + level + ', ' + level };
	        var i;
	        for (i = 0; i < 24; ++i, level += 10) {
	          PALETTE_COLORS.push(format.call(this, level));
	        }
	      })();
	    };
	
	    Ansi_Up.prototype.escape_for_html = function (txt) {
	      return txt.replace(/[&<>]/gm, function(str) {
	        if (str == "&") return "&amp;";
	        if (str == "<") return "&lt;";
	        if (str == ">") return "&gt;";
	      });
	    };
	
	    Ansi_Up.prototype.linkify = function (txt) {
	      return txt.replace(/(https?:\/\/[^\s]+)/gm, function(str) {
	        return "<a href=\"" + str + "\">" + str + "</a>";
	      });
	    };
	
	    Ansi_Up.prototype.ansi_to_html = function (txt, options) {
	      return this.process(txt, options, true);
	    };
	
	    Ansi_Up.prototype.ansi_to_text = function (txt) {
	      var options = {};
	      return this.process(txt, options, false);
	    };
	
	    Ansi_Up.prototype.process = function (txt, options, markup) {
	      var self = this;
	      var raw_text_chunks = txt.split(/\033\[/);
	      var first_chunk = raw_text_chunks.shift(); // the first chunk is not the result of the split
	
	      var color_chunks = raw_text_chunks.map(function (chunk) {
	        return self.process_chunk(chunk, options, markup);
	      });
	
	      color_chunks.unshift(first_chunk);
	
	      return color_chunks.join('');
	    };
	
	    Ansi_Up.prototype.process_chunk = function (text, options, markup) {
	
	      // Are we using classes or styles?
	      options = typeof options == 'undefined' ? {} : options;
	      var use_classes = typeof options.use_classes != 'undefined' && options.use_classes;
	      var key = use_classes ? 'class' : 'color';
	
	      // Each 'chunk' is the text after the CSI (ESC + '[') and before the next CSI/EOF.
	      //
	      // This regex matches four groups within a chunk.
	      //
	      // The first and third groups match code type.
	      // We supported only SGR command. It has empty first group and 'm' in third.
	      //
	      // The second group matches all of the number+semicolon command sequences
	      // before the 'm' (or other trailing) character.
	      // These are the graphics or SGR commands.
	      //
	      // The last group is the text (including newlines) that is colored by
	      // the other group's commands.
	      var matches = text.match(/^([!\x3c-\x3f]*)([\d;]*)([\x20-\x2c]*[\x40-\x7e])([\s\S]*)/m);
	
	      if (!matches) return text;
	
	      var orig_txt = matches[4];
	      var nums = matches[2].split(';');
	
	      // We currently support only "SGR" (Select Graphic Rendition)
	      // Simply ignore if not a SGR command.
	      if (matches[1] !== '' || matches[3] !== 'm') {
	        return orig_txt;
	      }
	
	      if (!markup) {
	        return orig_txt;
	      }
	
	      var self = this;
	
	      while (nums.length > 0) {
	        var num_str = nums.shift();
	        var num = parseInt(num_str);
	
	        if (isNaN(num) || num === 0) {
	          self.fg = self.bg = null;
	          self.bright = 0;
	        } else if (num === 1) {
	          self.bright = 1;
	        } else if (num == 39) {
	          self.fg = null;
	        } else if (num == 49) {
	          self.bg = null;
	        } else if ((num >= 30) && (num < 38)) {
	          self.fg = ANSI_COLORS[self.bright][(num % 10)][key];
	        } else if ((num >= 90) && (num < 98)) {
	          self.fg = ANSI_COLORS[1][(num % 10)][key];
	        } else if ((num >= 40) && (num < 48)) {
	          self.bg = ANSI_COLORS[0][(num % 10)][key];
	        } else if ((num >= 100) && (num < 108)) {
	          self.bg = ANSI_COLORS[1][(num % 10)][key];
	        } else if (num === 38 || num === 48) { // extend color (38=fg, 48=bg)
	          (function() {
	            var is_foreground = (num === 38);
	            if (nums.length >= 1) {
	              var mode = nums.shift();
	              if (mode === '5' && nums.length >= 1) { // palette color
	                var palette_index = parseInt(nums.shift());
	                if (palette_index >= 0 && palette_index <= 255) {
	                  if (!use_classes) {
	                    if (!PALETTE_COLORS) {
	                      self.setup_palette.call(self);
	                    }
	                    if (is_foreground) {
	                      self.fg = PALETTE_COLORS[palette_index];
	                    } else {
	                      self.bg = PALETTE_COLORS[palette_index];
	                    }
	                  } else {
	                    var klass = (palette_index >= 16)
	                          ? ('ansi-palette-' + palette_index)
	                          : ANSI_COLORS[palette_index > 7 ? 1 : 0][palette_index % 8]['class'];
	                    if (is_foreground) {
	                      self.fg = klass;
	                    } else {
	                      self.bg = klass;
	                    }
	                  }
	                }
	              } else if(mode === '2' && nums.length >= 3) { // true color
	                var r = parseInt(nums.shift());
	                var g = parseInt(nums.shift());
	                var b = parseInt(nums.shift());
	                if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) {
	                  var color = r + ', ' + g + ', ' + b;
	                  if (!use_classes) {
	                    if (is_foreground) {
	                      self.fg = color;
	                    } else {
	                      self.bg = color;
	                    }
	                  } else {
	                    if (is_foreground) {
	                      self.fg = 'ansi-truecolor';
	                      self.fg_truecolor = color;
	                    } else {
	                      self.bg = 'ansi-truecolor';
	                      self.bg_truecolor = color;
	                    }
	                  }
	                }
	              }
	            }
	          })();
	        }
	      }
	
	      if ((self.fg === null) && (self.bg === null)) {
	        return orig_txt;
	      } else {
	        var styles = [];
	        var classes = [];
	        var data = {};
	        var render_data = function (data) {
	          var fragments = [];
	          var key;
	          for (key in data) {
	            if (data.hasOwnProperty(key)) {
	              fragments.push('data-' + key + '="' + this.escape_for_html(data[key]) + '"');
	            }
	          }
	          return fragments.length > 0 ? ' ' + fragments.join(' ') : '';
	        };
	
	        if (self.fg) {
	          if (use_classes) {
	            classes.push(self.fg + "-fg");
	            if (self.fg_truecolor !== null) {
	              data['ansi-truecolor-fg'] = self.fg_truecolor;
	              self.fg_truecolor = null;
	            }
	          } else {
	            styles.push("color:rgb(" + self.fg + ")");
	          }
	        }
	        if (self.bg) {
	          if (use_classes) {
	            classes.push(self.bg + "-bg");
	            if (self.bg_truecolor !== null) {
	              data['ansi-truecolor-bg'] = self.bg_truecolor;
	              self.bg_truecolor = null;
	            }
	          } else {
	            styles.push("background-color:rgb(" + self.bg + ")");
	          }
	        }
	        if (use_classes) {
	          return '<span class="' + classes.join(' ') + '"' + render_data.call(self, data) + '>' + orig_txt + '</span>';
	        } else {
	          return '<span style="' + styles.join(';') + '"' + render_data.call(self, data) + '>' + orig_txt + '</span>';
	        }
	      }
	    };
	
	    // Module exports
	    ansi_up = {
	
	      escape_for_html: function (txt) {
	        var a2h = new Ansi_Up();
	        return a2h.escape_for_html(txt);
	      },
	
	      linkify: function (txt) {
	        var a2h = new Ansi_Up();
	        return a2h.linkify(txt);
	      },
	
	      ansi_to_html: function (txt, options) {
	        var a2h = new Ansi_Up();
	        return a2h.ansi_to_html(txt, options);
	      },
	
	      ansi_to_text: function (txt) {
	        var a2h = new Ansi_Up();
	        return a2h.ansi_to_text(txt);
	      },
	
	      ansi_to_html_obj: function () {
	        return new Ansi_Up();
	      }
	    };
	
	    // CommonJS module is defined
	    if (hasModule) {
	        module.exports = ansi_up;
	    }
	    /*global ender:false */
	    if (typeof window !== 'undefined' && typeof ender === 'undefined') {
	        window.ansi_up = ansi_up;
	    }
	    /*global define:false */
	    if (true) {
	        !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
	            return ansi_up;
	        }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	    }
	})(Date);
	
})
/** END DEFINE BLOCK for ansi_up@1.3.0/ansi_up.js **/


/** START DEFINE BLOCK for marked@0.3.6/lib/marked.js **/
jupyter.define('marked@0.3.6/lib/marked.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(global) {/**
	 * marked - a markdown parser
	 * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
	 * https://github.com/chjj/marked
	 */
	
	;(function() {
	
	/**
	 * Block-Level Grammar
	 */
	
	var block = {
	  newline: /^\n+/,
	  code: /^( {4}[^\n]+\n*)+/,
	  fences: noop,
	  hr: /^( *[-*_]){3,} *(?:\n+|$)/,
	  heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
	  nptable: noop,
	  lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
	  blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
	  list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
	  html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
	  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
	  table: noop,
	  paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
	  text: /^[^\n]+/
	};
	
	block.bullet = /(?:[*+-]|\d+\.)/;
	block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
	block.item = replace(block.item, 'gm')
	  (/bull/g, block.bullet)
	  ();
	
	block.list = replace(block.list)
	  (/bull/g, block.bullet)
	  ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
	  ('def', '\\n+(?=' + block.def.source + ')')
	  ();
	
	block.blockquote = replace(block.blockquote)
	  ('def', block.def)
	  ();
	
	block._tag = '(?!(?:'
	  + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
	  + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
	  + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
	
	block.html = replace(block.html)
	  ('comment', /<!--[\s\S]*?-->/)
	  ('closed', /<(tag)[\s\S]+?<\/\1>/)
	  ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
	  (/tag/g, block._tag)
	  ();
	
	block.paragraph = replace(block.paragraph)
	  ('hr', block.hr)
	  ('heading', block.heading)
	  ('lheading', block.lheading)
	  ('blockquote', block.blockquote)
	  ('tag', '<' + block._tag)
	  ('def', block.def)
	  ();
	
	/**
	 * Normal Block Grammar
	 */
	
	block.normal = merge({}, block);
	
	/**
	 * GFM Block Grammar
	 */
	
	block.gfm = merge({}, block.normal, {
	  fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
	  paragraph: /^/,
	  heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
	});
	
	block.gfm.paragraph = replace(block.paragraph)
	  ('(?!', '(?!'
	    + block.gfm.fences.source.replace('\\1', '\\2') + '|'
	    + block.list.source.replace('\\1', '\\3') + '|')
	  ();
	
	/**
	 * GFM + Tables Block Grammar
	 */
	
	block.tables = merge({}, block.gfm, {
	  nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
	  table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
	});
	
	/**
	 * Block Lexer
	 */
	
	function Lexer(options) {
	  this.tokens = [];
	  this.tokens.links = {};
	  this.options = options || marked.defaults;
	  this.rules = block.normal;
	
	  if (this.options.gfm) {
	    if (this.options.tables) {
	      this.rules = block.tables;
	    } else {
	      this.rules = block.gfm;
	    }
	  }
	}
	
	/**
	 * Expose Block Rules
	 */
	
	Lexer.rules = block;
	
	/**
	 * Static Lex Method
	 */
	
	Lexer.lex = function(src, options) {
	  var lexer = new Lexer(options);
	  return lexer.lex(src);
	};
	
	/**
	 * Preprocessing
	 */
	
	Lexer.prototype.lex = function(src) {
	  src = src
	    .replace(/\r\n|\r/g, '\n')
	    .replace(/\t/g, '    ')
	    .replace(/\u00a0/g, ' ')
	    .replace(/\u2424/g, '\n');
	
	  return this.token(src, true);
	};
	
	/**
	 * Lexing
	 */
	
	Lexer.prototype.token = function(src, top, bq) {
	  var src = src.replace(/^ +$/gm, '')
	    , next
	    , loose
	    , cap
	    , bull
	    , b
	    , item
	    , space
	    , i
	    , l;
	
	  while (src) {
	    // newline
	    if (cap = this.rules.newline.exec(src)) {
	      src = src.substring(cap[0].length);
	      if (cap[0].length > 1) {
	        this.tokens.push({
	          type: 'space'
	        });
	      }
	    }
	
	    // code
	    if (cap = this.rules.code.exec(src)) {
	      src = src.substring(cap[0].length);
	      cap = cap[0].replace(/^ {4}/gm, '');
	      this.tokens.push({
	        type: 'code',
	        text: !this.options.pedantic
	          ? cap.replace(/\n+$/, '')
	          : cap
	      });
	      continue;
	    }
	
	    // fences (gfm)
	    if (cap = this.rules.fences.exec(src)) {
	      src = src.substring(cap[0].length);
	      this.tokens.push({
	        type: 'code',
	        lang: cap[2],
	        text: cap[3] || ''
	      });
	      continue;
	    }
	
	    // heading
	    if (cap = this.rules.heading.exec(src)) {
	      src = src.substring(cap[0].length);
	      this.tokens.push({
	        type: 'heading',
	        depth: cap[1].length,
	        text: cap[2]
	      });
	      continue;
	    }
	
	    // table no leading pipe (gfm)
	    if (top && (cap = this.rules.nptable.exec(src))) {
	      src = src.substring(cap[0].length);
	
	      item = {
	        type: 'table',
	        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
	        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
	        cells: cap[3].replace(/\n$/, '').split('\n')
	      };
	
	      for (i = 0; i < item.align.length; i++) {
	        if (/^ *-+: *$/.test(item.align[i])) {
	          item.align[i] = 'right';
	        } else if (/^ *:-+: *$/.test(item.align[i])) {
	          item.align[i] = 'center';
	        } else if (/^ *:-+ *$/.test(item.align[i])) {
	          item.align[i] = 'left';
	        } else {
	          item.align[i] = null;
	        }
	      }
	
	      for (i = 0; i < item.cells.length; i++) {
	        item.cells[i] = item.cells[i].split(/ *\| */);
	      }
	
	      this.tokens.push(item);
	
	      continue;
	    }
	
	    // lheading
	    if (cap = this.rules.lheading.exec(src)) {
	      src = src.substring(cap[0].length);
	      this.tokens.push({
	        type: 'heading',
	        depth: cap[2] === '=' ? 1 : 2,
	        text: cap[1]
	      });
	      continue;
	    }
	
	    // hr
	    if (cap = this.rules.hr.exec(src)) {
	      src = src.substring(cap[0].length);
	      this.tokens.push({
	        type: 'hr'
	      });
	      continue;
	    }
	
	    // blockquote
	    if (cap = this.rules.blockquote.exec(src)) {
	      src = src.substring(cap[0].length);
	
	      this.tokens.push({
	        type: 'blockquote_start'
	      });
	
	      cap = cap[0].replace(/^ *> ?/gm, '');
	
	      // Pass `top` to keep the current
	      // "toplevel" state. This is exactly
	      // how markdown.pl works.
	      this.token(cap, top, true);
	
	      this.tokens.push({
	        type: 'blockquote_end'
	      });
	
	      continue;
	    }
	
	    // list
	    if (cap = this.rules.list.exec(src)) {
	      src = src.substring(cap[0].length);
	      bull = cap[2];
	
	      this.tokens.push({
	        type: 'list_start',
	        ordered: bull.length > 1
	      });
	
	      // Get each top-level item.
	      cap = cap[0].match(this.rules.item);
	
	      next = false;
	      l = cap.length;
	      i = 0;
	
	      for (; i < l; i++) {
	        item = cap[i];
	
	        // Remove the list item's bullet
	        // so it is seen as the next token.
	        space = item.length;
	        item = item.replace(/^ *([*+-]|\d+\.) +/, '');
	
	        // Outdent whatever the
	        // list item contains. Hacky.
	        if (~item.indexOf('\n ')) {
	          space -= item.length;
	          item = !this.options.pedantic
	            ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
	            : item.replace(/^ {1,4}/gm, '');
	        }
	
	        // Determine whether the next list item belongs here.
	        // Backpedal if it does not belong in this list.
	        if (this.options.smartLists && i !== l - 1) {
	          b = block.bullet.exec(cap[i + 1])[0];
	          if (bull !== b && !(bull.length > 1 && b.length > 1)) {
	            src = cap.slice(i + 1).join('\n') + src;
	            i = l - 1;
	          }
	        }
	
	        // Determine whether item is loose or not.
	        // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
	        // for discount behavior.
	        loose = next || /\n\n(?!\s*$)/.test(item);
	        if (i !== l - 1) {
	          next = item.charAt(item.length - 1) === '\n';
	          if (!loose) loose = next;
	        }
	
	        this.tokens.push({
	          type: loose
	            ? 'loose_item_start'
	            : 'list_item_start'
	        });
	
	        // Recurse.
	        this.token(item, false, bq);
	
	        this.tokens.push({
	          type: 'list_item_end'
	        });
	      }
	
	      this.tokens.push({
	        type: 'list_end'
	      });
	
	      continue;
	    }
	
	    // html
	    if (cap = this.rules.html.exec(src)) {
	      src = src.substring(cap[0].length);
	      this.tokens.push({
	        type: this.options.sanitize
	          ? 'paragraph'
	          : 'html',
	        pre: !this.options.sanitizer
	          && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
	        text: cap[0]
	      });
	      continue;
	    }
	
	    // def
	    if ((!bq && top) && (cap = this.rules.def.exec(src))) {
	      src = src.substring(cap[0].length);
	      this.tokens.links[cap[1].toLowerCase()] = {
	        href: cap[2],
	        title: cap[3]
	      };
	      continue;
	    }
	
	    // table (gfm)
	    if (top && (cap = this.rules.table.exec(src))) {
	      src = src.substring(cap[0].length);
	
	      item = {
	        type: 'table',
	        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
	        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
	        cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
	      };
	
	      for (i = 0; i < item.align.length; i++) {
	        if (/^ *-+: *$/.test(item.align[i])) {
	          item.align[i] = 'right';
	        } else if (/^ *:-+: *$/.test(item.align[i])) {
	          item.align[i] = 'center';
	        } else if (/^ *:-+ *$/.test(item.align[i])) {
	          item.align[i] = 'left';
	        } else {
	          item.align[i] = null;
	        }
	      }
	
	      for (i = 0; i < item.cells.length; i++) {
	        item.cells[i] = item.cells[i]
	          .replace(/^ *\| *| *\| *$/g, '')
	          .split(/ *\| */);
	      }
	
	      this.tokens.push(item);
	
	      continue;
	    }
	
	    // top-level paragraph
	    if (top && (cap = this.rules.paragraph.exec(src))) {
	      src = src.substring(cap[0].length);
	      this.tokens.push({
	        type: 'paragraph',
	        text: cap[1].charAt(cap[1].length - 1) === '\n'
	          ? cap[1].slice(0, -1)
	          : cap[1]
	      });
	      continue;
	    }
	
	    // text
	    if (cap = this.rules.text.exec(src)) {
	      // Top-level should never reach here.
	      src = src.substring(cap[0].length);
	      this.tokens.push({
	        type: 'text',
	        text: cap[0]
	      });
	      continue;
	    }
	
	    if (src) {
	      throw new
	        Error('Infinite loop on byte: ' + src.charCodeAt(0));
	    }
	  }
	
	  return this.tokens;
	};
	
	/**
	 * Inline-Level Grammar
	 */
	
	var inline = {
	  escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
	  autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
	  url: noop,
	  tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
	  link: /^!?\[(inside)\]\(href\)/,
	  reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
	  nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
	  strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
	  em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
	  code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
	  br: /^ {2,}\n(?!\s*$)/,
	  del: noop,
	  text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
	};
	
	inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
	inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
	
	inline.link = replace(inline.link)
	  ('inside', inline._inside)
	  ('href', inline._href)
	  ();
	
	inline.reflink = replace(inline.reflink)
	  ('inside', inline._inside)
	  ();
	
	/**
	 * Normal Inline Grammar
	 */
	
	inline.normal = merge({}, inline);
	
	/**
	 * Pedantic Inline Grammar
	 */
	
	inline.pedantic = merge({}, inline.normal, {
	  strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
	  em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
	});
	
	/**
	 * GFM Inline Grammar
	 */
	
	inline.gfm = merge({}, inline.normal, {
	  escape: replace(inline.escape)('])', '~|])')(),
	  url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
	  del: /^~~(?=\S)([\s\S]*?\S)~~/,
	  text: replace(inline.text)
	    (']|', '~]|')
	    ('|', '|https?://|')
	    ()
	});
	
	/**
	 * GFM + Line Breaks Inline Grammar
	 */
	
	inline.breaks = merge({}, inline.gfm, {
	  br: replace(inline.br)('{2,}', '*')(),
	  text: replace(inline.gfm.text)('{2,}', '*')()
	});
	
	/**
	 * Inline Lexer & Compiler
	 */
	
	function InlineLexer(links, options) {
	  this.options = options || marked.defaults;
	  this.links = links;
	  this.rules = inline.normal;
	  this.renderer = this.options.renderer || new Renderer;
	  this.renderer.options = this.options;
	
	  if (!this.links) {
	    throw new
	      Error('Tokens array requires a `links` property.');
	  }
	
	  if (this.options.gfm) {
	    if (this.options.breaks) {
	      this.rules = inline.breaks;
	    } else {
	      this.rules = inline.gfm;
	    }
	  } else if (this.options.pedantic) {
	    this.rules = inline.pedantic;
	  }
	}
	
	/**
	 * Expose Inline Rules
	 */
	
	InlineLexer.rules = inline;
	
	/**
	 * Static Lexing/Compiling Method
	 */
	
	InlineLexer.output = function(src, links, options) {
	  var inline = new InlineLexer(links, options);
	  return inline.output(src);
	};
	
	/**
	 * Lexing/Compiling
	 */
	
	InlineLexer.prototype.output = function(src) {
	  var out = ''
	    , link
	    , text
	    , href
	    , cap;
	
	  while (src) {
	    // escape
	    if (cap = this.rules.escape.exec(src)) {
	      src = src.substring(cap[0].length);
	      out += cap[1];
	      continue;
	    }
	
	    // autolink
	    if (cap = this.rules.autolink.exec(src)) {
	      src = src.substring(cap[0].length);
	      if (cap[2] === '@') {
	        text = cap[1].charAt(6) === ':'
	          ? this.mangle(cap[1].substring(7))
	          : this.mangle(cap[1]);
	        href = this.mangle('mailto:') + text;
	      } else {
	        text = escape(cap[1]);
	        href = text;
	      }
	      out += this.renderer.link(href, null, text);
	      continue;
	    }
	
	    // url (gfm)
	    if (!this.inLink && (cap = this.rules.url.exec(src))) {
	      src = src.substring(cap[0].length);
	      text = escape(cap[1]);
	      href = text;
	      out += this.renderer.link(href, null, text);
	      continue;
	    }
	
	    // tag
	    if (cap = this.rules.tag.exec(src)) {
	      if (!this.inLink && /^<a /i.test(cap[0])) {
	        this.inLink = true;
	      } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
	        this.inLink = false;
	      }
	      src = src.substring(cap[0].length);
	      out += this.options.sanitize
	        ? this.options.sanitizer
	          ? this.options.sanitizer(cap[0])
	          : escape(cap[0])
	        : cap[0]
	      continue;
	    }
	
	    // link
	    if (cap = this.rules.link.exec(src)) {
	      src = src.substring(cap[0].length);
	      this.inLink = true;
	      out += this.outputLink(cap, {
	        href: cap[2],
	        title: cap[3]
	      });
	      this.inLink = false;
	      continue;
	    }
	
	    // reflink, nolink
	    if ((cap = this.rules.reflink.exec(src))
	        || (cap = this.rules.nolink.exec(src))) {
	      src = src.substring(cap[0].length);
	      link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
	      link = this.links[link.toLowerCase()];
	      if (!link || !link.href) {
	        out += cap[0].charAt(0);
	        src = cap[0].substring(1) + src;
	        continue;
	      }
	      this.inLink = true;
	      out += this.outputLink(cap, link);
	      this.inLink = false;
	      continue;
	    }
	
	    // strong
	    if (cap = this.rules.strong.exec(src)) {
	      src = src.substring(cap[0].length);
	      out += this.renderer.strong(this.output(cap[2] || cap[1]));
	      continue;
	    }
	
	    // em
	    if (cap = this.rules.em.exec(src)) {
	      src = src.substring(cap[0].length);
	      out += this.renderer.em(this.output(cap[2] || cap[1]));
	      continue;
	    }
	
	    // code
	    if (cap = this.rules.code.exec(src)) {
	      src = src.substring(cap[0].length);
	      out += this.renderer.codespan(escape(cap[2], true));
	      continue;
	    }
	
	    // br
	    if (cap = this.rules.br.exec(src)) {
	      src = src.substring(cap[0].length);
	      out += this.renderer.br();
	      continue;
	    }
	
	    // del (gfm)
	    if (cap = this.rules.del.exec(src)) {
	      src = src.substring(cap[0].length);
	      out += this.renderer.del(this.output(cap[1]));
	      continue;
	    }
	
	    // text
	    if (cap = this.rules.text.exec(src)) {
	      src = src.substring(cap[0].length);
	      out += this.renderer.text(escape(this.smartypants(cap[0])));
	      continue;
	    }
	
	    if (src) {
	      throw new
	        Error('Infinite loop on byte: ' + src.charCodeAt(0));
	    }
	  }
	
	  return out;
	};
	
	/**
	 * Compile Link
	 */
	
	InlineLexer.prototype.outputLink = function(cap, link) {
	  var href = escape(link.href)
	    , title = link.title ? escape(link.title) : null;
	
	  return cap[0].charAt(0) !== '!'
	    ? this.renderer.link(href, title, this.output(cap[1]))
	    : this.renderer.image(href, title, escape(cap[1]));
	};
	
	/**
	 * Smartypants Transformations
	 */
	
	InlineLexer.prototype.smartypants = function(text) {
	  if (!this.options.smartypants) return text;
	  return text
	    // em-dashes
	    .replace(/---/g, '\u2014')
	    // en-dashes
	    .replace(/--/g, '\u2013')
	    // opening singles
	    .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
	    // closing singles & apostrophes
	    .replace(/'/g, '\u2019')
	    // opening doubles
	    .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
	    // closing doubles
	    .replace(/"/g, '\u201d')
	    // ellipses
	    .replace(/\.{3}/g, '\u2026');
	};
	
	/**
	 * Mangle Links
	 */
	
	InlineLexer.prototype.mangle = function(text) {
	  if (!this.options.mangle) return text;
	  var out = ''
	    , l = text.length
	    , i = 0
	    , ch;
	
	  for (; i < l; i++) {
	    ch = text.charCodeAt(i);
	    if (Math.random() > 0.5) {
	      ch = 'x' + ch.toString(16);
	    }
	    out += '&#' + ch + ';';
	  }
	
	  return out;
	};
	
	/**
	 * Renderer
	 */
	
	function Renderer(options) {
	  this.options = options || {};
	}
	
	Renderer.prototype.code = function(code, lang, escaped) {
	  if (this.options.highlight) {
	    var out = this.options.highlight(code, lang);
	    if (out != null && out !== code) {
	      escaped = true;
	      code = out;
	    }
	  }
	
	  if (!lang) {
	    return '<pre><code>'
	      + (escaped ? code : escape(code, true))
	      + '\n</code></pre>';
	  }
	
	  return '<pre><code class="'
	    + this.options.langPrefix
	    + escape(lang, true)
	    + '">'
	    + (escaped ? code : escape(code, true))
	    + '\n</code></pre>\n';
	};
	
	Renderer.prototype.blockquote = function(quote) {
	  return '<blockquote>\n' + quote + '</blockquote>\n';
	};
	
	Renderer.prototype.html = function(html) {
	  return html;
	};
	
	Renderer.prototype.heading = function(text, level, raw) {
	  return '<h'
	    + level
	    + ' id="'
	    + this.options.headerPrefix
	    + raw.toLowerCase().replace(/[^\w]+/g, '-')
	    + '">'
	    + text
	    + '</h'
	    + level
	    + '>\n';
	};
	
	Renderer.prototype.hr = function() {
	  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
	};
	
	Renderer.prototype.list = function(body, ordered) {
	  var type = ordered ? 'ol' : 'ul';
	  return '<' + type + '>\n' + body + '</' + type + '>\n';
	};
	
	Renderer.prototype.listitem = function(text) {
	  return '<li>' + text + '</li>\n';
	};
	
	Renderer.prototype.paragraph = function(text) {
	  return '<p>' + text + '</p>\n';
	};
	
	Renderer.prototype.table = function(header, body) {
	  return '<table>\n'
	    + '<thead>\n'
	    + header
	    + '</thead>\n'
	    + '<tbody>\n'
	    + body
	    + '</tbody>\n'
	    + '</table>\n';
	};
	
	Renderer.prototype.tablerow = function(content) {
	  return '<tr>\n' + content + '</tr>\n';
	};
	
	Renderer.prototype.tablecell = function(content, flags) {
	  var type = flags.header ? 'th' : 'td';
	  var tag = flags.align
	    ? '<' + type + ' style="text-align:' + flags.align + '">'
	    : '<' + type + '>';
	  return tag + content + '</' + type + '>\n';
	};
	
	// span level renderer
	Renderer.prototype.strong = function(text) {
	  return '<strong>' + text + '</strong>';
	};
	
	Renderer.prototype.em = function(text) {
	  return '<em>' + text + '</em>';
	};
	
	Renderer.prototype.codespan = function(text) {
	  return '<code>' + text + '</code>';
	};
	
	Renderer.prototype.br = function() {
	  return this.options.xhtml ? '<br/>' : '<br>';
	};
	
	Renderer.prototype.del = function(text) {
	  return '<del>' + text + '</del>';
	};
	
	Renderer.prototype.link = function(href, title, text) {
	  if (this.options.sanitize) {
	    try {
	      var prot = decodeURIComponent(unescape(href))
	        .replace(/[^\w:]/g, '')
	        .toLowerCase();
	    } catch (e) {
	      return '';
	    }
	    if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
	      return '';
	    }
	  }
	  var out = '<a href="' + href + '"';
	  if (title) {
	    out += ' title="' + title + '"';
	  }
	  out += '>' + text + '</a>';
	  return out;
	};
	
	Renderer.prototype.image = function(href, title, text) {
	  var out = '<img src="' + href + '" alt="' + text + '"';
	  if (title) {
	    out += ' title="' + title + '"';
	  }
	  out += this.options.xhtml ? '/>' : '>';
	  return out;
	};
	
	Renderer.prototype.text = function(text) {
	  return text;
	};
	
	/**
	 * Parsing & Compiling
	 */
	
	function Parser(options) {
	  this.tokens = [];
	  this.token = null;
	  this.options = options || marked.defaults;
	  this.options.renderer = this.options.renderer || new Renderer;
	  this.renderer = this.options.renderer;
	  this.renderer.options = this.options;
	}
	
	/**
	 * Static Parse Method
	 */
	
	Parser.parse = function(src, options, renderer) {
	  var parser = new Parser(options, renderer);
	  return parser.parse(src);
	};
	
	/**
	 * Parse Loop
	 */
	
	Parser.prototype.parse = function(src) {
	  this.inline = new InlineLexer(src.links, this.options, this.renderer);
	  this.tokens = src.reverse();
	
	  var out = '';
	  while (this.next()) {
	    out += this.tok();
	  }
	
	  return out;
	};
	
	/**
	 * Next Token
	 */
	
	Parser.prototype.next = function() {
	  return this.token = this.tokens.pop();
	};
	
	/**
	 * Preview Next Token
	 */
	
	Parser.prototype.peek = function() {
	  return this.tokens[this.tokens.length - 1] || 0;
	};
	
	/**
	 * Parse Text Tokens
	 */
	
	Parser.prototype.parseText = function() {
	  var body = this.token.text;
	
	  while (this.peek().type === 'text') {
	    body += '\n' + this.next().text;
	  }
	
	  return this.inline.output(body);
	};
	
	/**
	 * Parse Current Token
	 */
	
	Parser.prototype.tok = function() {
	  switch (this.token.type) {
	    case 'space': {
	      return '';
	    }
	    case 'hr': {
	      return this.renderer.hr();
	    }
	    case 'heading': {
	      return this.renderer.heading(
	        this.inline.output(this.token.text),
	        this.token.depth,
	        this.token.text);
	    }
	    case 'code': {
	      return this.renderer.code(this.token.text,
	        this.token.lang,
	        this.token.escaped);
	    }
	    case 'table': {
	      var header = ''
	        , body = ''
	        , i
	        , row
	        , cell
	        , flags
	        , j;
	
	      // header
	      cell = '';
	      for (i = 0; i < this.token.header.length; i++) {
	        flags = { header: true, align: this.token.align[i] };
	        cell += this.renderer.tablecell(
	          this.inline.output(this.token.header[i]),
	          { header: true, align: this.token.align[i] }
	        );
	      }
	      header += this.renderer.tablerow(cell);
	
	      for (i = 0; i < this.token.cells.length; i++) {
	        row = this.token.cells[i];
	
	        cell = '';
	        for (j = 0; j < row.length; j++) {
	          cell += this.renderer.tablecell(
	            this.inline.output(row[j]),
	            { header: false, align: this.token.align[j] }
	          );
	        }
	
	        body += this.renderer.tablerow(cell);
	      }
	      return this.renderer.table(header, body);
	    }
	    case 'blockquote_start': {
	      var body = '';
	
	      while (this.next().type !== 'blockquote_end') {
	        body += this.tok();
	      }
	
	      return this.renderer.blockquote(body);
	    }
	    case 'list_start': {
	      var body = ''
	        , ordered = this.token.ordered;
	
	      while (this.next().type !== 'list_end') {
	        body += this.tok();
	      }
	
	      return this.renderer.list(body, ordered);
	    }
	    case 'list_item_start': {
	      var body = '';
	
	      while (this.next().type !== 'list_item_end') {
	        body += this.token.type === 'text'
	          ? this.parseText()
	          : this.tok();
	      }
	
	      return this.renderer.listitem(body);
	    }
	    case 'loose_item_start': {
	      var body = '';
	
	      while (this.next().type !== 'list_item_end') {
	        body += this.tok();
	      }
	
	      return this.renderer.listitem(body);
	    }
	    case 'html': {
	      var html = !this.token.pre && !this.options.pedantic
	        ? this.inline.output(this.token.text)
	        : this.token.text;
	      return this.renderer.html(html);
	    }
	    case 'paragraph': {
	      return this.renderer.paragraph(this.inline.output(this.token.text));
	    }
	    case 'text': {
	      return this.renderer.paragraph(this.parseText());
	    }
	  }
	};
	
	/**
	 * Helpers
	 */
	
	function escape(html, encode) {
	  return html
	    .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
	    .replace(/</g, '&lt;')
	    .replace(/>/g, '&gt;')
	    .replace(/"/g, '&quot;')
	    .replace(/'/g, '&#39;');
	}
	
	function unescape(html) {
		// explicitly match decimal, hex, and named HTML entities 
	  return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
	    n = n.toLowerCase();
	    if (n === 'colon') return ':';
	    if (n.charAt(0) === '#') {
	      return n.charAt(1) === 'x'
	        ? String.fromCharCode(parseInt(n.substring(2), 16))
	        : String.fromCharCode(+n.substring(1));
	    }
	    return '';
	  });
	}
	
	function replace(regex, opt) {
	  regex = regex.source;
	  opt = opt || '';
	  return function self(name, val) {
	    if (!name) return new RegExp(regex, opt);
	    val = val.source || val;
	    val = val.replace(/(^|[^\[])\^/g, '$1');
	    regex = regex.replace(name, val);
	    return self;
	  };
	}
	
	function noop() {}
	noop.exec = noop;
	
	function merge(obj) {
	  var i = 1
	    , target
	    , key;
	
	  for (; i < arguments.length; i++) {
	    target = arguments[i];
	    for (key in target) {
	      if (Object.prototype.hasOwnProperty.call(target, key)) {
	        obj[key] = target[key];
	      }
	    }
	  }
	
	  return obj;
	}
	
	
	/**
	 * Marked
	 */
	
	function marked(src, opt, callback) {
	  if (callback || typeof opt === 'function') {
	    if (!callback) {
	      callback = opt;
	      opt = null;
	    }
	
	    opt = merge({}, marked.defaults, opt || {});
	
	    var highlight = opt.highlight
	      , tokens
	      , pending
	      , i = 0;
	
	    try {
	      tokens = Lexer.lex(src, opt)
	    } catch (e) {
	      return callback(e);
	    }
	
	    pending = tokens.length;
	
	    var done = function(err) {
	      if (err) {
	        opt.highlight = highlight;
	        return callback(err);
	      }
	
	      var out;
	
	      try {
	        out = Parser.parse(tokens, opt);
	      } catch (e) {
	        err = e;
	      }
	
	      opt.highlight = highlight;
	
	      return err
	        ? callback(err)
	        : callback(null, out);
	    };
	
	    if (!highlight || highlight.length < 3) {
	      return done();
	    }
	
	    delete opt.highlight;
	
	    if (!pending) return done();
	
	    for (; i < tokens.length; i++) {
	      (function(token) {
	        if (token.type !== 'code') {
	          return --pending || done();
	        }
	        return highlight(token.text, token.lang, function(err, code) {
	          if (err) return done(err);
	          if (code == null || code === token.text) {
	            return --pending || done();
	          }
	          token.text = code;
	          token.escaped = true;
	          --pending || done();
	        });
	      })(tokens[i]);
	    }
	
	    return;
	  }
	  try {
	    if (opt) opt = merge({}, marked.defaults, opt);
	    return Parser.parse(Lexer.lex(src, opt), opt);
	  } catch (e) {
	    e.message += '\nPlease report this to https://github.com/chjj/marked.';
	    if ((opt || marked.defaults).silent) {
	      return '<p>An error occured:</p><pre>'
	        + escape(e.message + '', true)
	        + '</pre>';
	    }
	    throw e;
	  }
	}
	
	/**
	 * Options
	 */
	
	marked.options =
	marked.setOptions = function(opt) {
	  merge(marked.defaults, opt);
	  return marked;
	};
	
	marked.defaults = {
	  gfm: true,
	  tables: true,
	  breaks: false,
	  pedantic: false,
	  sanitize: false,
	  sanitizer: null,
	  mangle: true,
	  smartLists: false,
	  silent: false,
	  highlight: null,
	  langPrefix: 'lang-',
	  smartypants: false,
	  headerPrefix: '',
	  renderer: new Renderer,
	  xhtml: false
	};
	
	/**
	 * Expose
	 */
	
	marked.Parser = Parser;
	marked.parser = Parser.parse;
	
	marked.Renderer = Renderer;
	
	marked.Lexer = Lexer;
	marked.lexer = Lexer.lex;
	
	marked.InlineLexer = InlineLexer;
	marked.inlineLexer = InlineLexer.output;
	
	marked.parse = marked;
	
	if (true) {
	  module.exports = marked;
	} else if (typeof define === 'function' && define.amd) {
	  define(function() { return marked; });
	} else {
	  this.marked = marked;
	}
	
	}).call(function() {
	  return this || (typeof window !== 'undefined' ? window : global);
	}());
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
})
/** END DEFINE BLOCK for marked@0.3.6/lib/marked.js **/


/** START DEFINE BLOCK for @jupyterlab/outputarea@0.3.2/lib/widget.js **/
jupyter.define('@jupyterlab/outputarea@0.3.2/lib/widget.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var services_1 = __jupyter_require__('@jupyterlab/services@^0.42.1/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var dragdrop_1 = __jupyter_require__('@phosphor/dragdrop@^1.0.0/lib/index.js');
	var widgets_1 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	var widgets_2 = __jupyter_require__('@phosphor/widgets@^1.0.0/lib/index.js');
	/**
	 * The threshold in pixels to start a drag event.
	 */
	var DRAG_THRESHOLD = 5;
	/**
	 * The factory MIME type supported by phosphor dock panels.
	 */
	var FACTORY_MIME = 'application/vnd.phosphor.widget-factory';
	/**
	 * The class name added to an output area widget.
	 */
	var OUTPUT_AREA_CLASS = 'jp-OutputAreaWidget';
	/**
	 * The class name added to a "mirrored" output area widget created by a drag.
	 */
	var MIRRORED_OUTPUT_AREA_CLASS = 'jp-MirroredOutputArea';
	/**
	 * The class name added to an child widget.
	 */
	var CHILD_CLASS = 'jp-OutputAreaWidget-child';
	/**
	 * The class name added to output area gutters.
	 */
	var GUTTER_CLASS = 'jp-OutputAreaWidget-gutter';
	/**
	 * The class name added to output area outputs.
	 */
	var OUTPUT_CLASS = 'jp-OutputAreaWidget-output';
	/**
	 * The class name added to an execution result.
	 */
	var EXECTUTE_CLASS = 'jp-OutputAreaWidget-executeResult';
	/**
	 * The class name added to stdin data.
	 */
	var STDIN_CLASS = 'jp-OutputAreaWidget-stdin';
	/**
	 * The class name added to stdin data prompt nodes.
	 */
	var STDIN_PROMPT_CLASS = 'jp-StdinWidget-prompt';
	/**
	 * The class name added to stdin data input nodes.
	 */
	var STDIN_INPUT_CLASS = 'jp-StdinWidget-input';
	/**
	 * The class name added to stdin rendered text nodes.
	 */
	var STDIN_RENDERED_CLASS = 'jp-StdinWidget-rendered';
	/**
	 * The class name added to fixed height output areas.
	 */
	var FIXED_HEIGHT_CLASS = 'jp-mod-fixedHeight';
	/**
	 * The class name added to collaped output areas.
	 */
	var COLLAPSED_CLASS = 'jp-mod-collapsed';
	/**
	 * An output area widget.
	 *
	 * #### Notes
	 * The widget model must be set separately and can be changed
	 * at any time.  Consumers of the widget must account for a
	 * `null` model, and may want to listen to the `modelChanged`
	 * signal.
	 */
	var OutputAreaWidget = (function (_super) {
	    __extends(OutputAreaWidget, _super);
	    /**
	     * Construct an output area widget.
	     */
	    function OutputAreaWidget(options) {
	        var _this = _super.call(this) || this;
	        _this._fixedHeight = false;
	        _this._collapsed = false;
	        _this._minHeightTimeout = null;
	        var model = _this.model = options.model;
	        _this.addClass(OUTPUT_AREA_CLASS);
	        _this.rendermime = options.rendermime;
	        _this.contentFactory = (options.contentFactory || OutputAreaWidget.defaultContentFactory);
	        _this.layout = new widgets_1.PanelLayout();
	        for (var i = 0; i < model.length; i++) {
	            var output = model.get(i);
	            _this._insertOutput(i, output);
	        }
	        model.changed.connect(_this.onModelChanged, _this);
	        return _this;
	    }
	    /**
	     * Create a mirrored output area widget.
	     */
	    OutputAreaWidget.prototype.mirror = function () {
	        var rendermime = this.rendermime;
	        var contentFactory = this.contentFactory;
	        var model = this.model;
	        var widget = new OutputAreaWidget({ model: model, rendermime: rendermime, contentFactory: contentFactory });
	        widget.title.label = 'Mirrored Output';
	        widget.title.closable = true;
	        widget.addClass(MIRRORED_OUTPUT_AREA_CLASS);
	        return widget;
	    };
	    Object.defineProperty(OutputAreaWidget.prototype, "widgets", {
	        /**
	         * A read-only sequence of the widgets in the output area.
	         */
	        get: function () {
	            return this.layout.widgets;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OutputAreaWidget.prototype, "collapsed", {
	        /**
	         * The collapsed state of the widget.
	         */
	        get: function () {
	            return this._collapsed;
	        },
	        set: function (value) {
	            if (this._collapsed === value) {
	                return;
	            }
	            this._collapsed = value;
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(OutputAreaWidget.prototype, "fixedHeight", {
	        /**
	         * The fixed height state of the widget.
	         */
	        get: function () {
	            return this._fixedHeight;
	        },
	        set: function (value) {
	            if (this._fixedHeight === value) {
	                return;
	            }
	            this._fixedHeight = value;
	            this.update();
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Execute code on a client session and handle response messages.
	     */
	    OutputAreaWidget.prototype.execute = function (code, session) {
	        var _this = this;
	        // Bail if the model is disposed.
	        if (this.model.isDisposed) {
	            return Promise.reject('Model is disposed');
	        }
	        // Bail if there is no kernel.
	        var kernel = session.kernel;
	        if (!kernel) {
	            return Promise.reject('No kernel exists on the session');
	        }
	        // Override the default for `stop_on_error`.
	        var content = {
	            code: code,
	            stop_on_error: true
	        };
	        this.model.clear();
	        // Make sure there were no input widgets.
	        if (this.widgets.length) {
	            this._clear();
	        }
	        return new Promise(function (resolve, reject) {
	            var future = kernel.requestExecute(content);
	            // Handle published messages.
	            future.onIOPub = function (msg) {
	                _this._onIOPub(msg);
	            };
	            // Handle the execute reply.
	            future.onReply = function (msg) {
	                _this._onExecuteReply(msg);
	                resolve(msg);
	            };
	            // Handle stdin.
	            future.onStdin = function (msg) {
	                if (services_1.KernelMessage.isInputRequestMsg(msg)) {
	                    _this._onInputRequest(msg, session);
	                }
	            };
	        });
	    };
	    /**
	     * Handle `update-request` messages.
	     */
	    OutputAreaWidget.prototype.onUpdateRequest = function (msg) {
	        this.toggleClass(COLLAPSED_CLASS, this.collapsed);
	        this.toggleClass(FIXED_HEIGHT_CLASS, this.fixedHeight);
	    };
	    /**
	     * Follow changes on the model state.
	     */
	    OutputAreaWidget.prototype.onModelChanged = function (sender, args) {
	        switch (args.type) {
	            case 'add':
	                this._insertOutput(args.newIndex, args.newValues[0]);
	                break;
	            case 'remove':
	                // Only clear is supported by the model.
	                if (this.widgets.length) {
	                    this._clear();
	                }
	                break;
	            case 'set':
	                this._setOutput(args.newIndex, args.newValues[0]);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Clear the widget inputs and outputs.
	     */
	    OutputAreaWidget.prototype._clear = function () {
	        var _this = this;
	        // Bail if there is no work to do.
	        if (!this.widgets.length) {
	            return;
	        }
	        // Remove all of our widgets.
	        var length = this.widgets.length;
	        for (var i = 0; i < length; i++) {
	            var widget = this.widgets[0];
	            widget.parent = null;
	            widget.dispose();
	        }
	        // When an output area is cleared and then quickly replaced with new
	        // content (as happens with @interact in widgets, for example), the
	        // quickly changing height can make the page jitter.
	        // We introduce a small delay in the minimum height
	        // to prevent this jitter.
	        var rect = this.node.getBoundingClientRect();
	        this.node.style.minHeight = rect.height + "px";
	        if (this._minHeightTimeout) {
	            clearTimeout(this._minHeightTimeout);
	        }
	        this._minHeightTimeout = window.setTimeout(function () {
	            if (_this.isDisposed) {
	                return;
	            }
	            _this.node.style.minHeight = '';
	        }, 50);
	    };
	    /**
	     * Handle an iopub message.
	     */
	    OutputAreaWidget.prototype._onIOPub = function (msg) {
	        var model = this.model;
	        var msgType = msg.header.msg_type;
	        switch (msgType) {
	            case 'execute_result':
	            case 'display_data':
	            case 'stream':
	            case 'error':
	                var output = msg.content;
	                output.output_type = msgType;
	                model.add(output);
	                break;
	            case 'clear_output':
	                var wait = msg.content.wait;
	                model.clear(wait);
	                break;
	            default:
	                break;
	        }
	    };
	    /**
	     * Handle an execute reply message.
	     */
	    OutputAreaWidget.prototype._onExecuteReply = function (msg) {
	        // API responses that contain a pager are special cased and their type
	        // is overriden from 'execute_reply' to 'display_data' in order to
	        // render output.
	        var model = this.model;
	        var content = msg.content;
	        var payload = content && content.payload;
	        if (!payload || !payload.length) {
	            return;
	        }
	        var pages = payload.filter(function (i) { return i.source === 'page'; });
	        if (!pages.length) {
	            return;
	        }
	        var page = JSON.parse(JSON.stringify(pages[0]));
	        var output = {
	            output_type: 'display_data',
	            data: page.data,
	            metadata: {}
	        };
	        model.add(output);
	    };
	    /**
	     * Handle an input request from a kernel.
	     */
	    OutputAreaWidget.prototype._onInputRequest = function (msg, session) {
	        // Add an output widget to the end.
	        var factory = this.contentFactory;
	        var prompt = msg.content.prompt;
	        var password = msg.content.password;
	        var panel = new widgets_1.Panel();
	        panel.addClass(CHILD_CLASS);
	        panel.addClass(STDIN_CLASS);
	        var gutter = factory.createGutter();
	        gutter.addClass(GUTTER_CLASS);
	        panel.addWidget(gutter);
	        var kernel = session.kernel;
	        var input = factory.createStdin({ prompt: prompt, password: password, kernel: kernel });
	        input.addClass(STDIN_CLASS);
	        panel.addWidget(input);
	        var layout = this.layout;
	        layout.addWidget(panel);
	    };
	    /**
	     * Insert an output to the layout.
	     */
	    OutputAreaWidget.prototype._insertOutput = function (index, model) {
	        var panel = new widgets_1.Panel();
	        panel.addClass(CHILD_CLASS);
	        panel.addClass(OUTPUT_CLASS);
	        var gutter = this.contentFactory.createGutter();
	        gutter.executionCount = model.executionCount;
	        gutter.addClass(GUTTER_CLASS);
	        panel.addWidget(gutter);
	        var output = this._createOutput(model);
	        output.toggleClass(EXECTUTE_CLASS, model.executionCount !== null);
	        panel.addWidget(output);
	        var layout = this.layout;
	        layout.insertWidget(index, panel);
	    };
	    /**
	     * Update an output in place.
	     */
	    OutputAreaWidget.prototype._setOutput = function (index, model) {
	        var layout = this.layout;
	        var widgets = this.widgets;
	        // Skip any stdin widgets to find the correct index.
	        for (var i = 0; i < index; i++) {
	            if (widgets[i].hasClass(STDIN_CLASS)) {
	                index++;
	            }
	        }
	        layout.widgets[index].dispose();
	        this._insertOutput(index, model);
	    };
	    /**
	     * Create an output.
	     */
	    OutputAreaWidget.prototype._createOutput = function (model) {
	        var widget = this.rendermime.render(model);
	        widget.addClass(CHILD_CLASS);
	        widget.addClass(OUTPUT_CLASS);
	        return widget;
	    };
	    return OutputAreaWidget;
	}(widgets_2.Widget));
	exports.OutputAreaWidget = OutputAreaWidget;
	/**
	 * A namespace for OutputAreaWidget statics.
	 */
	(function (OutputAreaWidget) {
	    /**
	     * The default implementation of `IContentFactory`.
	     */
	    var ContentFactory = (function () {
	        function ContentFactory() {
	        }
	        /**
	         * Create the gutter for the widget.
	         */
	        ContentFactory.prototype.createGutter = function () {
	            return new GutterWidget();
	        };
	        /**
	         * Create an stdin widget.
	         */
	        ContentFactory.prototype.createStdin = function (options) {
	            return new StdinWidget(options);
	        };
	        return ContentFactory;
	    }());
	    OutputAreaWidget.ContentFactory = ContentFactory;
	    /**
	     * The default `ContentFactory` instance.
	     */
	    OutputAreaWidget.defaultContentFactory = new ContentFactory();
	    /**
	     * The default stdin widget.
	     */
	    var StdinWidget = (function (_super) {
	        __extends(StdinWidget, _super);
	        /**
	         * Construct a new input widget.
	         */
	        function StdinWidget(options) {
	            var _this = _super.call(this, { node: Private.createInputWidgetNode() }) || this;
	            _this._kernel = null;
	            _this._input = null;
	            var text = _this.node.firstChild;
	            text.textContent = options.prompt;
	            _this._input = _this.node.lastChild;
	            if (options.password) {
	                _this._input.type = 'password';
	            }
	            _this._kernel = options.kernel;
	            return _this;
	        }
	        /**
	         * Handle the DOM events for the widget.
	         *
	         * @param event - The DOM event sent to the widget.
	         *
	         * #### Notes
	         * This method implements the DOM `EventListener` interface and is
	         * called in response to events on the dock panel's node. It should
	         * not be called directly by user code.
	         */
	        StdinWidget.prototype.handleEvent = function (event) {
	            var input = this._input;
	            if (event.type === 'keydown') {
	                if (event.keyCode === 13) {
	                    this._kernel.sendInputReply({
	                        value: input.value
	                    });
	                    var rendered = document.createElement('span');
	                    rendered.className = STDIN_RENDERED_CLASS;
	                    if (input.type === 'password') {
	                        rendered.textContent = Array(input.value.length + 1).join('·');
	                    }
	                    else {
	                        rendered.textContent = input.value;
	                    }
	                    this.node.replaceChild(rendered, input);
	                }
	            }
	        };
	        /**
	         * Handle `after-attach` messages sent to the widget.
	         */
	        StdinWidget.prototype.onAfterAttach = function (msg) {
	            this._input.addEventListener('keydown', this);
	            this.update();
	        };
	        /**
	         * Handle `update-request` messages sent to the widget.
	         */
	        StdinWidget.prototype.onUpdateRequest = function (msg) {
	            this._input.focus();
	        };
	        /**
	         * Handle `before-detach` messages sent to the widget.
	         */
	        StdinWidget.prototype.onBeforeDetach = function (msg) {
	            this._input.removeEventListener('keydown', this);
	        };
	        return StdinWidget;
	    }(widgets_2.Widget));
	    OutputAreaWidget.StdinWidget = StdinWidget;
	    /**
	     * The default output gutter.
	     */
	    var GutterWidget = (function (_super) {
	        __extends(GutterWidget, _super);
	        function GutterWidget() {
	            var _this = _super !== null && _super.apply(this, arguments) || this;
	            _this._drag = null;
	            _this._dragData = null;
	            _this._executionCount = null;
	            return _this;
	        }
	        Object.defineProperty(GutterWidget.prototype, "executionCount", {
	            /**
	             * The execution count for the widget.
	             */
	            get: function () {
	                return this._executionCount;
	            },
	            set: function (value) {
	                this._executionCount = value;
	                if (value === null) {
	                    this.node.textContent = '';
	                }
	                else {
	                    this.node.textContent = "Out[" + value + "]:";
	                }
	            },
	            enumerable: true,
	            configurable: true
	        });
	        /**
	         * Handle the DOM events for the output gutter widget.
	         *
	         * @param event - The DOM event sent to the widget.
	         *
	         * #### Notes
	         * This method implements the DOM `EventListener` interface and is
	         * called in response to events on the panel's DOM node. It should
	         * not be called directly by user code.
	         */
	        GutterWidget.prototype.handleEvent = function (event) {
	            switch (event.type) {
	                case 'mousedown':
	                    this._evtMousedown(event);
	                    break;
	                case 'mouseup':
	                    this._evtMouseup(event);
	                    break;
	                case 'mousemove':
	                    this._evtMousemove(event);
	                    break;
	                default:
	                    break;
	            }
	        };
	        /**
	         * A message handler invoked on an `'after-attach'` message.
	         */
	        GutterWidget.prototype.onAfterAttach = function (msg) {
	            _super.prototype.onAfterAttach.call(this, msg);
	            this.node.addEventListener('mousedown', this);
	        };
	        /**
	         * A message handler invoked on a `'before-detach'` message.
	         */
	        GutterWidget.prototype.onBeforeDetach = function (msg) {
	            _super.prototype.onBeforeDetach.call(this, msg);
	            var node = this.node;
	            node.removeEventListener('mousedown', this);
	        };
	        /**
	         * Handle the `'mousedown'` event for the widget.
	         */
	        GutterWidget.prototype._evtMousedown = function (event) {
	            // Left mouse press for drag start.
	            if (event.button === 0) {
	                this._dragData = { pressX: event.clientX, pressY: event.clientY };
	                document.addEventListener('mouseup', this, true);
	                document.addEventListener('mousemove', this, true);
	            }
	        };
	        /**
	         * Handle the `'mouseup'` event for the widget.
	         */
	        GutterWidget.prototype._evtMouseup = function (event) {
	            if (event.button !== 0 || !this._drag) {
	                document.removeEventListener('mousemove', this, true);
	                document.removeEventListener('mouseup', this, true);
	                return;
	            }
	            event.preventDefault();
	            event.stopPropagation();
	        };
	        /**
	         * Handle the `'mousemove'` event for the widget.
	         */
	        GutterWidget.prototype._evtMousemove = function (event) {
	            event.preventDefault();
	            event.stopPropagation();
	            // Bail if we are the one dragging.
	            if (this._drag) {
	                return;
	            }
	            // Check for a drag initialization.
	            var data = this._dragData;
	            var dx = Math.abs(event.clientX - data.pressX);
	            var dy = Math.abs(event.clientY - data.pressY);
	            if (dx < DRAG_THRESHOLD && dy < DRAG_THRESHOLD) {
	                return;
	            }
	            this._startDrag(event.clientX, event.clientY);
	        };
	        /**
	         * Start a drag event.
	         */
	        GutterWidget.prototype._startDrag = function (clientX, clientY) {
	            var _this = this;
	            // Set up the drag event.
	            this._drag = new dragdrop_1.Drag({
	                mimeData: new coreutils_1.MimeData(),
	                supportedActions: 'copy',
	                proposedAction: 'copy'
	            });
	            this._drag.mimeData.setData(FACTORY_MIME, function () {
	                var outputArea = _this.parent.parent;
	                return outputArea.mirror();
	            });
	            // Remove mousemove and mouseup listeners and start the drag.
	            document.removeEventListener('mousemove', this, true);
	            document.removeEventListener('mouseup', this, true);
	            this._drag.start(clientX, clientY).then(function (action) {
	                _this._drag = null;
	            });
	        };
	        /**
	         * Dispose of the resources held by the widget.
	         */
	        GutterWidget.prototype.dispose = function () {
	            this._dragData = null;
	            this._drag = null;
	            _super.prototype.dispose.call(this);
	        };
	        return GutterWidget;
	    }(widgets_2.Widget));
	    OutputAreaWidget.GutterWidget = GutterWidget;
	})(OutputAreaWidget = exports.OutputAreaWidget || (exports.OutputAreaWidget = {}));
	exports.OutputAreaWidget = OutputAreaWidget;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Create the node for an InputWidget.
	     */
	    function createInputWidgetNode() {
	        var node = document.createElement('div');
	        var prompt = document.createElement('span');
	        prompt.className = STDIN_PROMPT_CLASS;
	        var input = document.createElement('input');
	        input.className = STDIN_INPUT_CLASS;
	        node.appendChild(prompt);
	        node.appendChild(input);
	        return node;
	    }
	    Private.createInputWidgetNode = createInputWidgetNode;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/outputarea@0.3.2/lib/widget.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/index.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/config/index.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/contents/index.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/index.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/manager.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/session/index.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/terminal/index.js'));
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	exports.utils = utils;
	/* tslint:disable */
	/**
	 * The default services provider token.
	 */
	exports.IServiceManager = new coreutils_1.Token('jupyter.services.services');
	;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/index.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/config/index.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/config/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	/**
	 * The url for the config service.
	 */
	var SERVICE_CONFIG_URL = 'api/config';
	/**
	 * The namespace for ConfigSection statics.
	 */
	var ConfigSection;
	(function (ConfigSection) {
	    /**
	     * Create a config section.
	     *
	     * @returns A Promise that is fulfilled with the config section is loaded.
	     */
	    function create(options) {
	        var section = new DefaultConfigSection(options);
	        return section.load().then(function () {
	            return section;
	        });
	    }
	    ConfigSection.create = create;
	})(ConfigSection = exports.ConfigSection || (exports.ConfigSection = {}));
	/**
	 * Implementation of the Configurable data section.
	 */
	var DefaultConfigSection = (function () {
	    /**
	     * Construct a new config section.
	     */
	    function DefaultConfigSection(options) {
	        this._url = 'unknown';
	        this._data = null;
	        this._ajaxSettings = null;
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        this.ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        this._url = utils.urlPathJoin(baseUrl, SERVICE_CONFIG_URL, encodeURIComponent(options.name));
	    }
	    Object.defineProperty(DefaultConfigSection.prototype, "ajaxSettings", {
	        /**
	         * Get a copy of the default ajax settings for the section.
	         */
	        get: function () {
	            return utils.copy(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the section.
	         */
	        set: function (value) {
	            this._ajaxSettings = utils.copy(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultConfigSection.prototype, "data", {
	        /**
	         * Get the data for this section.
	         */
	        get: function () {
	            return this._data;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Load the initial data for this section.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/config).
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    DefaultConfigSection.prototype.load = function () {
	        var _this = this;
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(this._url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            _this._data = success.data;
	        });
	    };
	    /**
	     * Modify the stored config values.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/config).
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     *
	     * Updates the local data immediately, sends the change to the server,
	     * and updates the local data with the response, and fulfils the promise
	     * with that data.
	     */
	    DefaultConfigSection.prototype.update = function (newdata) {
	        var _this = this;
	        this._data = utils.extend(this._data, newdata);
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'PATCH';
	        ajaxSettings.data = JSON.stringify(newdata);
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.contentType = 'application/json';
	        return utils.ajaxRequest(this._url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            _this._data = success.data;
	            return _this._data;
	        });
	    };
	    return DefaultConfigSection;
	}());
	/**
	 * Configurable object with defaults.
	 */
	var ConfigWithDefaults = (function () {
	    /**
	     * Create a new config with defaults.
	     */
	    function ConfigWithDefaults(options) {
	        this._section = null;
	        this._defaults = null;
	        this._className = '';
	        this._section = options.section;
	        this._defaults = options.defaults || {};
	        this._className = options.className || '';
	    }
	    /**
	     * Get data from the config section or fall back to defaults.
	     */
	    ConfigWithDefaults.prototype.get = function (key) {
	        var data = this._classData();
	        return key in data ? data[key] : this._defaults[key];
	    };
	    /**
	     * Set a config value.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/config).
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     *
	     * Sends the update to the server, and changes our local copy of the data
	     * immediately.
	     */
	    ConfigWithDefaults.prototype.set = function (key, value) {
	        var d = {};
	        d[key] = value;
	        if (this._className) {
	            var d2 = {};
	            d2[this._className] = d;
	            return this._section.update(d2);
	        }
	        else {
	            return this._section.update(d);
	        }
	    };
	    /**
	     * Get data from the Section with our classname, if available.
	     *
	     * #### Notes
	     * If we have no classname, get all of the data in the Section
	     */
	    ConfigWithDefaults.prototype._classData = function () {
	        var data = this._section.data;
	        if (this._className && this._className in data) {
	            return data[this._className];
	        }
	        return data;
	    };
	    return ConfigWithDefaults;
	}());
	exports.ConfigWithDefaults = ConfigWithDefaults;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/config/index.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/utils.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/utils.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(process) {// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	Object.defineProperty(exports, "__esModule", { value: true });
	var minimist = __jupyter_require__('minimist@^1.2.0/index.js');
	var path = __jupyter_require__('path-posix@^1.0.0/index.js');
	var urlparse = __jupyter_require__('url-parse@^1.1.8/index.js');
	// Export the Promise Delegate for now to preserve API.
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	exports.PromiseDelegate = coreutils_1.PromiseDelegate;
	/**
	 * Copy the contents of one object to another, recursively.
	 *
	 * From [stackoverflow](http://stackoverflow.com/a/12317051).
	 */
	function extend(target, source) {
	    target = target || {};
	    for (var prop in source) {
	        if (typeof source[prop] === 'object') {
	            target[prop] = extend(target[prop], source[prop]);
	        }
	        else {
	            target[prop] = source[prop];
	        }
	    }
	    return target;
	}
	exports.extend = extend;
	/**
	 * Get a deep copy of a JSON object.
	 */
	function copy(object) {
	    return JSON.parse(JSON.stringify(object));
	}
	exports.copy = copy;
	/**
	 * Get a random 32 character hex string (not a formal UUID)
	 */
	function uuid() {
	    var s = [];
	    var hexDigits = '0123456789abcdef';
	    var nChars = hexDigits.length;
	    for (var i = 0; i < 32; i++) {
	        s[i] = hexDigits.charAt(Math.floor(Math.random() * nChars));
	    }
	    return s.join('');
	}
	exports.uuid = uuid;
	/**
	 * Parse a url into a URL object.
	 *
	 * @param url - The URL string to parse.
	 *
	 * @returns A URL object.
	 */
	function urlParse(url) {
	    if (typeof document !== 'undefined') {
	        var a = document.createElement('a');
	        a.href = url;
	        return a;
	    }
	    return urlparse(url);
	}
	exports.urlParse = urlParse;
	/**
	 * Join a sequence of url components with `'/'`.
	 */
	function urlPathJoin() {
	    var parts = [];
	    for (var _i = 0; _i < arguments.length; _i++) {
	        parts[_i] = arguments[_i];
	    }
	    // Adapted from url-join.
	    // Copyright (c) 2016 José F. Romaniello, MIT License.
	    // https://github.com/jfromaniello/url-join/blob/v1.1.0/lib/url-join.js
	    var str = [].slice.call(parts, 0).join('/');
	    // make sure protocol is followed by two slashes
	    str = str.replace(/:\//g, '://');
	    // remove consecutive slashes
	    str = str.replace(/([^:\s])\/+/g, '$1/');
	    // remove trailing slash before parameters or hash
	    str = str.replace(/\/(\?|&|#[^!])/g, '$1');
	    // replace ? in parameters with &
	    str = str.replace(/(\?.+)\?/g, '$1&');
	    return str;
	}
	exports.urlPathJoin = urlPathJoin;
	/**
	 * Encode the components of a multi-segment url.
	 *
	 * #### Notes
	 * Preserves the `'/'` separators.
	 * Should not include the base url, since all parts are escaped.
	 */
	function urlEncodeParts(uri) {
	    return urlPathJoin.apply(void 0, uri.split('/').map(encodeURIComponent));
	}
	exports.urlEncodeParts = urlEncodeParts;
	/**
	 * Return a serialized object string suitable for a query.
	 *
	 * From [stackoverflow](http://stackoverflow.com/a/30707423).
	 */
	function jsonToQueryString(json) {
	    return '?' + Object.keys(json).map(function (key) {
	        return encodeURIComponent(key) + '=' + encodeURIComponent(String(json[key]));
	    }).join('&');
	}
	exports.jsonToQueryString = jsonToQueryString;
	function _getCookie(name) {
	    // from tornado docs: http://www.tornadoweb.org/en/stable/guide/security.html
	    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
	    return r ? r[1] : void 0;
	}
	/**
	 * Asynchronous XMLHTTPRequest handler.
	 *
	 * @param url - The url to request.
	 *
	 * @param settings - The settings to apply to the request and response.
	 *
	 * #### Notes
	 * Based on this [example](http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest).
	 */
	function ajaxRequest(url, ajaxSettings) {
	    var method = ajaxSettings.method || 'GET';
	    // Ensure that requests have applied data.
	    if (!ajaxSettings.data) {
	        ajaxSettings.data = '{}';
	        ajaxSettings.contentType = 'application/json';
	    }
	    var user = ajaxSettings.user || '';
	    var password = ajaxSettings.password || '';
	    var headers = ajaxSettings.requestHeaders || {};
	    if (!ajaxSettings.cache) {
	        // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache.
	        url += ((/\?/).test(url) ? '&' : '?') + (new Date()).getTime();
	    }
	    return new Promise(function (resolve, reject) {
	        var xhr = new XMLHttpRequest();
	        xhr.open(method, url, true, user, password);
	        if (ajaxSettings.contentType !== void 0) {
	            xhr.setRequestHeader('Content-Type', ajaxSettings.contentType);
	        }
	        if (ajaxSettings.timeout !== void 0) {
	            xhr.timeout = ajaxSettings.timeout;
	        }
	        if (!!ajaxSettings.withCredentials) {
	            xhr.withCredentials = true;
	        }
	        // Try to add the xsrf token if there is no existing authorization.
	        var token = headers['Authorization'];
	        if (!token && typeof document !== 'undefined' && document.cookie) {
	            var xsrfToken = _getCookie('_xsrf');
	            if (xsrfToken !== void 0) {
	                xhr.setRequestHeader('X-XSRFToken', xsrfToken);
	            }
	        }
	        for (var prop in headers) {
	            xhr.setRequestHeader(prop, headers[prop]);
	        }
	        xhr.onload = function (event) {
	            if (xhr.status >= 300) {
	                reject({ event: event, xhr: xhr, ajaxSettings: ajaxSettings, throwError: xhr.statusText });
	            }
	            var data = xhr.responseText;
	            try {
	                data = JSON.parse(data);
	            }
	            catch (err) {
	                // no-op
	            }
	            resolve({ xhr: xhr, ajaxSettings: ajaxSettings, data: data, event: event });
	        };
	        xhr.onabort = function (event) {
	            reject({ xhr: xhr, event: event, ajaxSettings: ajaxSettings });
	        };
	        xhr.onerror = function (event) {
	            reject({ xhr: xhr, event: event, ajaxSettings: ajaxSettings });
	        };
	        xhr.ontimeout = function (ev) {
	            reject({ xhr: xhr, event: event, ajaxSettings: ajaxSettings });
	        };
	        if (ajaxSettings.data) {
	            xhr.send(ajaxSettings.data);
	        }
	        else {
	            xhr.send();
	        }
	    });
	}
	exports.ajaxRequest = ajaxRequest;
	/**
	 * Create an ajax error from an ajax success.
	 *
	 * @param success - The original success object.
	 *
	 * @param throwError - The optional new error name.  If not given
	 *  we use "Invalid Status: <xhr.status>"
	 */
	function makeAjaxError(success, throwError) {
	    var xhr = success.xhr;
	    var ajaxSettings = success.ajaxSettings;
	    var event = success.event;
	    throwError = throwError || "Invalid Status: " + xhr.status;
	    return { xhr: xhr, ajaxSettings: ajaxSettings, event: event, throwError: throwError };
	}
	exports.makeAjaxError = makeAjaxError;
	/**
	 * Try to load an object from a module or a registry.
	 *
	 * Try to load an object from a module asynchronously if a module
	 * is specified, otherwise tries to load an object from the global
	 * registry, if the global registry is provided.
	 */
	function loadObject(name, moduleName, registry) {
	    return new Promise(function (resolve, reject) {
	        // Try loading the view module using require.js
	        if (moduleName) {
	            if (typeof requirejs === 'undefined') {
	                throw new Error('requirejs not found');
	            }
	            requirejs([moduleName], function (mod) {
	                if (mod[name] === void 0) {
	                    var msg = "Object '" + name + "' not found in module '" + moduleName + "'";
	                    reject(new Error(msg));
	                }
	                else {
	                    resolve(mod[name]);
	                }
	            }, reject);
	        }
	        else {
	            if (registry && registry[name]) {
	                resolve(registry[name]);
	            }
	            else {
	                reject(new Error("Object '" + name + "' not found in registry"));
	            }
	        }
	    });
	}
	exports.loadObject = loadObject;
	;
	/**
	 * Global config data for the Jupyter application.
	 */
	var configData = null;
	/**
	 *  Make an object fully immutable by freezing each object in it.
	 */
	function deepFreeze(obj) {
	    // Freeze properties before freezing self
	    Object.getOwnPropertyNames(obj).forEach(function (name) {
	        var prop = obj[name];
	        // Freeze prop if it is an object
	        if (typeof prop === 'object' && prop !== null && !Object.isFrozen(prop)) {
	            deepFreeze(prop);
	        }
	    });
	    // Freeze self
	    return Object.freeze(obj);
	}
	/**
	 * Get global configuration data for the Jupyter application.
	 *
	 * @param name - The name of the configuration option.
	 *
	 * @returns The config value or `undefined` if not found.
	 *
	 * #### Notes
	 * For browser based applications, it is assumed that the page HTML
	 * includes a script tag with the id `jupyter-config-data` containing the
	 * configuration as valid JSON.
	 */
	function getConfigOption(name) {
	    if (configData) {
	        return configData[name];
	    }
	    if (typeof document === 'undefined') {
	        configData = minimist(process.argv.slice(2));
	    }
	    else {
	        var el = document.getElementById('jupyter-config-data');
	        if (el) {
	            configData = JSON.parse(el.textContent);
	        }
	        else {
	            configData = {};
	        }
	    }
	    configData = deepFreeze(configData);
	    return configData[name];
	}
	exports.getConfigOption = getConfigOption;
	/**
	 * Get the base URL for a Jupyter application.
	 */
	function getBaseUrl() {
	    var baseUrl = getConfigOption('baseUrl');
	    if (!baseUrl || baseUrl === '/') {
	        baseUrl = (typeof location === 'undefined' ?
	            'http://localhost:8888/' : location.origin + '/');
	    }
	    return baseUrl;
	}
	exports.getBaseUrl = getBaseUrl;
	/**
	 * Get the base websocket URL for a Jupyter application.
	 */
	function getWsUrl(baseUrl) {
	    var wsUrl = getConfigOption('wsUrl');
	    if (!wsUrl) {
	        baseUrl = baseUrl || getBaseUrl();
	        if (baseUrl.indexOf('http') !== 0) {
	            if (typeof location !== 'undefined') {
	                baseUrl = path.join(location.origin, baseUrl);
	            }
	            else {
	                baseUrl = path.join('http://localhost:8888/', baseUrl);
	            }
	        }
	        wsUrl = 'ws' + baseUrl.slice(4);
	    }
	    return wsUrl;
	}
	exports.getWsUrl = getWsUrl;
	/**
	 * Add token to ajaxSettings.requestHeaders if defined.
	 * Always returns a copy of ajaxSettings, and a dict.
	 */
	function ajaxSettingsWithToken(ajaxSettings, token) {
	    if (!ajaxSettings) {
	        ajaxSettings = {};
	    }
	    else {
	        ajaxSettings = copy(ajaxSettings);
	    }
	    if (!token) {
	        token = getConfigOption('token');
	    }
	    if (!token || token === '') {
	        return ajaxSettings;
	    }
	    if (!ajaxSettings.requestHeaders) {
	        ajaxSettings.requestHeaders = {};
	    }
	    ajaxSettings.requestHeaders['Authorization'] = "token " + token;
	    return ajaxSettings;
	}
	exports.ajaxSettingsWithToken = ajaxSettingsWithToken;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('process@0.11.10/browser.js')))
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/utils.js **/


/** START DEFINE BLOCK for minimist@1.2.0/index.js **/
jupyter.define('minimist@1.2.0/index.js', function (module, exports, __jupyter_require__) {
	module.exports = function (args, opts) {
	    if (!opts) opts = {};
	    
	    var flags = { bools : {}, strings : {}, unknownFn: null };
	
	    if (typeof opts['unknown'] === 'function') {
	        flags.unknownFn = opts['unknown'];
	    }
	
	    if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
	      flags.allBools = true;
	    } else {
	      [].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
	          flags.bools[key] = true;
	      });
	    }
	    
	    var aliases = {};
	    Object.keys(opts.alias || {}).forEach(function (key) {
	        aliases[key] = [].concat(opts.alias[key]);
	        aliases[key].forEach(function (x) {
	            aliases[x] = [key].concat(aliases[key].filter(function (y) {
	                return x !== y;
	            }));
	        });
	    });
	
	    [].concat(opts.string).filter(Boolean).forEach(function (key) {
	        flags.strings[key] = true;
	        if (aliases[key]) {
	            flags.strings[aliases[key]] = true;
	        }
	     });
	
	    var defaults = opts['default'] || {};
	    
	    var argv = { _ : [] };
	    Object.keys(flags.bools).forEach(function (key) {
	        setArg(key, defaults[key] === undefined ? false : defaults[key]);
	    });
	    
	    var notFlags = [];
	
	    if (args.indexOf('--') !== -1) {
	        notFlags = args.slice(args.indexOf('--')+1);
	        args = args.slice(0, args.indexOf('--'));
	    }
	
	    function argDefined(key, arg) {
	        return (flags.allBools && /^--[^=]+$/.test(arg)) ||
	            flags.strings[key] || flags.bools[key] || aliases[key];
	    }
	
	    function setArg (key, val, arg) {
	        if (arg && flags.unknownFn && !argDefined(key, arg)) {
	            if (flags.unknownFn(arg) === false) return;
	        }
	
	        var value = !flags.strings[key] && isNumber(val)
	            ? Number(val) : val
	        ;
	        setKey(argv, key.split('.'), value);
	        
	        (aliases[key] || []).forEach(function (x) {
	            setKey(argv, x.split('.'), value);
	        });
	    }
	
	    function setKey (obj, keys, value) {
	        var o = obj;
	        keys.slice(0,-1).forEach(function (key) {
	            if (o[key] === undefined) o[key] = {};
	            o = o[key];
	        });
	
	        var key = keys[keys.length - 1];
	        if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
	            o[key] = value;
	        }
	        else if (Array.isArray(o[key])) {
	            o[key].push(value);
	        }
	        else {
	            o[key] = [ o[key], value ];
	        }
	    }
	    
	    function aliasIsBoolean(key) {
	      return aliases[key].some(function (x) {
	          return flags.bools[x];
	      });
	    }
	
	    for (var i = 0; i < args.length; i++) {
	        var arg = args[i];
	        
	        if (/^--.+=/.test(arg)) {
	            // Using [\s\S] instead of . because js doesn't support the
	            // 'dotall' regex modifier. See:
	            // http://stackoverflow.com/a/1068308/13216
	            var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
	            var key = m[1];
	            var value = m[2];
	            if (flags.bools[key]) {
	                value = value !== 'false';
	            }
	            setArg(key, value, arg);
	        }
	        else if (/^--no-.+/.test(arg)) {
	            var key = arg.match(/^--no-(.+)/)[1];
	            setArg(key, false, arg);
	        }
	        else if (/^--.+/.test(arg)) {
	            var key = arg.match(/^--(.+)/)[1];
	            var next = args[i + 1];
	            if (next !== undefined && !/^-/.test(next)
	            && !flags.bools[key]
	            && !flags.allBools
	            && (aliases[key] ? !aliasIsBoolean(key) : true)) {
	                setArg(key, next, arg);
	                i++;
	            }
	            else if (/^(true|false)$/.test(next)) {
	                setArg(key, next === 'true', arg);
	                i++;
	            }
	            else {
	                setArg(key, flags.strings[key] ? '' : true, arg);
	            }
	        }
	        else if (/^-[^-]+/.test(arg)) {
	            var letters = arg.slice(1,-1).split('');
	            
	            var broken = false;
	            for (var j = 0; j < letters.length; j++) {
	                var next = arg.slice(j+2);
	                
	                if (next === '-') {
	                    setArg(letters[j], next, arg)
	                    continue;
	                }
	                
	                if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
	                    setArg(letters[j], next.split('=')[1], arg);
	                    broken = true;
	                    break;
	                }
	                
	                if (/[A-Za-z]/.test(letters[j])
	                && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
	                    setArg(letters[j], next, arg);
	                    broken = true;
	                    break;
	                }
	                
	                if (letters[j+1] && letters[j+1].match(/\W/)) {
	                    setArg(letters[j], arg.slice(j+2), arg);
	                    broken = true;
	                    break;
	                }
	                else {
	                    setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
	                }
	            }
	            
	            var key = arg.slice(-1)[0];
	            if (!broken && key !== '-') {
	                if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
	                && !flags.bools[key]
	                && (aliases[key] ? !aliasIsBoolean(key) : true)) {
	                    setArg(key, args[i+1], arg);
	                    i++;
	                }
	                else if (args[i+1] && /true|false/.test(args[i+1])) {
	                    setArg(key, args[i+1] === 'true', arg);
	                    i++;
	                }
	                else {
	                    setArg(key, flags.strings[key] ? '' : true, arg);
	                }
	            }
	        }
	        else {
	            if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
	                argv._.push(
	                    flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
	                );
	            }
	            if (opts.stopEarly) {
	                argv._.push.apply(argv._, args.slice(i + 1));
	                break;
	            }
	        }
	    }
	    
	    Object.keys(defaults).forEach(function (key) {
	        if (!hasKey(argv, key.split('.'))) {
	            setKey(argv, key.split('.'), defaults[key]);
	            
	            (aliases[key] || []).forEach(function (x) {
	                setKey(argv, x.split('.'), defaults[key]);
	            });
	        }
	    });
	    
	    if (opts['--']) {
	        argv['--'] = new Array();
	        notFlags.forEach(function(key) {
	            argv['--'].push(key);
	        });
	    }
	    else {
	        notFlags.forEach(function(key) {
	            argv._.push(key);
	        });
	    }
	
	    return argv;
	};
	
	function hasKey (obj, keys) {
	    var o = obj;
	    keys.slice(0,-1).forEach(function (key) {
	        o = (o[key] || {});
	    });
	
	    var key = keys[keys.length - 1];
	    return key in o;
	}
	
	function isNumber (x) {
	    if (typeof x === 'number') return true;
	    if (/^0x[0-9a-f]+$/i.test(x)) return true;
	    return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
	}
	
	
})
/** END DEFINE BLOCK for minimist@1.2.0/index.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/contents/index.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/contents/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	var validate = __jupyter_require__('@jupyterlab/services@0.42.1/lib/contents/validate.js');
	/**
	 * The url for the contents service.
	 */
	var SERVICE_CONTENTS_URL = 'api/contents';
	/**
	 * The url for the file access.
	 */
	var FILES_URL = 'files';
	/**
	 * A contents manager that passes file operations to the server.
	 *
	 * This includes checkpointing with the normal file operations.
	 */
	var ContentsManager = (function () {
	    /**
	     * Construct a new contents manager object.
	     *
	     * @param options - The options used to initialize the object.
	     */
	    function ContentsManager(options) {
	        if (options === void 0) { options = {}; }
	        this._baseUrl = '';
	        this._isDisposed = false;
	        this._ajaxSettings = null;
	        this._fileChanged = new signaling_1.Signal(this);
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	    }
	    Object.defineProperty(ContentsManager.prototype, "fileChanged", {
	        /**
	         * A signal emitted when a file operation takes place.
	         */
	        get: function () {
	            return this._fileChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ContentsManager.prototype, "isDisposed", {
	        /**
	         * Test whether the manager has been disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the manager.
	     */
	    ContentsManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        signaling_1.Signal.clearData(this);
	    };
	    Object.defineProperty(ContentsManager.prototype, "baseUrl", {
	        /**
	         * Get the base url of the manager.
	         */
	        get: function () {
	            return this._baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ContentsManager.prototype, "ajaxSettings", {
	        /**
	         * Get a copy of the default ajax settings for the contents manager.
	         */
	        get: function () {
	            return utils.copy(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the contents manager.
	         */
	        set: function (value) {
	            this._ajaxSettings = utils.copy(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get a file or directory.
	     *
	     * @param path: The path to the file.
	     *
	     * @param options: The options used to fetch the file.
	     *
	     * @returns A promise which resolves with the file content.
	     *
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents) and validates the response model.
	     */
	    ContentsManager.prototype.get = function (path, options) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        var url = this._getUrl(path);
	        if (options) {
	            // The notebook type cannot take an format option.
	            if (options.type === 'notebook') {
	                delete options['format'];
	            }
	            var params = utils.copy(options);
	            params.content = options.content ? '1' : '0';
	            url += utils.jsonToQueryString(params);
	        }
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            try {
	                validate.validateContentsModel(success.data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            return success.data;
	        });
	    };
	    /**
	     * Get an encoded download url given a file path.
	     *
	     * @param path - An absolute POSIX file path on the server.
	     *
	     * #### Notes
	     * It is expected that the path contains no relative paths.
	     */
	    ContentsManager.prototype.getDownloadUrl = function (path) {
	        return Promise.resolve(utils.urlPathJoin(this._baseUrl, FILES_URL, utils.urlEncodeParts(path)));
	    };
	    /**
	     * Create a new untitled file or directory in the specified directory path.
	     *
	     * @param options: The options used to create the file.
	     *
	     * @returns A promise which resolves with the created file content when the
	     *    file is created.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents) and validates the response model.
	     */
	    ContentsManager.prototype.newUntitled = function (options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'POST';
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.dataType = 'json';
	        if (options) {
	            if (options.ext) {
	                options.ext = Private.normalizeExtension(options.ext);
	            }
	            ajaxSettings.data = JSON.stringify(options);
	        }
	        var url = this._getUrl(options.path || '');
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 201) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            try {
	                validate.validateContentsModel(data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            _this._fileChanged.emit({
	                type: 'new',
	                oldValue: null,
	                newValue: data
	            });
	            return data;
	        });
	    };
	    /**
	     * Delete a file.
	     *
	     * @param path - The path to the file.
	     *
	     * @returns A promise which resolves when the file is deleted.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents).
	     */
	    ContentsManager.prototype.delete = function (path) {
	        var _this = this;
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'DELETE';
	        ajaxSettings.dataType = 'json';
	        var url = this._getUrl(path);
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw utils.makeAjaxError(success);
	            }
	            _this._fileChanged.emit({
	                type: 'delete',
	                oldValue: { path: path },
	                newValue: null
	            });
	        }, function (error) {
	            // Translate certain errors to more specific ones.
	            // TODO: update IPEP27 to specify errors more precisely, so
	            // that error types can be detected here with certainty.
	            if (error.xhr.status === 400) {
	                var err = JSON.parse(error.xhr.response);
	                if (err.message) {
	                    error.throwError = err.message;
	                }
	            }
	            return Promise.reject(error);
	        });
	    };
	    /**
	     * Rename a file or directory.
	     *
	     * @param path - The original file path.
	     *
	     * @param newPath - The new file path.
	     *
	     * @returns A promise which resolves with the new file contents model when
	     *   the file is renamed.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents) and validates the response model.
	     */
	    ContentsManager.prototype.rename = function (path, newPath) {
	        var _this = this;
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'PATCH';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.data = JSON.stringify({ path: newPath });
	        var url = this._getUrl(path);
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            try {
	                validate.validateContentsModel(data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            _this._fileChanged.emit({
	                type: 'rename',
	                oldValue: { path: path },
	                newValue: data
	            });
	            return data;
	        });
	    };
	    /**
	     * Save a file.
	     *
	     * @param path - The desired file path.
	     *
	     * @param options - Optional overrides to the model.
	     *
	     * @returns A promise which resolves with the file content model when the
	     *   file is saved.
	     *
	     * #### Notes
	     * Ensure that `model.content` is populated for the file.
	     *
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents) and validates the response model.
	     */
	    ContentsManager.prototype.save = function (path, options) {
	        var _this = this;
	        if (options === void 0) { options = {}; }
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'PUT';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.data = JSON.stringify(options);
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.cache = false;
	        var url = this._getUrl(path);
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            // will return 200 for an existing file and 201 for a new file
	            if (success.xhr.status !== 200 && success.xhr.status !== 201) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            try {
	                validate.validateContentsModel(data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            _this._fileChanged.emit({
	                type: 'save',
	                oldValue: null,
	                newValue: data
	            });
	            return data;
	        });
	    };
	    /**
	     * Copy a file into a given directory.
	     *
	     * @param path - The original file path.
	     *
	     * @param toDir - The destination directory path.
	     *
	     * @returns A promise which resolves with the new contents model when the
	     *  file is copied.
	     *
	     * #### Notes
	     * The server will select the name of the copied file.
	     *
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents) and validates the response model.
	     */
	    ContentsManager.prototype.copy = function (fromFile, toDir) {
	        var _this = this;
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'POST';
	        ajaxSettings.data = JSON.stringify({ copy_from: fromFile });
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.dataType = 'json';
	        var url = this._getUrl(toDir);
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 201) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            try {
	                validate.validateContentsModel(data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            _this._fileChanged.emit({
	                type: 'new',
	                oldValue: null,
	                newValue: data
	            });
	            return data;
	        });
	    };
	    /**
	     * Create a checkpoint for a file.
	     *
	     * @param path - The path of the file.
	     *
	     * @returns A promise which resolves with the new checkpoint model when the
	     *   checkpoint is created.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents) and validates the response model.
	     */
	    ContentsManager.prototype.createCheckpoint = function (path) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        var url = this._getUrl(path, 'checkpoints');
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 201) {
	                throw utils.makeAjaxError(success);
	            }
	            try {
	                validate.validateCheckpointModel(success.data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            return success.data;
	        });
	    };
	    /**
	     * List available checkpoints for a file.
	     *
	     * @param path - The path of the file.
	     *
	     * @returns A promise which resolves with a list of checkpoint models for
	     *    the file.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents) and validates the response model.
	     */
	    ContentsManager.prototype.listCheckpoints = function (path) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        var url = this._getUrl(path, 'checkpoints');
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            if (!Array.isArray(success.data)) {
	                throw utils.makeAjaxError(success, 'Invalid Checkpoint list');
	            }
	            for (var i = 0; i < success.data.length; i++) {
	                try {
	                    validate.validateCheckpointModel(success.data[i]);
	                }
	                catch (err) {
	                    throw utils.makeAjaxError(success, err.message);
	                }
	            }
	            return success.data;
	        });
	    };
	    /**
	     * Restore a file to a known checkpoint state.
	     *
	     * @param path - The path of the file.
	     *
	     * @param checkpointID - The id of the checkpoint to restore.
	     *
	     * @returns A promise which resolves when the checkpoint is restored.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents).
	     */
	    ContentsManager.prototype.restoreCheckpoint = function (path, checkpointID) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        var url = this._getUrl(path, 'checkpoints', checkpointID);
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw utils.makeAjaxError(success);
	            }
	        });
	    };
	    /**
	     * Delete a checkpoint for a file.
	     *
	     * @param path - The path of the file.
	     *
	     * @param checkpointID - The id of the checkpoint to delete.
	     *
	     * @returns A promise which resolves when the checkpoint is deleted.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/contents).
	     */
	    ContentsManager.prototype.deleteCheckpoint = function (path, checkpointID) {
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'DELETE';
	        ajaxSettings.dataType = 'json';
	        var url = this._getUrl(path, 'checkpoints', checkpointID);
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw utils.makeAjaxError(success);
	            }
	        });
	    };
	    /**
	     * Get a REST url for a file given a path.
	     */
	    ContentsManager.prototype._getUrl = function () {
	        var args = [];
	        for (var _i = 0; _i < arguments.length; _i++) {
	            args[_i] = arguments[_i];
	        }
	        var parts = args.map(function (path) { return utils.urlEncodeParts(path); });
	        return utils.urlPathJoin.apply(utils, [this._baseUrl, SERVICE_CONTENTS_URL].concat(parts));
	    };
	    return ContentsManager;
	}());
	exports.ContentsManager = ContentsManager;
	/**
	 * A namespace for module private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * Normalize a file extension to be of the type `'.foo'`.
	     *
	     * Adds a leading dot if not present and converts to lower case.
	     */
	    function normalizeExtension(extension) {
	        if (extension.length > 0 && extension.indexOf('.') !== 0) {
	            extension = "." + extension;
	        }
	        return extension;
	    }
	    Private.normalizeExtension = normalizeExtension;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/contents/index.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/contents/validate.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/contents/validate.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Validate a property as being on an object, and optionally
	 * of a given type.
	 */
	function validateProperty(object, name, typeName) {
	    if (!object.hasOwnProperty(name)) {
	        throw Error("Missing property '" + name + "'");
	    }
	    if (typeName !== void 0) {
	        var valid = true;
	        var value = object[name];
	        switch (typeName) {
	            case 'array':
	                valid = Array.isArray(value);
	                break;
	            case 'object':
	                valid = typeof value !== 'undefined';
	                break;
	            default:
	                valid = typeof value === typeName;
	        }
	        if (!valid) {
	            throw new Error("Property '" + name + "' is not of type '" + typeName);
	        }
	    }
	}
	/**
	 * Validate an `Contents.IModel` object.
	 */
	function validateContentsModel(model) {
	    validateProperty(model, 'name', 'string');
	    validateProperty(model, 'path', 'string');
	    validateProperty(model, 'type', 'string');
	    validateProperty(model, 'created', 'string');
	    validateProperty(model, 'last_modified', 'string');
	    validateProperty(model, 'mimetype', 'object');
	    validateProperty(model, 'content', 'object');
	    validateProperty(model, 'format', 'object');
	}
	exports.validateContentsModel = validateContentsModel;
	/**
	 * Validate an `Contents.ICheckpointModel` object.
	 */
	function validateCheckpointModel(model) {
	    validateProperty(model, 'id', 'string');
	    validateProperty(model, 'last_modified', 'string');
	}
	exports.validateCheckpointModel = validateCheckpointModel;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/contents/validate.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/index.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/index.js', function (module, exports, __jupyter_require__) {
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	'use strict';
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/kernel.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/manager.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/messages.js'));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/index.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/kernel.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/kernel.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var default_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/default.js');
	/**
	 * A namespace for kernel types, interfaces, and type checker functions.
	 */
	var Kernel;
	(function (Kernel) {
	    /**
	     * Find a kernel by id.
	     *
	     * #### Notes
	     * If the kernel was already started via `startNewKernel`, we return its
	     * `Kernel.IModel`.
	     *
	     * Otherwise, if `options` are given, we attempt to find to the existing
	     * kernel.
	     * The promise is fulfilled when the kernel is found,
	     * otherwise the promise is rejected.
	     */
	    function findById(id, options) {
	        return default_1.DefaultKernel.findById(id, options);
	    }
	    Kernel.findById = findById;
	    /**
	     * Fetch all of the kernel specs.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernelspecs).
	     */
	    function getSpecs(options) {
	        if (options === void 0) { options = {}; }
	        return default_1.DefaultKernel.getSpecs(options);
	    }
	    Kernel.getSpecs = getSpecs;
	    /**
	     * Fetch the running kernels.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels) and validates the response model.
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    function listRunning(options) {
	        if (options === void 0) { options = {}; }
	        return default_1.DefaultKernel.listRunning(options);
	    }
	    Kernel.listRunning = listRunning;
	    /**
	     * Start a new kernel.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels) and validates the response model.
	     *
	     * If no options are given or the kernel name is not given, the
	     * default kernel will by started by the server.
	     *
	     * Wraps the result in a Kernel object. The promise is fulfilled
	     * when the kernel is started by the server, otherwise the promise is rejected.
	     */
	    function startNew(options) {
	        options = options || {};
	        return default_1.DefaultKernel.startNew(options);
	    }
	    Kernel.startNew = startNew;
	    /**
	     * Connect to a running kernel.
	     *
	     * #### Notes
	     * If the kernel was already started via `startNewKernel`, the existing
	     * Kernel object info is used to create another instance.
	     *
	     * Otherwise, if `options` are given, we attempt to connect to the existing
	     * kernel found by calling `listRunningKernels`.
	     * The promise is fulfilled when the kernel is running on the server,
	     * otherwise the promise is rejected.
	     *
	     * If the kernel was not already started and no `options` are given,
	     * the promise is rejected.
	     */
	    function connectTo(id, options) {
	        return default_1.DefaultKernel.connectTo(id, options);
	    }
	    Kernel.connectTo = connectTo;
	    /**
	     * Shut down a kernel by id.
	     */
	    function shutdown(id, options) {
	        if (options === void 0) { options = {}; }
	        return default_1.DefaultKernel.shutdown(id, options);
	    }
	    Kernel.shutdown = shutdown;
	})(Kernel = exports.Kernel || (exports.Kernel = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/kernel.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/default.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/default.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var comm_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/comm.js');
	var messages_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/messages.js');
	var future_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/future.js');
	var serialize = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/serialize.js');
	var validate = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/validate.js');
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	/**
	 * The url for the kernel service.
	 */
	var KERNEL_SERVICE_URL = 'api/kernels';
	/**
	 * The url for the kernelspec service.
	 */
	var KERNELSPEC_SERVICE_URL = 'api/kernelspecs';
	/**
	 * Implementation of the Kernel object
	 */
	var DefaultKernel = (function () {
	    /**
	     * Construct a kernel object.
	     */
	    function DefaultKernel(options, id) {
	        this._id = '';
	        this._token = '';
	        this._name = '';
	        this._baseUrl = '';
	        this._wsUrl = '';
	        this._status = 'unknown';
	        this._clientId = '';
	        this._ws = null;
	        this._username = '';
	        this._ajaxSettings = '{}';
	        this._reconnectLimit = 7;
	        this._reconnectAttempt = 0;
	        this._isReady = false;
	        this._futures = null;
	        this._commPromises = null;
	        this._comms = null;
	        this._targetRegistry = Object.create(null);
	        this._info = null;
	        this._pendingMessages = [];
	        this._connectionPromise = null;
	        this._specPromise = null;
	        this._statusChanged = new signaling_1.Signal(this);
	        this._iopubMessage = new signaling_1.Signal(this);
	        this._unhandledMessage = new signaling_1.Signal(this);
	        this._name = options.name;
	        this._id = id;
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._wsUrl = options.wsUrl || utils.getWsUrl(this._baseUrl);
	        this._ajaxSettings = JSON.stringify(utils.ajaxSettingsWithToken(options.ajaxSettings, options.token));
	        this._token = options.token || utils.getConfigOption('token');
	        this._clientId = options.clientId || utils.uuid();
	        this._username = options.username || '';
	        this._futures = new Map();
	        this._commPromises = new Map();
	        this._comms = new Map();
	        this._createSocket();
	        this.terminated = new signaling_1.Signal(this);
	        Private.runningKernels.push(this);
	    }
	    Object.defineProperty(DefaultKernel.prototype, "statusChanged", {
	        /**
	         * A signal emitted when the kernel status changes.
	         */
	        get: function () {
	            return this._statusChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "iopubMessage", {
	        /**
	         * A signal emitted for iopub kernel messages.
	         */
	        get: function () {
	            return this._iopubMessage;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "unhandledMessage", {
	        /**
	         * A signal emitted for unhandled kernel message.
	         */
	        get: function () {
	            return this._unhandledMessage;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "id", {
	        /**
	         * The id of the server-side kernel.
	         */
	        get: function () {
	            return this._id;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "name", {
	        /**
	         * The name of the server-side kernel.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "model", {
	        /**
	         * Get the model associated with the kernel.
	         */
	        get: function () {
	            return { name: this.name, id: this.id };
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "username", {
	        /**
	         * The client username.
	         */
	        get: function () {
	            return this._username;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "clientId", {
	        /**
	         * The client unique id.
	         */
	        get: function () {
	            return this._clientId;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "status", {
	        /**
	         * The current status of the kernel.
	         */
	        get: function () {
	            return this._status;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "baseUrl", {
	        /**
	         * The base url of the kernel.
	         */
	        get: function () {
	            return this._baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "ajaxSettings", {
	        /**
	         * Get a copy of the default ajax settings for the kernel.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the kernel.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "isDisposed", {
	        /**
	         * Test whether the kernel has been disposed.
	         */
	        get: function () {
	            return this._futures === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "info", {
	        /**
	         * The cached kernel info.
	         *
	         * #### Notes
	         * This value will be null until the kernel is ready.
	         */
	        get: function () {
	            return this._info;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "isReady", {
	        /**
	         * Test whether the kernel is ready.
	         */
	        get: function () {
	            return this._isReady;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultKernel.prototype, "ready", {
	        /**
	         * A promise that is fulfilled when the kernel is ready.
	         */
	        get: function () {
	            return this._connectionPromise.promise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Get the kernel spec.
	     *
	     * @returns A promise that resolves with the kernel spec.
	     */
	    DefaultKernel.prototype.getSpec = function () {
	        var _this = this;
	        if (this._specPromise) {
	            return this._specPromise;
	        }
	        var options = {
	            baseUrl: this._baseUrl,
	            ajaxSettings: this.ajaxSettings
	        };
	        this._specPromise = Private.findSpecs(options).then(function (specs) {
	            return specs.kernelspecs[_this._name];
	        });
	        return this._specPromise;
	    };
	    /**
	     * Clone the current kernel with a new clientId.
	     */
	    DefaultKernel.prototype.clone = function () {
	        var options = {
	            baseUrl: this._baseUrl,
	            wsUrl: this._wsUrl,
	            name: this._name,
	            username: this._username,
	            token: this._token,
	            ajaxSettings: this.ajaxSettings
	        };
	        return new DefaultKernel(options, this._id);
	    };
	    /**
	     * Dispose of the resources held by the kernel.
	     */
	    DefaultKernel.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._status = 'dead';
	        if (this._ws !== null) {
	            this._ws.close();
	        }
	        this._ws = null;
	        this._futures.forEach(function (future, key) {
	            future.dispose();
	        });
	        this._comms.forEach(function (comm, key) {
	            comm.dispose();
	        });
	        this._futures = null;
	        this._commPromises = null;
	        this._comms = null;
	        this._targetRegistry = null;
	        algorithm_1.ArrayExt.removeFirstOf(Private.runningKernels, this);
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * Send a shell message to the kernel.
	     *
	     * #### Notes
	     * Send a message to the kernel's shell channel, yielding a future object
	     * for accepting replies.
	     *
	     * If `expectReply` is given and `true`, the future is disposed when both a
	     * shell reply and an idle status message are received. If `expectReply`
	     * is not given or is `false`, the future is resolved when an idle status
	     * message is received.
	     * If `disposeOnDone` is not given or is `true`, the Future is disposed at this point.
	     * If `disposeOnDone` is given and `false`, it is up to the caller to dispose of the Future.
	     *
	     * All replies are validated as valid kernel messages.
	     *
	     * If the kernel status is `dead`, this will throw an error.
	     */
	    DefaultKernel.prototype.sendShellMessage = function (msg, expectReply, disposeOnDone) {
	        var _this = this;
	        if (expectReply === void 0) { expectReply = false; }
	        if (disposeOnDone === void 0) { disposeOnDone = true; }
	        if (this.status === 'dead') {
	            throw new Error('Kernel is dead');
	        }
	        if (!this._isReady) {
	            this._pendingMessages.push(msg);
	        }
	        else {
	            this._ws.send(serialize.serialize(msg));
	        }
	        var future = new future_1.KernelFutureHandler(function () {
	            _this._futures.delete(msg.header.msg_id);
	        }, msg, expectReply, disposeOnDone);
	        this._futures.set(msg.header.msg_id, future);
	        return future;
	    };
	    /**
	     * Interrupt a kernel.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels).
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     *
	     * It is assumed that the API call does not mutate the kernel id or name.
	     *
	     * The promise will be rejected if the kernel status is `Dead` or if the
	     * request fails or the response is invalid.
	     */
	    DefaultKernel.prototype.interrupt = function () {
	        return Private.interruptKernel(this, this._baseUrl, this.ajaxSettings);
	    };
	    /**
	     * Restart a kernel.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels) and validates the response model.
	     *
	     * Any existing Future or Comm objects are cleared.
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     *
	     * It is assumed that the API call does not mutate the kernel id or name.
	     *
	     * The promise will be rejected if the request fails or the response is
	     * invalid.
	     */
	    DefaultKernel.prototype.restart = function () {
	        this._clearState();
	        this._updateStatus('restarting');
	        return Private.restartKernel(this, this._baseUrl, this.ajaxSettings);
	    };
	    /**
	     * Reconnect to a disconnected kernel.
	     *
	     * #### Notes
	     * Used when the websocket connection to the kernel is lost.
	     */
	    DefaultKernel.prototype.reconnect = function () {
	        this._isReady = false;
	        if (this._ws !== null) {
	            // Clear the websocket event handlers and the socket itself.
	            this._ws.onopen = null;
	            this._ws.onclose = null;
	            this._ws.onerror = null;
	            this._ws.onmessage = null;
	            this._ws.close();
	            this._ws = null;
	        }
	        this._updateStatus('reconnecting');
	        this._createSocket();
	        return this._connectionPromise.promise;
	    };
	    /**
	     * Shutdown a kernel.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels).
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     *
	     * On a valid response, closes the websocket and disposes of the kernel
	     * object, and fulfills the promise.
	     *
	     * The promise will be rejected if the kernel status is `Dead` or if the
	     * request fails or the response is invalid.
	     */
	    DefaultKernel.prototype.shutdown = function () {
	        var _this = this;
	        if (this.status === 'dead') {
	            return Promise.reject(new Error('Kernel is dead'));
	        }
	        this._clearState();
	        return this.ready.then(function () {
	            return Private.shutdownKernel(_this.id, _this._baseUrl, _this.ajaxSettings);
	        });
	    };
	    /**
	     * Send a `kernel_info_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info).
	     *
	     * Fulfills with the `kernel_info_response` content when the shell reply is
	     * received and validated.
	     */
	    DefaultKernel.prototype.requestKernelInfo = function () {
	        var _this = this;
	        var options = {
	            msgType: 'kernel_info_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options);
	        return Private.handleShellMessage(this, msg).then(function (reply) {
	            _this._info = reply.content;
	            return reply;
	        });
	    };
	    /**
	     * Send a `complete_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#completion).
	     *
	     * Fulfills with the `complete_reply` content when the shell reply is
	     * received and validated.
	     */
	    DefaultKernel.prototype.requestComplete = function (content) {
	        var options = {
	            msgType: 'complete_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content);
	        return Private.handleShellMessage(this, msg);
	    };
	    /**
	     * Send an `inspect_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#introspection).
	     *
	     * Fulfills with the `inspect_reply` content when the shell reply is
	     * received and validated.
	     */
	    DefaultKernel.prototype.requestInspect = function (content) {
	        var options = {
	            msgType: 'inspect_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content);
	        return Private.handleShellMessage(this, msg);
	    };
	    /**
	     * Send a `history_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history).
	     *
	     * Fulfills with the `history_reply` content when the shell reply is
	     * received and validated.
	     */
	    DefaultKernel.prototype.requestHistory = function (content) {
	        var options = {
	            msgType: 'history_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content);
	        return Private.handleShellMessage(this, msg);
	    };
	    /**
	     * Send an `execute_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execute).
	     *
	     * Future `onReply` is called with the `execute_reply` content when the
	     * shell reply is received and validated. The future will resolve when
	     * this message is received and the `idle` iopub status is received.
	     * The future will also be disposed at this point unless `disposeOnDone`
	     * is specified and `false`, in which case it is up to the caller to dispose
	     * of the future.
	     *
	     * **See also:** [[IExecuteReply]]
	     */
	    DefaultKernel.prototype.requestExecute = function (content, disposeOnDone) {
	        if (disposeOnDone === void 0) { disposeOnDone = true; }
	        var options = {
	            msgType: 'execute_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var defaults = {
	            silent: false,
	            store_history: true,
	            user_expressions: {},
	            allow_stdin: true,
	            stop_on_error: false
	        };
	        content = utils.extend(defaults, content);
	        var msg = messages_1.KernelMessage.createShellMessage(options, content);
	        return this.sendShellMessage(msg, true, disposeOnDone);
	    };
	    /**
	     * Send an `is_complete_request` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#code-completeness).
	     *
	     * Fulfills with the `is_complete_response` content when the shell reply is
	     * received and validated.
	     */
	    DefaultKernel.prototype.requestIsComplete = function (content) {
	        var options = {
	            msgType: 'is_complete_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content);
	        return Private.handleShellMessage(this, msg);
	    };
	    /**
	     * Send a `comm_info_request` message.
	     *
	     * #### Notes
	     * Fulfills with the `comm_info_reply` content when the shell reply is
	     * received and validated.
	     */
	    DefaultKernel.prototype.requestCommInfo = function (content) {
	        var options = {
	            msgType: 'comm_info_request',
	            channel: 'shell',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content);
	        return Private.handleShellMessage(this, msg);
	    };
	    /**
	     * Send an `input_reply` message.
	     *
	     * #### Notes
	     * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).
	     */
	    DefaultKernel.prototype.sendInputReply = function (content) {
	        if (this.status === 'dead') {
	            throw new Error('Kernel is dead');
	        }
	        var options = {
	            msgType: 'input_reply',
	            channel: 'stdin',
	            username: this._username,
	            session: this._clientId
	        };
	        var msg = messages_1.KernelMessage.createMessage(options, content);
	        if (!this._isReady) {
	            this._pendingMessages.push(msg);
	        }
	        else {
	            this._ws.send(serialize.serialize(msg));
	        }
	    };
	    /**
	     * Register an IOPub message hook.
	     *
	     * @param msg_id - The parent_header message id the hook will intercept.
	     *
	     * @param hook - The callback invoked for the message.
	     *
	     * @returns A disposable used to unregister the message hook.
	     *
	     * #### Notes
	     * The IOPub hook system allows you to preempt the handlers for IOPub messages with a
	     * given parent_header message id. The most recently registered hook is run first.
	     * If the hook returns false, any later hooks and the future's onIOPub handler will not run.
	     * If a hook throws an error, the error is logged to the console and the next hook is run.
	     * If a hook is registered during the hook processing, it won't run until the next message.
	     * If a hook is disposed during the hook processing, it will be deactivated immediately.
	     *
	     * See also [[IFuture.registerMessageHook]].
	     */
	    DefaultKernel.prototype.registerMessageHook = function (msgId, hook) {
	        var _this = this;
	        var future = this._futures && this._futures.get(msgId);
	        if (future) {
	            future.registerMessageHook(hook);
	        }
	        return new disposable_1.DisposableDelegate(function () {
	            future = _this._futures && _this._futures.get(msgId);
	            if (future) {
	                future.removeMessageHook(hook);
	            }
	        });
	    };
	    /**
	     * Register a comm target handler.
	     *
	     * @param targetName - The name of the comm target.
	     *
	     * @param callback - The callback invoked for a comm open message.
	     *
	     * @returns A disposable used to unregister the comm target.
	     *
	     * #### Notes
	     * Only one comm target can be registered at a time, an existing
	     * callback will be overidden.  A registered comm target handler will take
	     * precedence over a comm which specifies a `target_module`.
	     */
	    DefaultKernel.prototype.registerCommTarget = function (targetName, callback) {
	        var _this = this;
	        this._targetRegistry[targetName] = callback;
	        return new disposable_1.DisposableDelegate(function () {
	            if (!_this.isDisposed) {
	                delete _this._targetRegistry[targetName];
	            }
	        });
	    };
	    /**
	     * Connect to a comm, or create a new one.
	     *
	     * #### Notes
	     * If a client-side comm already exists, it is returned.
	     */
	    DefaultKernel.prototype.connectToComm = function (targetName, commId) {
	        var _this = this;
	        if (commId === void 0) {
	            commId = utils.uuid();
	        }
	        var comm = this._comms.get(commId);
	        if (!comm) {
	            comm = new comm_1.CommHandler(targetName, commId, this, function () { _this._unregisterComm(commId); });
	            this._comms.set(commId, comm);
	        }
	        return comm;
	    };
	    /**
	     * Create the kernel websocket connection and add socket status handlers.
	     */
	    DefaultKernel.prototype._createSocket = function () {
	        var _this = this;
	        var partialUrl = utils.urlPathJoin(this._wsUrl, KERNEL_SERVICE_URL, encodeURIComponent(this._id));
	        // Strip any authentication from the display string.
	        var parsed = utils.urlParse(partialUrl);
	        console.log('Starting websocket', parsed.hostname);
	        var url = utils.urlPathJoin(partialUrl, 'channels?session_id=' + encodeURIComponent(this._clientId));
	        // if token authentication is in use
	        if (this._token !== '') {
	            url = url + ("&token=" + encodeURIComponent(this._token));
	        }
	        this._connectionPromise = new coreutils_1.PromiseDelegate();
	        this._ws = new WebSocket(url);
	        // Ensure incoming binary messages are not Blobs
	        this._ws.binaryType = 'arraybuffer';
	        this._ws.onmessage = function (evt) { _this._onWSMessage(evt); };
	        this._ws.onopen = function (evt) { _this._onWSOpen(evt); };
	        this._ws.onclose = function (evt) { _this._onWSClose(evt); };
	        this._ws.onerror = function (evt) { _this._onWSClose(evt); };
	    };
	    /**
	     * Handle a websocket open event.
	     */
	    DefaultKernel.prototype._onWSOpen = function (evt) {
	        var _this = this;
	        this._reconnectAttempt = 0;
	        // Allow the message to get through.
	        this._isReady = true;
	        // Get the kernel info, signaling that the kernel is ready.
	        this.requestKernelInfo().then(function () {
	            _this._connectionPromise.resolve(void 0);
	        }).catch(function (err) {
	            _this._connectionPromise.reject(err);
	        });
	        this._isReady = false;
	    };
	    /**
	     * Handle a websocket message, validating and routing appropriately.
	     */
	    DefaultKernel.prototype._onWSMessage = function (evt) {
	        if (this.status === 'dead') {
	            // If the socket is being closed, ignore any messages
	            return;
	        }
	        var msg = serialize.deserialize(evt.data);
	        try {
	            validate.validateMessage(msg);
	        }
	        catch (error) {
	            console.error("Invalid message: " + error.message);
	            return;
	        }
	        if (msg.parent_header) {
	            var parentHeader = msg.parent_header;
	            var future = this._futures && this._futures.get(parentHeader.msg_id);
	            if (future) {
	                future.handleMsg(msg);
	            }
	            else {
	                // If the message was sent by us and was not iopub, it is orphaned.
	                var owned = parentHeader.session === this.clientId;
	                if (msg.channel !== 'iopub' && owned) {
	                    this._unhandledMessage.emit(msg);
	                }
	            }
	        }
	        if (msg.channel === 'iopub') {
	            switch (msg.header.msg_type) {
	                case 'status':
	                    this._updateStatus(msg.content.execution_state);
	                    break;
	                case 'comm_open':
	                    this._handleCommOpen(msg);
	                    break;
	                case 'comm_msg':
	                    this._handleCommMsg(msg);
	                    break;
	                case 'comm_close':
	                    this._handleCommClose(msg);
	                    break;
	                default:
	                    break;
	            }
	            this._iopubMessage.emit(msg);
	        }
	    };
	    /**
	     * Handle a websocket close event.
	     */
	    DefaultKernel.prototype._onWSClose = function (evt) {
	        if (this.status === 'dead') {
	            return;
	        }
	        // Clear the websocket event handlers and the socket itself.
	        this._ws.onclose = null;
	        this._ws.onerror = null;
	        this._ws = null;
	        if (this._reconnectAttempt < this._reconnectLimit) {
	            this._updateStatus('reconnecting');
	            var timeout = Math.pow(2, this._reconnectAttempt);
	            console.error('Connection lost, reconnecting in ' + timeout + ' seconds.');
	            setTimeout(this._createSocket.bind(this), 1e3 * timeout);
	            this._reconnectAttempt += 1;
	        }
	        else {
	            this._updateStatus('dead');
	            this._connectionPromise.reject(new Error('Could not establish connection'));
	        }
	    };
	    /**
	     * Handle status iopub messages from the kernel.
	     */
	    DefaultKernel.prototype._updateStatus = function (status) {
	        switch (status) {
	            case 'starting':
	            case 'idle':
	            case 'busy':
	                this._isReady = true;
	                break;
	            case 'restarting':
	            case 'reconnecting':
	            case 'dead':
	                this._isReady = false;
	                break;
	            default:
	                console.error('invalid kernel status:', status);
	                return;
	        }
	        if (status !== this._status) {
	            this._status = status;
	            Private.logKernelStatus(this);
	            this._statusChanged.emit(status);
	            if (status === 'dead') {
	                this.dispose();
	            }
	        }
	        if (this._isReady) {
	            this._sendPending();
	        }
	    };
	    /**
	     * Send pending messages to the kernel.
	     */
	    DefaultKernel.prototype._sendPending = function () {
	        // We shift the message off the queue
	        // after the message is sent so that if there is an exception,
	        // the message is still pending.
	        while (this._pendingMessages.length > 0) {
	            var msg = serialize.serialize(this._pendingMessages[0]);
	            this._ws.send(msg);
	            this._pendingMessages.shift();
	        }
	    };
	    /**
	     * Clear the internal state.
	     */
	    DefaultKernel.prototype._clearState = function () {
	        this._isReady = false;
	        this._pendingMessages = [];
	        this._futures.forEach(function (future, key) {
	            future.dispose();
	        });
	        this._comms.forEach(function (comm, key) {
	            comm.dispose();
	        });
	        this._futures = new Map();
	        this._commPromises = new Map();
	        this._comms = new Map();
	    };
	    /**
	     * Handle a `comm_open` kernel message.
	     */
	    DefaultKernel.prototype._handleCommOpen = function (msg) {
	        var _this = this;
	        var content = msg.content;
	        var promise = utils.loadObject(content.target_name, content.target_module, this._targetRegistry).then(function (target) {
	            var comm = new comm_1.CommHandler(content.target_name, content.comm_id, _this, function () { _this._unregisterComm(content.comm_id); });
	            var response;
	            try {
	                response = target(comm, msg);
	            }
	            catch (e) {
	                comm.close();
	                console.error('Exception opening new comm');
	                throw (e);
	            }
	            return Promise.resolve(response).then(function () {
	                _this._commPromises.delete(comm.commId);
	                _this._comms.set(comm.commId, comm);
	                return comm;
	            });
	        });
	        this._commPromises.set(content.comm_id, promise);
	    };
	    /**
	     * Handle 'comm_close' kernel message.
	     */
	    DefaultKernel.prototype._handleCommClose = function (msg) {
	        var _this = this;
	        var content = msg.content;
	        var promise = this._commPromises.get(content.comm_id);
	        if (!promise) {
	            var comm = this._comms.get(content.comm_id);
	            if (!comm) {
	                console.error('Comm not found for comm id ' + content.comm_id);
	                return;
	            }
	            promise = Promise.resolve(comm);
	        }
	        promise.then(function (comm) {
	            _this._unregisterComm(comm.commId);
	            try {
	                var onClose = comm.onClose;
	                if (onClose) {
	                    onClose(msg);
	                }
	                comm.dispose();
	            }
	            catch (e) {
	                console.error('Exception closing comm: ', e, e.stack, msg);
	            }
	        });
	    };
	    /**
	     * Handle a 'comm_msg' kernel message.
	     */
	    DefaultKernel.prototype._handleCommMsg = function (msg) {
	        var content = msg.content;
	        var promise = this._commPromises.get(content.comm_id);
	        if (!promise) {
	            var comm = this._comms.get(content.comm_id);
	            if (!comm) {
	                // We do have a registered comm for this comm id, ignore.
	                return;
	            }
	            else {
	                var onMsg = comm.onMsg;
	                if (onMsg) {
	                    onMsg(msg);
	                }
	            }
	        }
	        else {
	            promise.then(function (comm) {
	                try {
	                    var onMsg = comm.onMsg;
	                    if (onMsg) {
	                        onMsg(msg);
	                    }
	                }
	                catch (e) {
	                    console.error('Exception handling comm msg: ', e, e.stack, msg);
	                }
	                return comm;
	            });
	        }
	    };
	    /**
	     * Unregister a comm instance.
	     */
	    DefaultKernel.prototype._unregisterComm = function (commId) {
	        this._comms.delete(commId);
	        this._commPromises.delete(commId);
	    };
	    return DefaultKernel;
	}());
	exports.DefaultKernel = DefaultKernel;
	/**
	 * The namespace for `DefaultKernel` statics.
	 */
	(function (DefaultKernel) {
	    /**
	     * Find a kernel by id.
	     *
	     * #### Notes
	     * If the kernel was already started via `startNewKernel`, we return its
	     * `Kernel.IModel`.
	     *
	     * Otherwise, if `options` are given, we attempt to find the existing
	     * kernel.
	     * The promise is fulfilled when the kernel is found,
	     * otherwise the promise is rejected.
	     */
	    function findById(id, options) {
	        return Private.findById(id, options);
	    }
	    DefaultKernel.findById = findById;
	    /**
	     * Fetch all of the kernel specs.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernelspecs).
	     */
	    function getSpecs(options) {
	        if (options === void 0) { options = {}; }
	        return Private.getSpecs(options);
	    }
	    DefaultKernel.getSpecs = getSpecs;
	    /**
	     * Fetch the running kernels.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels) and validates the response model.
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    function listRunning(options) {
	        if (options === void 0) { options = {}; }
	        return Private.listRunning(options);
	    }
	    DefaultKernel.listRunning = listRunning;
	    /**
	     * Start a new kernel.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels) and validates the response model.
	     *
	     * If no options are given or the kernel name is not given, the
	     * default kernel will by started by the server.
	     *
	     * Wraps the result in a Kernel object. The promise is fulfilled
	     * when the kernel is started by the server, otherwise the promise is rejected.
	     */
	    function startNew(options) {
	        options = options || {};
	        return Private.startNew(options);
	    }
	    DefaultKernel.startNew = startNew;
	    /**
	     * Connect to a running kernel.
	     *
	     * #### Notes
	     * If the kernel was already started via `startNewKernel`, the existing
	     * Kernel object info is used to create another instance.
	     *
	     * Otherwise, if `options` are given, we attempt to connect to the existing
	     * kernel found by calling `listRunningKernels`.
	     * The promise is fulfilled when the kernel is running on the server,
	     * otherwise the promise is rejected.
	     *
	     * If the kernel was not already started and no `options` are given,
	     * the promise is rejected.
	     */
	    function connectTo(id, options) {
	        return Private.connectTo(id, options);
	    }
	    DefaultKernel.connectTo = connectTo;
	    /**
	     * Shut down a kernel by id.
	     */
	    function shutdown(id, options) {
	        if (options === void 0) { options = {}; }
	        return Private.shutdown(id, options);
	    }
	    DefaultKernel.shutdown = shutdown;
	})(DefaultKernel = exports.DefaultKernel || (exports.DefaultKernel = {}));
	exports.DefaultKernel = DefaultKernel;
	/**
	 * A private namespace for the Kernel.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A module private store for running kernels.
	     */
	    Private.runningKernels = [];
	    /**
	     * A module private store of kernel specs by base url.
	     */
	    Private.specs = Object.create(null);
	    /**
	     * Find a kernel by id.
	     */
	    function findById(id, options) {
	        var kernel = algorithm_1.find(Private.runningKernels, function (value) {
	            return (value.id === id);
	        });
	        if (kernel) {
	            return Promise.resolve(kernel.model);
	        }
	        return getKernelModel(id, options).catch(function () {
	            throw new Error("No running kernel with id: " + id);
	        });
	    }
	    Private.findById = findById;
	    /**
	     * Get the cached kernel specs or fetch them.
	     */
	    function findSpecs(options) {
	        var promise = Private.specs[options.baseUrl];
	        if (promise) {
	            return promise;
	        }
	        return getSpecs(options);
	    }
	    Private.findSpecs = findSpecs;
	    /**
	     * Fetch all of the kernel specs.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernelspecs).
	     */
	    function getSpecs(options) {
	        if (options === void 0) { options = {}; }
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, KERNELSPEC_SERVICE_URL);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        var promise = utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            try {
	                return validate.validateSpecModels(success.data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	        });
	        Private.specs[baseUrl] = promise;
	        return promise;
	    }
	    Private.getSpecs = getSpecs;
	    /**
	     * Fetch the running kernels.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernels) and validates the response model.
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    function listRunning(options) {
	        if (options === void 0) { options = {}; }
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            if (!Array.isArray(success.data)) {
	                throw utils.makeAjaxError(success, 'Invalid kernel list');
	            }
	            for (var i = 0; i < success.data.length; i++) {
	                try {
	                    validate.validateModel(success.data[i]);
	                }
	                catch (err) {
	                    throw utils.makeAjaxError(success, err.message);
	                }
	            }
	            return updateRunningKernels(success.data);
	        }, onKernelError);
	    }
	    Private.listRunning = listRunning;
	    /**
	     * Update the running kernels based on new data from the server.
	     */
	    function updateRunningKernels(kernels) {
	        algorithm_1.each(Private.runningKernels, function (kernel) {
	            var updated = algorithm_1.find(kernels, function (model) {
	                if (kernel.id === model.id) {
	                    return true;
	                }
	            });
	            // If kernel is no longer running on disk, emit dead signal.
	            if (!updated && kernel.status !== 'dead') {
	                kernel.terminated.emit(void 0);
	                kernel.dispose();
	            }
	        });
	        return kernels;
	    }
	    Private.updateRunningKernels = updateRunningKernels;
	    /**
	     * Start a new kernel.
	     */
	    function startNew(options) {
	        options = options || {};
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'POST';
	        ajaxSettings.data = JSON.stringify({ name: options.name });
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 201) {
	                throw utils.makeAjaxError(success);
	            }
	            validate.validateModel(success.data);
	            options = utils.copy(options);
	            options.name = success.data.name;
	            return new DefaultKernel(options, success.data.id);
	        }, onKernelError);
	    }
	    Private.startNew = startNew;
	    /**
	     * Connect to a running kernel.
	     *
	     * #### Notes
	     * If the kernel was already started via `startNewKernel`, the existing
	     * Kernel object info is used to create another instance.
	     *
	     * Otherwise, if `options` are given, we attempt to connect to the existing
	     * kernel found by calling `listRunningKernels`.
	     * The promise is fulfilled when the kernel is running on the server,
	     * otherwise the promise is rejected.
	     *
	     * If the kernel was not already started and no `options` are given,
	     * the promise is rejected.
	     */
	    function connectTo(id, options) {
	        var kernel = algorithm_1.find(Private.runningKernels, function (value) {
	            return value.id === id;
	        });
	        if (kernel) {
	            return Promise.resolve(kernel.clone());
	        }
	        return getKernelModel(id, options).then(function (model) {
	            options = utils.copy(options);
	            options.name = model.name;
	            return new DefaultKernel(options, id);
	        }).catch(function () {
	            throw new Error("No running kernel with id: " + id);
	        });
	    }
	    Private.connectTo = connectTo;
	    /**
	     * Shut down a kernel by id.
	     */
	    function shutdown(id, options) {
	        if (options === void 0) { options = {}; }
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        return shutdownKernel(id, baseUrl, ajaxSettings);
	    }
	    Private.shutdown = shutdown;
	    /**
	     * Restart a kernel.
	     */
	    function restartKernel(kernel, baseUrl, ajaxSettings) {
	        if (kernel.status === 'dead') {
	            return Promise.reject(new Error('Kernel is dead'));
	        }
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, encodeURIComponent(kernel.id), 'restart');
	        ajaxSettings = ajaxSettings || {};
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            try {
	                validate.validateModel(success.data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	        }, onKernelError);
	    }
	    Private.restartKernel = restartKernel;
	    /**
	     * Interrupt a kernel.
	     */
	    function interruptKernel(kernel, baseUrl, ajaxSettings) {
	        if (kernel.status === 'dead') {
	            return Promise.reject(new Error('Kernel is dead'));
	        }
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, encodeURIComponent(kernel.id), 'interrupt');
	        ajaxSettings = ajaxSettings || {};
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw utils.makeAjaxError(success);
	            }
	        }, onKernelError);
	    }
	    Private.interruptKernel = interruptKernel;
	    /**
	     * Delete a kernel.
	     */
	    function shutdownKernel(id, baseUrl, ajaxSettings) {
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, encodeURIComponent(id));
	        ajaxSettings = ajaxSettings || {};
	        ajaxSettings.method = 'DELETE';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw utils.makeAjaxError(success);
	            }
	            killKernels(id);
	        }, function (error) {
	            if (error.xhr.status === 404) {
	                var response = JSON.parse(error.xhr.responseText);
	                console.warn(response['message']);
	                killKernels(id);
	            }
	            else {
	                return onKernelError(error);
	            }
	        });
	    }
	    Private.shutdownKernel = shutdownKernel;
	    /**
	     * Kill the kernels by id.
	     */
	    function killKernels(id) {
	        algorithm_1.each(algorithm_1.toArray(Private.runningKernels), function (kernel) {
	            if (kernel.id === id) {
	                kernel.terminated.emit(void 0);
	                kernel.dispose();
	            }
	        });
	    }
	    /**
	     * Get a full kernel model from the server by kernel id string.
	     */
	    function getKernelModel(id, options) {
	        options = options || {};
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, KERNEL_SERVICE_URL, encodeURIComponent(id));
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            try {
	                validate.validateModel(data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            return data;
	        }, Private.onKernelError);
	    }
	    Private.getKernelModel = getKernelModel;
	    /**
	     * Log the current kernel status.
	     */
	    function logKernelStatus(kernel) {
	        switch (kernel.status) {
	            case 'idle':
	            case 'busy':
	            case 'unknown':
	                return;
	            default:
	                console.log("Kernel: " + kernel.status + " (" + kernel.id + ")");
	                break;
	        }
	    }
	    Private.logKernelStatus = logKernelStatus;
	    /**
	     * Handle an error on a kernel Ajax call.
	     */
	    function onKernelError(error) {
	        var text = (error.throwError ||
	            error.xhr.statusText ||
	            error.xhr.responseText);
	        var msg = "API request failed: " + text;
	        console.error(msg);
	        return Promise.reject(error);
	    }
	    Private.onKernelError = onKernelError;
	    /**
	     * Send a kernel message to the kernel and resolve the reply message.
	     */
	    function handleShellMessage(kernel, msg) {
	        var future;
	        try {
	            future = kernel.sendShellMessage(msg, true);
	        }
	        catch (e) {
	            return Promise.reject(e);
	        }
	        return new Promise(function (resolve, reject) {
	            future.onReply = function (reply) {
	                resolve(reply);
	            };
	        });
	    }
	    Private.handleShellMessage = handleShellMessage;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/default.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/comm.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/comm.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var messages_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/messages.js');
	/**
	 * Comm channel handler.
	 */
	var CommHandler = (function (_super) {
	    __extends(CommHandler, _super);
	    /**
	     * Construct a new comm channel.
	     */
	    function CommHandler(target, id, kernel, disposeCb) {
	        var _this = _super.call(this, disposeCb) || this;
	        _this._target = '';
	        _this._id = '';
	        _this._kernel = null;
	        _this._onClose = null;
	        _this._onMsg = null;
	        _this._id = id;
	        _this._target = target;
	        _this._kernel = kernel;
	        return _this;
	    }
	    Object.defineProperty(CommHandler.prototype, "commId", {
	        /**
	         * The unique id for the comm channel.
	         */
	        get: function () {
	            return this._id;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommHandler.prototype, "targetName", {
	        /**
	         * The target name for the comm channel.
	         */
	        get: function () {
	            return this._target;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommHandler.prototype, "onClose", {
	        /**
	         * Get the callback for a comm close event.
	         *
	         * #### Notes
	         * This is called when the comm is closed from either the server or
	         * client.
	         *
	         * **See also:** [[ICommClose]], [[close]]
	         */
	        get: function () {
	            return this._onClose;
	        },
	        /**
	         * Set the callback for a comm close event.
	         *
	         * #### Notes
	         * This is called when the comm is closed from either the server or
	         * client.
	         *
	         * **See also:** [[close]]
	         */
	        set: function (cb) {
	            this._onClose = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommHandler.prototype, "onMsg", {
	        /**
	         * Get the callback for a comm message received event.
	         */
	        get: function () {
	            return this._onMsg;
	        },
	        /**
	         * Set the callback for a comm message received event.
	         */
	        set: function (cb) {
	            this._onMsg = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(CommHandler.prototype, "isDisposed", {
	        /**
	         * Test whether the comm has been disposed.
	         */
	        get: function () {
	            return (this._kernel === null);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Open a comm with optional data and metadata.
	     *
	     * #### Notes
	     * This sends a `comm_open` message to the server.
	     *
	     * **See also:** [[ICommOpen]]
	     */
	    CommHandler.prototype.open = function (data, metadata) {
	        if (this.isDisposed || this._kernel.isDisposed) {
	            return;
	        }
	        var options = {
	            msgType: 'comm_open',
	            channel: 'shell',
	            username: this._kernel.username,
	            session: this._kernel.clientId
	        };
	        var content = {
	            comm_id: this._id,
	            target_name: this._target,
	            data: data || {}
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content, metadata);
	        return this._kernel.sendShellMessage(msg, false, true);
	    };
	    /**
	     * Send a `comm_msg` message to the kernel.
	     *
	     * #### Notes
	     * This is a no-op if the comm has been closed.
	     *
	     * **See also:** [[ICommMsg]]
	     */
	    CommHandler.prototype.send = function (data, metadata, buffers, disposeOnDone) {
	        if (buffers === void 0) { buffers = []; }
	        if (disposeOnDone === void 0) { disposeOnDone = true; }
	        if (this.isDisposed || this._kernel.isDisposed) {
	            return;
	        }
	        var options = {
	            msgType: 'comm_msg',
	            channel: 'shell',
	            username: this._kernel.username,
	            session: this._kernel.clientId
	        };
	        var content = {
	            comm_id: this._id,
	            data: data
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content, metadata, buffers);
	        return this._kernel.sendShellMessage(msg, false, true);
	    };
	    /**
	     * Close the comm.
	     *
	     * #### Notes
	     * This will send a `comm_close` message to the kernel, and call the
	     * `onClose` callback if set.
	     *
	     * This is a no-op if the comm is already closed.
	     *
	     * **See also:** [[ICommClose]], [[onClose]]
	     */
	    CommHandler.prototype.close = function (data, metadata) {
	        if (this.isDisposed || this._kernel.isDisposed) {
	            return;
	        }
	        var options = {
	            msgType: 'comm_msg',
	            channel: 'shell',
	            username: this._kernel.username,
	            session: this._kernel.clientId
	        };
	        var content = {
	            comm_id: this._id,
	            data: data || {}
	        };
	        var msg = messages_1.KernelMessage.createShellMessage(options, content, metadata);
	        var future = this._kernel.sendShellMessage(msg, false, true);
	        options.channel = 'iopub';
	        var ioMsg = messages_1.KernelMessage.createMessage(options, content, metadata);
	        var onClose = this._onClose;
	        if (onClose) {
	            onClose(ioMsg);
	        }
	        this.dispose();
	        return future;
	    };
	    /**
	     * Dispose of the resources held by the comm.
	     */
	    CommHandler.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._onClose = null;
	        this._onMsg = null;
	        this._kernel = null;
	        _super.prototype.dispose.call(this);
	    };
	    return CommHandler;
	}(disposable_1.DisposableDelegate));
	exports.CommHandler = CommHandler;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/comm.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/messages.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/messages.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	/**
	 * A namespace for kernel messages.
	 */
	var KernelMessage;
	(function (KernelMessage) {
	    /**
	     * Create a well-formed kernel message.
	     */
	    function createMessage(options, content, metadata, buffers) {
	        if (content === void 0) { content = {}; }
	        if (metadata === void 0) { metadata = {}; }
	        if (buffers === void 0) { buffers = []; }
	        return {
	            header: {
	                username: options.username || '',
	                version: '5.0',
	                session: options.session,
	                msg_id: options.msgId || utils.uuid(),
	                msg_type: options.msgType
	            },
	            parent_header: {},
	            channel: options.channel,
	            content: content,
	            metadata: metadata,
	            buffers: buffers
	        };
	    }
	    KernelMessage.createMessage = createMessage;
	    /**
	     * Create a well-formed kernel shell message.
	     */
	    function createShellMessage(options, content, metadata, buffers) {
	        if (content === void 0) { content = {}; }
	        if (metadata === void 0) { metadata = {}; }
	        if (buffers === void 0) { buffers = []; }
	        var msg = createMessage(options, content, metadata, buffers);
	        return msg;
	    }
	    KernelMessage.createShellMessage = createShellMessage;
	    /**
	     * Test whether a kernel message is a `'stream'` message.
	     */
	    function isStreamMsg(msg) {
	        return msg.header.msg_type === 'stream';
	    }
	    KernelMessage.isStreamMsg = isStreamMsg;
	    /**
	     * Test whether a kernel message is an `'display_data'` message.
	     */
	    function isDisplayDataMsg(msg) {
	        return msg.header.msg_type === 'display_data';
	    }
	    KernelMessage.isDisplayDataMsg = isDisplayDataMsg;
	    /**
	     * Test whether a kernel message is an `'execute_input'` message.
	     */
	    function isExecuteInputMsg(msg) {
	        return msg.header.msg_type === 'execute_input';
	    }
	    KernelMessage.isExecuteInputMsg = isExecuteInputMsg;
	    /**
	     * Test whether a kernel message is an `'execute_result'` message.
	     */
	    function isExecuteResultMsg(msg) {
	        return msg.header.msg_type === 'execute_result';
	    }
	    KernelMessage.isExecuteResultMsg = isExecuteResultMsg;
	    /**
	     * Test whether a kernel message is an `'error'` message.
	     */
	    function isErrorMsg(msg) {
	        return msg.header.msg_type === 'error';
	    }
	    KernelMessage.isErrorMsg = isErrorMsg;
	    /**
	     * Test whether a kernel message is a `'status'` message.
	     */
	    function isStatusMsg(msg) {
	        return msg.header.msg_type === 'status';
	    }
	    KernelMessage.isStatusMsg = isStatusMsg;
	    /**
	     * Test whether a kernel message is a `'clear_output'` message.
	     */
	    function isClearOutputMsg(msg) {
	        return msg.header.msg_type === 'clear_output';
	    }
	    KernelMessage.isClearOutputMsg = isClearOutputMsg;
	    /**
	     * Test whether a kernel message is a `'comm_open'` message.
	     */
	    function isCommOpenMsg(msg) {
	        return msg.header.msg_type === 'comm_open';
	    }
	    KernelMessage.isCommOpenMsg = isCommOpenMsg;
	    /**
	     * Test whether a kernel message is a `'comm_close'` message.
	     */
	    function isCommCloseMsg(msg) {
	        return msg.header.msg_type === 'comm_close';
	    }
	    KernelMessage.isCommCloseMsg = isCommCloseMsg;
	    /**
	     * Test whether a kernel message is a `'comm_msg'` message.
	     */
	    function isCommMsgMsg(msg) {
	        return msg.header.msg_type === 'comm_msg';
	    }
	    KernelMessage.isCommMsgMsg = isCommMsgMsg;
	    ;
	    /**
	     * Test whether a kernel message is an `'input_request'` message.
	     */
	    function isInputRequestMsg(msg) {
	        return msg.header.msg_type === 'input_request';
	    }
	    KernelMessage.isInputRequestMsg = isInputRequestMsg;
	})(KernelMessage = exports.KernelMessage || (exports.KernelMessage = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/messages.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/future.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/future.js', function (module, exports, __jupyter_require__) {
	/* WEBPACK VAR INJECTION */(function(setImmediate) {"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	var __extends = (this && this.__extends) || (function () {
	    var extendStatics = Object.setPrototypeOf ||
	        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
	        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
	    return function (d, b) {
	        extendStatics(d, b);
	        function __() { this.constructor = d; }
	        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
	    };
	})();
	Object.defineProperty(exports, "__esModule", { value: true });
	var disposable_1 = __jupyter_require__('@phosphor/disposable@^1.0.0/lib/index.js');
	var messages_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/messages.js');
	/**
	 * Implementation of a kernel future.
	 */
	var KernelFutureHandler = (function (_super) {
	    __extends(KernelFutureHandler, _super);
	    /**
	     * Construct a new KernelFutureHandler.
	     */
	    function KernelFutureHandler(cb, msg, expectShell, disposeOnDone) {
	        var _this = _super.call(this, cb) || this;
	        _this._msg = null;
	        _this._status = 0;
	        _this._stdin = null;
	        _this._iopub = null;
	        _this._reply = null;
	        _this._done = null;
	        _this._hooks = new Private.HookList();
	        _this._disposeOnDone = true;
	        _this._msg = msg;
	        if (!expectShell) {
	            _this._setFlag(Private.KernelFutureFlag.GotReply);
	        }
	        _this._disposeOnDone = disposeOnDone;
	        return _this;
	    }
	    Object.defineProperty(KernelFutureHandler.prototype, "msg", {
	        /**
	         * Get the original outgoing message.
	         */
	        get: function () {
	            return this._msg;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelFutureHandler.prototype, "isDone", {
	        /**
	         * Check for message done state.
	         */
	        get: function () {
	            return this._testFlag(Private.KernelFutureFlag.IsDone);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelFutureHandler.prototype, "onReply", {
	        /**
	         * Get the reply handler.
	         */
	        get: function () {
	            return this._reply;
	        },
	        /**
	         * Set the reply handler.
	         */
	        set: function (cb) {
	            this._reply = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelFutureHandler.prototype, "onIOPub", {
	        /**
	         * Get the iopub handler.
	         */
	        get: function () {
	            return this._iopub;
	        },
	        /**
	         * Set the iopub handler.
	         */
	        set: function (cb) {
	            this._iopub = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelFutureHandler.prototype, "onDone", {
	        /**
	         * Get the done handler.
	         */
	        get: function () {
	            return this._done;
	        },
	        /**
	         * Set the done handler.
	         */
	        set: function (cb) {
	            this._done = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelFutureHandler.prototype, "onStdin", {
	        /**
	         * Get the stdin handler.
	         */
	        get: function () {
	            return this._stdin;
	        },
	        /**
	         * Set the stdin handler.
	         */
	        set: function (cb) {
	            this._stdin = cb;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Register hook for IOPub messages.
	     *
	     * @param hook - The callback invoked for an IOPub message.
	     *
	     * #### Notes
	     * The IOPub hook system allows you to preempt the handlers for IOPub messages handled
	     * by the future. The most recently registered hook is run first.
	     * If the hook returns false, any later hooks and the future's onIOPub handler will not run.
	     * If a hook throws an error, the error is logged to the console and the next hook is run.
	     * If a hook is registered during the hook processing, it won't run until the next message.
	     * If a hook is removed during the hook processing, it will be deactivated immediately.
	     */
	    KernelFutureHandler.prototype.registerMessageHook = function (hook) {
	        this._hooks.add(hook);
	    };
	    /**
	     * Remove a hook for IOPub messages.
	     *
	     * @param hook - The hook to remove.
	     *
	     * #### Notes
	     * If a hook is removed during the hook processing, it will be deactivated immediately.
	     */
	    KernelFutureHandler.prototype.removeMessageHook = function (hook) {
	        if (this.isDisposed) {
	            return;
	        }
	        this._hooks.remove(hook);
	    };
	    /**
	     * Dispose and unregister the future.
	     */
	    KernelFutureHandler.prototype.dispose = function () {
	        this._stdin = null;
	        this._iopub = null;
	        this._reply = null;
	        this._done = null;
	        this._msg = null;
	        if (this._hooks) {
	            this._hooks.dispose();
	        }
	        this._hooks = null;
	        _super.prototype.dispose.call(this);
	    };
	    /**
	     * Handle an incoming kernel message.
	     */
	    KernelFutureHandler.prototype.handleMsg = function (msg) {
	        switch (msg.channel) {
	            case 'shell':
	                this._handleReply(msg);
	                break;
	            case 'stdin':
	                this._handleStdin(msg);
	                break;
	            case 'iopub':
	                this._handleIOPub(msg);
	                break;
	        }
	    };
	    KernelFutureHandler.prototype._handleReply = function (msg) {
	        var reply = this._reply;
	        if (reply) {
	            reply(msg);
	        }
	        this._setFlag(Private.KernelFutureFlag.GotReply);
	        if (this._testFlag(Private.KernelFutureFlag.GotIdle)) {
	            this._handleDone();
	        }
	    };
	    KernelFutureHandler.prototype._handleStdin = function (msg) {
	        var stdin = this._stdin;
	        if (stdin) {
	            stdin(msg);
	        }
	    };
	    KernelFutureHandler.prototype._handleIOPub = function (msg) {
	        var process = this._hooks.process(msg);
	        var iopub = this._iopub;
	        if (process && iopub) {
	            iopub(msg);
	        }
	        if (messages_1.KernelMessage.isStatusMsg(msg) &&
	            msg.content.execution_state === 'idle') {
	            this._setFlag(Private.KernelFutureFlag.GotIdle);
	            if (this._testFlag(Private.KernelFutureFlag.GotReply)) {
	                this._handleDone();
	            }
	        }
	    };
	    KernelFutureHandler.prototype._handleDone = function () {
	        if (this.isDone) {
	            return;
	        }
	        this._setFlag(Private.KernelFutureFlag.IsDone);
	        var done = this._done;
	        if (done)
	            done();
	        this._done = null;
	        if (this._disposeOnDone) {
	            this.dispose();
	        }
	    };
	    /**
	     * Test whether the given future flag is set.
	     */
	    KernelFutureHandler.prototype._testFlag = function (flag) {
	        return (this._status & flag) !== 0;
	    };
	    /**
	     * Set the given future flag.
	     */
	    KernelFutureHandler.prototype._setFlag = function (flag) {
	        this._status |= flag;
	    };
	    return KernelFutureHandler;
	}(disposable_1.DisposableDelegate));
	exports.KernelFutureHandler = KernelFutureHandler;
	var Private;
	(function (Private) {
	    /**
	     * A polyfill for a function to run code outside of the current execution context.
	     */
	    var defer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setImmediate;
	    var HookList = (function () {
	        function HookList() {
	            this._hooks = [];
	        }
	        /**
	         * Register a hook.
	         *
	         * @param hook - The callback to register.
	         */
	        HookList.prototype.add = function (hook) {
	            this.remove(hook);
	            this._hooks.push(hook);
	        };
	        /**
	         * Remove a hook.
	         *
	         * @param hook - The callback to remove.
	         */
	        HookList.prototype.remove = function (hook) {
	            if (this.isDisposed) {
	                return;
	            }
	            var index = this._hooks.indexOf(hook);
	            if (index >= 0) {
	                this._hooks[index] = null;
	                this._scheduleCompact();
	            }
	        };
	        /**
	         * Process a message through the hooks.
	         *
	         * #### Notes
	         * The most recently registered hook is run first.
	         * If the hook returns false, any later hooks will not run.
	         * If a hook throws an error, the error is logged to the console and the next hook is run.
	         * If a hook is registered during the hook processing, it won't run until the next message.
	         * If a hook is removed during the hook processing, it will be deactivated immediately.
	         */
	        HookList.prototype.process = function (msg) {
	            var continueHandling;
	            // most recently-added hook is called first
	            for (var i = this._hooks.length - 1; i >= 0; i--) {
	                var hook = this._hooks[i];
	                if (hook === null) {
	                    continue;
	                }
	                try {
	                    continueHandling = hook(msg);
	                }
	                catch (err) {
	                    continueHandling = true;
	                    console.error(err);
	                }
	                if (continueHandling === false) {
	                    return false;
	                }
	            }
	            return true;
	        };
	        Object.defineProperty(HookList.prototype, "isDisposed", {
	            /**
	             * Test whether the HookList has been disposed.
	             */
	            get: function () {
	                return (this._hooks === null);
	            },
	            enumerable: true,
	            configurable: true
	        });
	        /**
	         * Dispose the hook list.
	         */
	        HookList.prototype.dispose = function () {
	            this._hooks = null;
	        };
	        /**
	         * Schedule a cleanup of the list, removing any hooks that have been nulled out.
	         */
	        HookList.prototype._scheduleCompact = function () {
	            var _this = this;
	            if (!this._cleanupScheduled) {
	                this._cleanupScheduled = true;
	                defer(function () {
	                    _this._cleanupScheduled = false;
	                    _this._compact();
	                });
	            }
	        };
	        /**
	         * Compact the list, removing any nulls.
	         */
	        HookList.prototype._compact = function () {
	            if (this.isDisposed) {
	                return;
	            }
	            var numNulls = 0;
	            for (var i = 0, len = this._hooks.length; i < len; i++) {
	                var hook = this._hooks[i];
	                if (this._hooks[i] === null) {
	                    numNulls++;
	                }
	                else {
	                    this._hooks[i - numNulls] = hook;
	                }
	            }
	            this._hooks.length -= numNulls;
	        };
	        return HookList;
	    }());
	    Private.HookList = HookList;
	    /**
	     * Bit flags for the kernel future state.
	     */
	    var KernelFutureFlag;
	    (function (KernelFutureFlag) {
	        KernelFutureFlag[KernelFutureFlag["GotReply"] = 1] = "GotReply";
	        KernelFutureFlag[KernelFutureFlag["GotIdle"] = 2] = "GotIdle";
	        KernelFutureFlag[KernelFutureFlag["IsDone"] = 4] = "IsDone";
	        KernelFutureFlag[KernelFutureFlag["DisposeOnDone"] = 8] = "DisposeOnDone";
	    })(KernelFutureFlag = Private.KernelFutureFlag || (Private.KernelFutureFlag = {}));
	})(Private || (Private = {}));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __jupyter_require__('timers-browserify@2.0.2/main.js').setImmediate))
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/future.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/serialize.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/serialize.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Deserialize and return the unpacked message.
	 *
	 * #### Notes
	 * Handles JSON blob strings and binary messages.
	 */
	function deserialize(data) {
	    var value;
	    if (typeof data === 'string') {
	        value = JSON.parse(data);
	    }
	    else {
	        value = deserializeBinary(data);
	    }
	    return value;
	}
	exports.deserialize = deserialize;
	/**
	 * Serialize a kernel message for transport.
	 *
	 * #### Notes
	 * If there is binary content, an `ArrayBuffer` is returned,
	 * otherwise the message is converted to a JSON string.
	 */
	function serialize(msg) {
	    var value;
	    if (msg.buffers && msg.buffers.length) {
	        value = serializeBinary(msg);
	    }
	    else {
	        value = JSON.stringify(msg);
	    }
	    return value;
	}
	exports.serialize = serialize;
	/**
	 * Deserialize a binary message to a Kernel Message.
	 */
	function deserializeBinary(buf) {
	    var data = new DataView(buf);
	    // read the header: 1 + nbufs 32b integers
	    var nbufs = data.getUint32(0);
	    var offsets = [];
	    if (nbufs < 2) {
	        throw new Error('Invalid incoming Kernel Message');
	    }
	    for (var i = 1; i <= nbufs; i++) {
	        offsets.push(data.getUint32(i * 4));
	    }
	    var jsonBytes = new Uint8Array(buf.slice(offsets[0], offsets[1]));
	    var msg = JSON.parse((new TextDecoder('utf8')).decode(jsonBytes));
	    // the remaining chunks are stored as DataViews in msg.buffers
	    msg.buffers = [];
	    for (var i = 1; i < nbufs; i++) {
	        var start = offsets[i];
	        var stop_1 = offsets[i + 1] || buf.byteLength;
	        msg.buffers.push(new DataView(buf.slice(start, stop_1)));
	    }
	    return msg;
	}
	/**
	 * Implement the binary serialization protocol.
	 *
	 * Serialize Kernel message to ArrayBuffer.
	 */
	function serializeBinary(msg) {
	    var offsets = [];
	    var buffers = [];
	    var encoder = new TextEncoder('utf8');
	    var jsonUtf8 = encoder.encode(JSON.stringify(msg, replaceBuffers));
	    buffers.push(jsonUtf8.buffer);
	    for (var i = 0; i < msg.buffers.length; i++) {
	        // msg.buffers elements could be either views or ArrayBuffers
	        // buffers elements are ArrayBuffers
	        var b = msg.buffers[i];
	        buffers.push(b instanceof ArrayBuffer ? b : b.buffer);
	    }
	    var nbufs = buffers.length;
	    offsets.push(4 * (nbufs + 1));
	    for (var i = 0; i + 1 < buffers.length; i++) {
	        offsets.push(offsets[offsets.length - 1] + buffers[i].byteLength);
	    }
	    var msgBuf = new Uint8Array(offsets[offsets.length - 1] + buffers[buffers.length - 1].byteLength);
	    // use DataView.setUint32 for network byte-order
	    var view = new DataView(msgBuf.buffer);
	    // write nbufs to first 4 bytes
	    view.setUint32(0, nbufs);
	    // write offsets to next 4 * nbufs bytes
	    for (var i = 0; i < offsets.length; i++) {
	        view.setUint32(4 * (i + 1), offsets[i]);
	    }
	    // write all the buffers at their respective offsets
	    for (var i = 0; i < buffers.length; i++) {
	        msgBuf.set(new Uint8Array(buffers[i]), offsets[i]);
	    }
	    return msgBuf.buffer;
	}
	/**
	 * Filter `"buffers"` key for `JSON.stringify`.
	 */
	function replaceBuffers(key, value) {
	    if (key === 'buffers') {
	        return undefined;
	    }
	    return value;
	}
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/serialize.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/validate.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/validate.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	/**
	 * Required fields for `IKernelHeader`.
	 */
	var HEADER_FIELDS = ['username', 'version', 'session', 'msg_id', 'msg_type'];
	/**
	 * Requred fields and types for contents of various types of `kernel.IMessage`
	 * messages on the iopub channel.
	 */
	var IOPUB_CONTENT_FIELDS = {
	    stream: { name: 'string', text: 'string' },
	    display_data: { data: 'object', metadata: 'object' },
	    execute_input: { code: 'string', execution_count: 'number' },
	    execute_result: { execution_count: 'number', data: 'object',
	        metadata: 'object' },
	    error: { ename: 'string', evalue: 'string', traceback: 'object' },
	    status: { execution_state: 'string' },
	    clear_output: { wait: 'boolean' },
	    comm_open: { comm_id: 'string', target_name: 'string', data: 'object' },
	    comm_msg: { comm_id: 'string', data: 'object' },
	    comm_close: { comm_id: 'string' },
	    shutdown_reply: { restart: 'boolean' } // Emitted by the IPython kernel.
	};
	/**
	 * Validate a property as being on an object, and optionally
	 * of a given type.
	 */
	function validateProperty(object, name, typeName) {
	    if (!object.hasOwnProperty(name)) {
	        throw Error("Missing property '" + name + "'");
	    }
	    if (typeName !== void 0) {
	        var valid = true;
	        var value = object[name];
	        switch (typeName) {
	            case 'array':
	                valid = Array.isArray(value);
	                break;
	            case 'object':
	                valid = typeof value !== 'undefined';
	                break;
	            default:
	                valid = typeof value === typeName;
	        }
	        if (!valid) {
	            throw new Error("Property '" + name + "' is not of type '" + typeName);
	        }
	    }
	}
	/**
	 * Validate the header of a kernel message.
	 */
	function validateHeader(header) {
	    for (var i = 0; i < HEADER_FIELDS.length; i++) {
	        validateProperty(header, HEADER_FIELDS[i], 'string');
	    }
	}
	/**
	 * Validate a kernel message object.
	 */
	function validateMessage(msg) {
	    validateProperty(msg, 'metadata', 'object');
	    validateProperty(msg, 'content', 'object');
	    validateProperty(msg, 'channel', 'string');
	    validateHeader(msg.header);
	    if (msg.channel === 'iopub') {
	        validateIOPubContent(msg);
	    }
	}
	exports.validateMessage = validateMessage;
	/**
	 * Validate content an kernel message on the iopub channel.
	 */
	function validateIOPubContent(msg) {
	    if (msg.channel === 'iopub') {
	        var fields = IOPUB_CONTENT_FIELDS[msg.header.msg_type];
	        // Check for unknown message type.
	        if (fields === void 0) {
	            return;
	        }
	        var names = Object.keys(fields);
	        var content = msg.content;
	        for (var i = 0; i < names.length; i++) {
	            validateProperty(content, names[i], fields[names[i]]);
	        }
	    }
	}
	/**
	 * Validate a `Kernel.IModel` object.
	 */
	function validateModel(model) {
	    validateProperty(model, 'name', 'string');
	    validateProperty(model, 'id', 'string');
	}
	exports.validateModel = validateModel;
	/**
	 * Validate a server kernelspec model to a client side model.
	 */
	function validateSpecModel(data) {
	    var spec = data.spec;
	    if (!spec) {
	        throw new Error('Invalid kernel spec');
	    }
	    validateProperty(data, 'name', 'string');
	    validateProperty(data, 'resources', 'object');
	    validateProperty(spec, 'language', 'string');
	    validateProperty(spec, 'display_name', 'string');
	    validateProperty(spec, 'argv', 'array');
	    return {
	        name: data.name,
	        resources: data.resources,
	        language: spec.language,
	        display_name: spec.display_name,
	        argv: spec.argv
	    };
	}
	exports.validateSpecModel = validateSpecModel;
	/**
	 * Validate a `Kernel.ISpecModels` object.
	 */
	function validateSpecModels(data) {
	    if (!data.hasOwnProperty('kernelspecs')) {
	        throw new Error('No kernelspecs found');
	    }
	    var keys = Object.keys(data.kernelspecs);
	    var kernelspecs = Object.create(null);
	    var defaultSpec = data.default;
	    for (var i = 0; i < keys.length; i++) {
	        var ks = data.kernelspecs[keys[i]];
	        try {
	            kernelspecs[keys[i]] = validateSpecModel(ks);
	        }
	        catch (err) {
	            // Remove the errant kernel spec.
	            console.warn("Removing errant kernel spec: " + keys[i]);
	        }
	    }
	    keys = Object.keys(kernelspecs);
	    if (!keys.length) {
	        throw new Error('No valid kernelspecs found');
	    }
	    if (!defaultSpec || typeof defaultSpec !== 'string' ||
	        !(defaultSpec in kernelspecs)) {
	        defaultSpec = keys[0];
	        console.warn("Default kernel not found, using '" + keys[0] + "'");
	    }
	    return {
	        default: defaultSpec,
	        kernelspecs: kernelspecs,
	    };
	}
	exports.validateSpecModels = validateSpecModels;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/validate.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/manager.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/kernel/manager.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	var kernel_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/kernel.js');
	/**
	 * An implementation of a kernel manager.
	 */
	var KernelManager = (function () {
	    /**
	     * Construct a new kernel manager.
	     *
	     * @param options - The default options for kernel.
	     */
	    function KernelManager(options) {
	        if (options === void 0) { options = {}; }
	        var _this = this;
	        this._baseUrl = '';
	        this._wsUrl = '';
	        this._token = '';
	        this._ajaxSettings = '';
	        this._running = [];
	        this._specs = null;
	        this._isDisposed = false;
	        this._runningTimer = -1;
	        this._specsTimer = -1;
	        this._isReady = false;
	        this._specsChanged = new signaling_1.Signal(this);
	        this._runningChanged = new signaling_1.Signal(this);
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._wsUrl = options.wsUrl || utils.getWsUrl(this._baseUrl);
	        this._token = options.token || utils.getConfigOption('token');
	        this._ajaxSettings = JSON.stringify(utils.ajaxSettingsWithToken(options.ajaxSettings, options.token));
	        // Initialize internal data.
	        this._readyPromise = this._refreshSpecs().then(function () {
	            return _this._refreshRunning();
	        });
	        // Set up polling.
	        this._runningTimer = setInterval(function () {
	            _this._refreshRunning();
	        }, 10000);
	        this._specsTimer = setInterval(function () {
	            _this._refreshSpecs();
	        }, 61000);
	    }
	    Object.defineProperty(KernelManager.prototype, "specsChanged", {
	        /**
	         * A signal emitted when the specs change.
	         */
	        get: function () {
	            return this._specsChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelManager.prototype, "runningChanged", {
	        /**
	         * A signal emitted when the running kernels change.
	         */
	        get: function () {
	            return this._runningChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelManager.prototype, "isDisposed", {
	        /**
	         * Test whether the terminal manager is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the manager.
	     */
	    KernelManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        clearInterval(this._runningTimer);
	        clearInterval(this._specsTimer);
	        signaling_1.Signal.clearData(this);
	        this._specs = null;
	        this._running = [];
	    };
	    Object.defineProperty(KernelManager.prototype, "baseUrl", {
	        /**
	         * Get the base url of the manager.
	         */
	        get: function () {
	            return this._baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelManager.prototype, "wsUrl", {
	        /**
	         * Get the ws url of the manager.
	         */
	        get: function () {
	            return this._wsUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelManager.prototype, "ajaxSettings", {
	        /**
	         * The default ajax settings for the manager.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the manager.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelManager.prototype, "specs", {
	        /**
	         * Get the most recently fetched kernel specs.
	         */
	        get: function () {
	            return this._specs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelManager.prototype, "isReady", {
	        /**
	         * Test whether the manager is ready.
	         */
	        get: function () {
	            return this._isReady;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(KernelManager.prototype, "ready", {
	        /**
	         * A promise that fulfills when the manager is ready.
	         */
	        get: function () {
	            return this._readyPromise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the most recent running kernels.
	     *
	     * @returns A new iterator over the running kernels.
	     */
	    KernelManager.prototype.running = function () {
	        return algorithm_1.iter(this._running);
	    };
	    /**
	     * Force a refresh of the specs from the server.
	     *
	     * @returns A promise that resolves when the specs are fetched.
	     *
	     * #### Notes
	     * This is intended to be called only in response to a user action,
	     * since the manager maintains its internal state.
	     */
	    KernelManager.prototype.refreshSpecs = function () {
	        return this._refreshSpecs();
	    };
	    /**
	     * Force a refresh of the running kernels.
	     *
	     * @returns A promise that with the list of running sessions.
	     *
	     * #### Notes
	     * This is not typically meant to be called by the user, since the
	     * manager maintains its own internal state.
	     */
	    KernelManager.prototype.refreshRunning = function () {
	        return this._refreshRunning();
	    };
	    /**
	     * Start a new kernel.  See also [[startNewKernel]].
	     *
	     * @param options - Overrides for the default options.
	     */
	    KernelManager.prototype.startNew = function (options) {
	        var _this = this;
	        return kernel_1.Kernel.startNew(this._getOptions(options)).then(function (kernel) {
	            _this._onStarted(kernel);
	            return kernel;
	        });
	    };
	    /**
	     * Find a kernel by id.
	     *
	     * @param options - Overrides for the default options.
	     */
	    KernelManager.prototype.findById = function (id, options) {
	        return kernel_1.Kernel.findById(id, this._getOptions(options));
	    };
	    /**
	     * Connect to a running kernel.  See also [[connectToKernel]].
	     *
	     * @param options - Overrides for the default options.
	     */
	    KernelManager.prototype.connectTo = function (id, options) {
	        var _this = this;
	        return kernel_1.Kernel.connectTo(id, this._getOptions(options)).then(function (kernel) {
	            _this._onStarted(kernel);
	            return kernel;
	        });
	    };
	    /**
	     * Shut down a kernel by id.
	     *
	     * @param options - Overrides for the default options.
	     *
	     * #### Notes
	     * This will emit [[runningChanged]] if the running kernels list
	     * changes.
	     */
	    KernelManager.prototype.shutdown = function (id, options) {
	        var _this = this;
	        return kernel_1.Kernel.shutdown(id, this._getOptions(options)).then(function () {
	            _this._onTerminated(id);
	        });
	    };
	    /**
	     * Handle a kernel terminating.
	     */
	    KernelManager.prototype._onTerminated = function (id) {
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._running, function (value) { return value.id === id; });
	        if (index !== -1) {
	            this._running.splice(index, 1);
	            this._runningChanged.emit(this._running.slice());
	        }
	    };
	    /**
	     * Handle a kernel starting.
	     */
	    KernelManager.prototype._onStarted = function (kernel) {
	        var _this = this;
	        var id = kernel.id;
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._running, function (value) { return value.id === id; });
	        if (index === -1) {
	            this._running.push(kernel.model);
	            this._runningChanged.emit(this._running.slice());
	        }
	        kernel.terminated.connect(function () {
	            _this._onTerminated(id);
	        });
	    };
	    /**
	     * Refresh the specs.
	     */
	    KernelManager.prototype._refreshSpecs = function () {
	        var _this = this;
	        var options = {
	            baseUrl: this._baseUrl,
	            token: this._token,
	            ajaxSettings: this.ajaxSettings
	        };
	        return kernel_1.Kernel.getSpecs(options).then(function (specs) {
	            if (!coreutils_1.JSONExt.deepEqual(specs, _this._specs)) {
	                _this._specs = specs;
	                _this._specsChanged.emit(specs);
	            }
	        });
	    };
	    /**
	     * Refresh the running sessions.
	     */
	    KernelManager.prototype._refreshRunning = function () {
	        var _this = this;
	        return kernel_1.Kernel.listRunning(this._getOptions({})).then(function (running) {
	            _this._isReady = true;
	            if (!coreutils_1.JSONExt.deepEqual(running, _this._running)) {
	                _this._running = running.slice();
	                _this._runningChanged.emit(running);
	            }
	        });
	    };
	    /**
	     * Get optionally overidden options.
	     */
	    KernelManager.prototype._getOptions = function (options) {
	        if (options === void 0) { options = {}; }
	        options.baseUrl = this._baseUrl;
	        options.wsUrl = this._wsUrl;
	        options.token = this._token;
	        options.ajaxSettings = options.ajaxSettings || this.ajaxSettings;
	        return options;
	    };
	    return KernelManager;
	}());
	exports.KernelManager = KernelManager;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/kernel/manager.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/manager.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/manager.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var contents_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/contents/index.js');
	var session_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/session/index.js');
	var terminal_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/terminal/index.js');
	var utils_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	/**
	 * A Jupyter services manager.
	 */
	var ServiceManager = (function () {
	    /**
	     * Construct a new services provider.
	     */
	    function ServiceManager(options) {
	        var _this = this;
	        this._sessionManager = null;
	        this._contentsManager = null;
	        this._terminalManager = null;
	        this._isDisposed = false;
	        this._specsChanged = new signaling_1.Signal(this);
	        options = options || {};
	        options.wsUrl = options.wsUrl || utils_1.getWsUrl();
	        options.baseUrl = options.baseUrl || utils_1.getBaseUrl();
	        options.ajaxSettings = utils_1.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        this._sessionManager = new session_1.SessionManager(options);
	        this._contentsManager = new contents_1.ContentsManager(options);
	        this._terminalManager = new terminal_1.TerminalManager(options);
	        this._sessionManager.specsChanged.connect(function (sender, specs) {
	            _this._specsChanged.emit(specs);
	        });
	        this._readyPromise = this._sessionManager.ready.then(function () {
	            if (_this._terminalManager.isAvailable()) {
	                return _this._terminalManager.ready;
	            }
	        });
	    }
	    Object.defineProperty(ServiceManager.prototype, "specsChanged", {
	        /**
	         * A signal emitted when the kernel specs change.
	         */
	        get: function () {
	            return this._specsChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ServiceManager.prototype, "isDisposed", {
	        /**
	         * Test whether the terminal manager is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the manager.
	     */
	    ServiceManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        signaling_1.Signal.clearData(this);
	        this._sessionManager.dispose();
	        this._contentsManager.dispose();
	        this._sessionManager.dispose();
	    };
	    Object.defineProperty(ServiceManager.prototype, "specs", {
	        /**
	         * The kernel spec models.
	         */
	        get: function () {
	            return this._sessionManager.specs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ServiceManager.prototype, "baseUrl", {
	        /**
	         * Get the base url of the server.
	         */
	        get: function () {
	            return this._sessionManager.baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ServiceManager.prototype, "sessions", {
	        /**
	         * Get the session manager instance.
	         */
	        get: function () {
	            return this._sessionManager;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ServiceManager.prototype, "contents", {
	        /**
	         * Get the contents manager instance.
	         */
	        get: function () {
	            return this._contentsManager;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ServiceManager.prototype, "terminals", {
	        /**
	         * Get the terminal manager instance.
	         */
	        get: function () {
	            return this._terminalManager;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ServiceManager.prototype, "isReady", {
	        /**
	         * Test whether the manager is ready.
	         */
	        get: function () {
	            return this._sessionManager.isReady || this._terminalManager.isReady;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(ServiceManager.prototype, "ready", {
	        /**
	         * A promise that fulfills when the manager is ready.
	         */
	        get: function () {
	            return this._readyPromise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    return ServiceManager;
	}());
	exports.ServiceManager = ServiceManager;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/manager.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/index.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/session/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/session/manager.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/session/session.js'));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/index.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/manager.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/session/manager.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var kernel_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/index.js');
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	var session_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/session/session.js');
	/**
	 * An implementation of a session manager.
	 */
	var SessionManager = (function () {
	    /**
	     * Construct a new session manager.
	     *
	     * @param options - The default options for each session.
	     */
	    function SessionManager(options) {
	        if (options === void 0) { options = {}; }
	        var _this = this;
	        this._baseUrl = '';
	        this._wsUrl = '';
	        this._ajaxSettings = '';
	        this._isDisposed = false;
	        this._running = [];
	        this._specs = null;
	        this._runningTimer = -1;
	        this._specsTimer = -1;
	        this._specsChanged = new signaling_1.Signal(this);
	        this._runningChanged = new signaling_1.Signal(this);
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._wsUrl = options.wsUrl || utils.getWsUrl(this._baseUrl);
	        this._ajaxSettings = JSON.stringify(options.ajaxSettings || {});
	        // Initialize internal data.
	        this._readyPromise = this._refreshSpecs().then(function () {
	            return _this._refreshRunning();
	        });
	        // Set up polling.
	        this._runningTimer = setInterval(function () {
	            _this._refreshRunning();
	        }, 10000);
	        this._specsTimer = setInterval(function () {
	            _this._refreshSpecs();
	        }, 61000);
	    }
	    Object.defineProperty(SessionManager.prototype, "specsChanged", {
	        /**
	         * A signal emitted when the kernel specs change.
	         */
	        get: function () {
	            return this._specsChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SessionManager.prototype, "runningChanged", {
	        /**
	         * A signal emitted when the running sessions change.
	         */
	        get: function () {
	            return this._runningChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SessionManager.prototype, "isDisposed", {
	        /**
	         * Test whether the terminal manager is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the manager.
	     */
	    SessionManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        clearInterval(this._runningTimer);
	        clearInterval(this._specsTimer);
	        signaling_1.Signal.clearData(this);
	        this._running = [];
	    };
	    Object.defineProperty(SessionManager.prototype, "baseUrl", {
	        /**
	         * The base url of the manager.
	         */
	        get: function () {
	            return this._baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SessionManager.prototype, "wsUrl", {
	        /**
	         * The base ws url of the manager.
	         */
	        get: function () {
	            return this._wsUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SessionManager.prototype, "ajaxSettings", {
	        /**
	         * The default ajax settings for the manager.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the manager.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SessionManager.prototype, "specs", {
	        /**
	         * Get the most recently fetched kernel specs.
	         */
	        get: function () {
	            return this._specs;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SessionManager.prototype, "isReady", {
	        /**
	         * Test whether the manager is ready.
	         */
	        get: function () {
	            return this._specs !== null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(SessionManager.prototype, "ready", {
	        /**
	         * A promise that fulfills when the manager is ready.
	         */
	        get: function () {
	            return this._readyPromise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Create an iterator over the most recent running sessions.
	     *
	     * @returns A new iterator over the running sessions.
	     */
	    SessionManager.prototype.running = function () {
	        return algorithm_1.iter(this._running);
	    };
	    /**
	     * Force a refresh of the specs from the server.
	     *
	     * @returns A promise that resolves when the specs are fetched.
	     *
	     * #### Notes
	     * This is intended to be called only in response to a user action,
	     * since the manager maintains its internal state.
	     */
	    SessionManager.prototype.refreshSpecs = function () {
	        return this._refreshSpecs();
	    };
	    /**
	     * Force a refresh of the running sessions.
	     *
	     * @returns A promise that with the list of running sessions.
	     *
	     * #### Notes
	     * This is not typically meant to be called by the user, since the
	     * manager maintains its own internal state.
	     */
	    SessionManager.prototype.refreshRunning = function () {
	        return this._refreshRunning();
	    };
	    /**
	     * Start a new session.  See also [[startNewSession]].
	     *
	     * @param options - Overrides for the default options, must include a
	     *   `'path'`.
	     */
	    SessionManager.prototype.startNew = function (options) {
	        var _this = this;
	        return session_1.Session.startNew(this._getOptions(options)).then(function (session) {
	            _this._onStarted(session);
	            return session;
	        });
	    };
	    /**
	     * Find a session by id.
	     */
	    SessionManager.prototype.findById = function (id, options) {
	        return session_1.Session.findById(id, this._getOptions(options));
	    };
	    /**
	     * Find a session by path.
	     */
	    SessionManager.prototype.findByPath = function (path, options) {
	        return session_1.Session.findByPath(path, this._getOptions(options));
	    };
	    /*
	     * Connect to a running session.  See also [[connectToSession]].
	     */
	    SessionManager.prototype.connectTo = function (id, options) {
	        var _this = this;
	        return session_1.Session.connectTo(id, this._getOptions(options)).then(function (session) {
	            _this._onStarted(session);
	            return session;
	        });
	    };
	    /**
	     * Shut down a session by id.
	     */
	    SessionManager.prototype.shutdown = function (id, options) {
	        var _this = this;
	        return session_1.Session.shutdown(id, this._getOptions(options)).then(function () {
	            _this._onTerminated(id);
	        });
	    };
	    /**
	     * Get optionally overidden options.
	     */
	    SessionManager.prototype._getOptions = function (options) {
	        if (options === void 0) { options = {}; }
	        options.baseUrl = this._baseUrl;
	        options.wsUrl = this._wsUrl;
	        options.ajaxSettings = options.ajaxSettings || this.ajaxSettings;
	        return options;
	    };
	    /**
	     * Handle a session terminating.
	     */
	    SessionManager.prototype._onTerminated = function (id) {
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._running, function (value) { return value.id === id; });
	        if (index !== -1) {
	            this._running.splice(index, 1);
	            this._runningChanged.emit(this._running.slice());
	        }
	    };
	    /**
	     * Handle a session starting.
	     */
	    SessionManager.prototype._onStarted = function (session) {
	        var _this = this;
	        var id = session.id;
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._running, function (value) { return value.id === id; });
	        if (index === -1) {
	            this._running.push(session.model);
	            this._runningChanged.emit(this._running.slice());
	        }
	        session.terminated.connect(function () {
	            _this._onTerminated(id);
	        });
	        session.pathChanged.connect(function () {
	            _this._onChanged(session.model);
	        });
	        session.kernelChanged.connect(function () {
	            _this._onChanged(session.model);
	        });
	    };
	    /**
	     * Handle a change to a session.
	     */
	    SessionManager.prototype._onChanged = function (model) {
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._running, function (value) { return value.id === model.id; });
	        if (index !== -1) {
	            this._running[index] = model;
	            this._runningChanged.emit(this._running.slice());
	        }
	    };
	    /**
	     * Refresh the specs.
	     */
	    SessionManager.prototype._refreshSpecs = function () {
	        var _this = this;
	        var options = {
	            baseUrl: this._baseUrl,
	            ajaxSettings: this.ajaxSettings
	        };
	        return kernel_1.Kernel.getSpecs(options).then(function (specs) {
	            if (!coreutils_1.JSONExt.deepEqual(specs, _this._specs)) {
	                _this._specs = specs;
	                _this._specsChanged.emit(specs);
	            }
	        });
	    };
	    /**
	     * Refresh the running sessions.
	     */
	    SessionManager.prototype._refreshRunning = function () {
	        var _this = this;
	        return session_1.Session.listRunning(this._getOptions({})).then(function (running) {
	            if (!coreutils_1.JSONExt.deepEqual(running, _this._running)) {
	                _this._running = running.slice();
	                _this._runningChanged.emit(running);
	            }
	        });
	    };
	    return SessionManager;
	}());
	exports.SessionManager = SessionManager;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/manager.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/session.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/session/session.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var default_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/session/default.js');
	/**
	 * A namespace for session interfaces and factory functions.
	 */
	var Session;
	(function (Session) {
	    /**
	     * List the running sessions.
	     *
	     * @param options - The options used for the request.
	     *
	     * @returns A promise that resolves with the list of session models.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/sessions), and validates the response.
	     *
	     * All client-side sessions are updated with current information.
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    function listRunning(options) {
	        return default_1.DefaultSession.listRunning(options);
	    }
	    Session.listRunning = listRunning;
	    /**
	     * Start a new session.
	     *
	     * @param options - The options used to start the session.
	     *
	     * @returns A promise that resolves with the session instance.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/sessions), and validates the response.
	     *
	     * A path must be provided.  If a kernel id is given, it will
	     * connect to an existing kernel.  If no kernel id or name is given,
	     * the server will start the default kernel type.
	     *
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     *
	     * Wrap the result in an Session object. The promise is fulfilled
	     * when the session is created on the server, otherwise the promise is
	     * rejected.
	     */
	    function startNew(options) {
	        return default_1.DefaultSession.startNew(options);
	    }
	    Session.startNew = startNew;
	    /**
	     * Find a session by id.
	     *
	     * @param id - The id of the target session.
	     *
	     * @param options - The options used to fetch the session.
	     *
	     * @returns A promise that resolves with the session model.
	     *
	     * #### Notes
	     * If the session was already started via `startNew`, the existing
	     * Session object's information is used in the fulfillment value.
	     *
	     * Otherwise, if `options` are given, we attempt to find to the existing
	     * session.
	     * The promise is fulfilled when the session is found,
	     * otherwise the promise is rejected.
	     */
	    function findById(id, options) {
	        return default_1.DefaultSession.findById(id, options);
	    }
	    Session.findById = findById;
	    /**
	     * Find a session by path.
	     *
	     * @param path - The path of the target session.
	     *
	     * @param options - The options used to fetch the session.
	     *
	     * @returns A promise that resolves with the session model.
	     *
	     * #### Notes
	     * If the session was already started via `startNewSession`, the existing
	     * Session object's info is used in the fulfillment value.
	     *
	     * Otherwise, if `options` are given, we attempt to find to the existing
	     * session using [listRunningSessions].
	     * The promise is fulfilled when the session is found,
	     * otherwise the promise is rejected.
	     *
	     * If the session was not already started and no `options` are given,
	     * the promise is rejected.
	     */
	    function findByPath(path, options) {
	        return default_1.DefaultSession.findByPath(path, options);
	    }
	    Session.findByPath = findByPath;
	    /**
	     * Connect to a running session.
	     *
	     * @param id - The id of the target session.
	     *
	     * @param options - The options used to fetch the session.
	     *
	     * @returns A promise that resolves with the session instance.
	     *
	     * #### Notes
	     * If the session was already started via `startNew`, the existing
	     * Session object is used as the fulfillment value.
	     *
	     * Otherwise, if `options` are given, we attempt to connect to the existing
	     * session.
	     * The promise is fulfilled when the session is ready on the server,
	     * otherwise the promise is rejected.
	     *
	     * If the session was not already started and no `options` are given,
	     * the promise is rejected.
	     */
	    function connectTo(id, options) {
	        return default_1.DefaultSession.connectTo(id, options);
	    }
	    Session.connectTo = connectTo;
	    /**
	     * Shut down a session by id.
	     *
	     * @param id - The id of the target session.
	     *
	     * @param options - The options used to fetch the session.
	     *
	     * @returns A promise that resolves when the session is shut down.
	     *
	     */
	    function shutdown(id, options) {
	        if (options === void 0) { options = {}; }
	        return default_1.DefaultSession.shutdown(id, options);
	    }
	    Session.shutdown = shutdown;
	})(Session = exports.Session || (exports.Session = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/session.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/default.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/session/default.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var kernel_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/index.js');
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	var validate = __jupyter_require__('@jupyterlab/services@0.42.1/lib/session/validate.js');
	/**
	 * The url for the session service.
	 */
	var SESSION_SERVICE_URL = 'api/sessions';
	/**
	 * Session object for accessing the session REST api. The session
	 * should be used to start kernels and then shut them down -- for
	 * all other operations, the kernel object should be used.
	 */
	var DefaultSession = (function () {
	    /**
	     * Construct a new session.
	     */
	    function DefaultSession(options, id, kernel) {
	        this._id = '';
	        this._path = '';
	        this._ajaxSettings = '';
	        this._token = '';
	        this._kernel = null;
	        this._uuid = '';
	        this._baseUrl = '';
	        this._options = null;
	        this._updating = false;
	        this._kernelChanged = new signaling_1.Signal(this);
	        this._statusChanged = new signaling_1.Signal(this);
	        this._iopubMessage = new signaling_1.Signal(this);
	        this._unhandledMessage = new signaling_1.Signal(this);
	        this._pathChanged = new signaling_1.Signal(this);
	        this._id = id;
	        this._path = options.path;
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._uuid = utils.uuid();
	        this._ajaxSettings = JSON.stringify(utils.ajaxSettingsWithToken(options.ajaxSettings || {}, options.token));
	        this._token = options.token || utils.getConfigOption('token');
	        Private.runningSessions.push(this);
	        this.setupKernel(kernel);
	        this._options = utils.copy(options);
	        this.terminated = new signaling_1.Signal(this);
	    }
	    Object.defineProperty(DefaultSession.prototype, "kernelChanged", {
	        /**
	         * A signal emitted when the kernel changes.
	         */
	        get: function () {
	            return this._kernelChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "statusChanged", {
	        /**
	         * A signal emitted when the kernel status changes.
	         */
	        get: function () {
	            return this._statusChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "iopubMessage", {
	        /**
	         * A signal emitted for a kernel messages.
	         */
	        get: function () {
	            return this._iopubMessage;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "unhandledMessage", {
	        /**
	         * A signal emitted for an unhandled kernel message.
	         */
	        get: function () {
	            return this._unhandledMessage;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "pathChanged", {
	        /**
	         * A signal emitted when the session path changes.
	         */
	        get: function () {
	            return this._pathChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "id", {
	        /**
	         * Get the session id.
	         */
	        get: function () {
	            return this._id;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "kernel", {
	        /**
	         * Get the session kernel object.
	         *
	         * #### Notes
	         * This is a read-only property, and can be altered by [changeKernel].
	         * Use the [statusChanged] and [unhandledMessage] signals on the session
	         * instead of the ones on the kernel.
	         */
	        get: function () {
	            return this._kernel;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "path", {
	        /**
	         * Get the session path.
	         */
	        get: function () {
	            return this._path;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "model", {
	        /**
	         * Get the model associated with the session.
	         */
	        get: function () {
	            return {
	                id: this.id,
	                kernel: this.kernel.model,
	                notebook: {
	                    path: this.path
	                }
	            };
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "status", {
	        /**
	         * The current status of the session.
	         *
	         * #### Notes
	         * This is a delegate to the kernel status.
	         */
	        get: function () {
	            return this._kernel ? this._kernel.status : 'dead';
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "baseUrl", {
	        /**
	         * Get the base url of the session.
	         */
	        get: function () {
	            return this._baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "ajaxSettings", {
	        /**
	         * Get a copy of the default ajax settings for the session.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the session.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultSession.prototype, "isDisposed", {
	        /**
	         * Test whether the session has been disposed.
	         */
	        get: function () {
	            return this._options === null;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Clone the current session with a new clientId.
	     */
	    DefaultSession.prototype.clone = function () {
	        var _this = this;
	        var options = this._getKernelOptions();
	        return kernel_1.Kernel.connectTo(this.kernel.id, options).then(function (kernel) {
	            options = utils.copy(_this._options);
	            options.ajaxSettings = _this.ajaxSettings;
	            return new DefaultSession(options, _this._id, kernel);
	        });
	    };
	    /**
	     * Update the session based on a session model from the server.
	     */
	    DefaultSession.prototype.update = function (model) {
	        var _this = this;
	        // Avoid a race condition if we are waiting for a REST call return.
	        if (this._updating) {
	            return Promise.resolve(void 0);
	        }
	        var oldPath = this._path;
	        var newPath = this._path = model.notebook.path;
	        if (this._kernel.isDisposed || model.kernel.id !== this._kernel.id) {
	            var options = this._getKernelOptions();
	            options.name = model.kernel.name;
	            return kernel_1.Kernel.connectTo(model.kernel.id, options).then(function (kernel) {
	                _this.setupKernel(kernel);
	                _this._kernelChanged.emit(kernel);
	                if (oldPath !== newPath) {
	                    _this._pathChanged.emit(newPath);
	                }
	            });
	        }
	        else if (oldPath !== newPath) {
	            this._pathChanged.emit(newPath);
	        }
	        return Promise.resolve(void 0);
	    };
	    /**
	     * Dispose of the resources held by the session.
	     */
	    DefaultSession.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._options = null;
	        if (this._kernel) {
	            this._kernel.dispose();
	        }
	        algorithm_1.ArrayExt.removeFirstOf(Private.runningSessions, this);
	        this._kernel = null;
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * Change the session path.
	     *
	     * @param path - The new session path.
	     *
	     * #### Notes
	     * This uses the Jupyter REST API, and the response is validated.
	     * The promise is fulfilled on a valid response and rejected otherwise.
	     */
	    DefaultSession.prototype.rename = function (path) {
	        if (this.isDisposed) {
	            return Promise.reject(new Error('Session is disposed'));
	        }
	        var data = JSON.stringify({
	            notebook: { path: path }
	        });
	        return this._patch(data).then(function () { return void 0; });
	    };
	    /**
	     * Change the kernel.
	     *
	     * @params options - The name or id of the new kernel.
	     *
	     * #### Notes
	     * This shuts down the existing kernel and creates a new kernel,
	     * keeping the existing session ID and session path.
	     */
	    DefaultSession.prototype.changeKernel = function (options) {
	        var _this = this;
	        if (this.isDisposed) {
	            return Promise.reject(new Error('Session is disposed'));
	        }
	        var data = JSON.stringify({ kernel: options });
	        if (this._kernel) {
	            return this._kernel.ready.then(function () {
	                _this._kernel.dispose();
	                return _this._patch(data);
	            }).then(function () { return _this.kernel; });
	        }
	        return this._patch(data).then(function () { return _this.kernel; });
	    };
	    /**
	     * Kill the kernel and shutdown the session.
	     *
	     * @returns - The promise fulfilled on a valid response from the server.
	     *
	     * #### Notes
	     * Uses the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/sessions), and validates the response.
	     * Emits a [sessionDied] signal on success.
	     */
	    DefaultSession.prototype.shutdown = function () {
	        var _this = this;
	        if (this.isDisposed) {
	            return Promise.reject(new Error('Session is disposed'));
	        }
	        if (this._kernel) {
	            return this._kernel.ready.then(function () {
	                return Private.shutdownSession(_this.id, _this._baseUrl, _this.ajaxSettings);
	            });
	        }
	        return Private.shutdownSession(this.id, this._baseUrl, this.ajaxSettings);
	    };
	    /**
	     * Handle connections to a kernel.
	     */
	    DefaultSession.prototype.setupKernel = function (kernel) {
	        this._kernel = kernel;
	        kernel.statusChanged.connect(this.onKernelStatus, this);
	        kernel.unhandledMessage.connect(this.onUnhandledMessage, this);
	        kernel.iopubMessage.connect(this.onIOPubMessage, this);
	    };
	    /**
	     * Handle to changes in the Kernel status.
	     */
	    DefaultSession.prototype.onKernelStatus = function (sender, state) {
	        this._statusChanged.emit(state);
	    };
	    /**
	     * Handle iopub kernel messages.
	     */
	    DefaultSession.prototype.onIOPubMessage = function (sender, msg) {
	        this._iopubMessage.emit(msg);
	    };
	    /**
	     * Handle unhandled kernel messages.
	     */
	    DefaultSession.prototype.onUnhandledMessage = function (sender, msg) {
	        this._unhandledMessage.emit(msg);
	    };
	    /**
	     * Get the options used to create a new kernel.
	     */
	    DefaultSession.prototype._getKernelOptions = function () {
	        return {
	            baseUrl: this._options.baseUrl,
	            wsUrl: this._options.wsUrl,
	            username: this.kernel.username,
	            ajaxSettings: this.ajaxSettings
	        };
	    };
	    /**
	     * Send a PATCH to the server, updating the session path or the kernel.
	     */
	    DefaultSession.prototype._patch = function (data) {
	        var _this = this;
	        var url = Private.getSessionUrl(this._baseUrl, this._id);
	        var ajaxSettings = this.ajaxSettings;
	        ajaxSettings.method = 'PATCH';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.data = data;
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.cache = false;
	        this._updating = true;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            _this._updating = false;
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            var value = success.data;
	            try {
	                validate.validateModel(value);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            return Private.updateFromServer(value);
	        }, function (error) {
	            _this._updating = false;
	            return Private.onSessionError(error);
	        });
	    };
	    return DefaultSession;
	}());
	exports.DefaultSession = DefaultSession;
	/**
	 * The namespace for `DefaultSession` statics.
	 */
	(function (DefaultSession) {
	    /**
	     * List the running sessions.
	     */
	    function listRunning(options) {
	        return Private.listRunning(options);
	    }
	    DefaultSession.listRunning = listRunning;
	    /**
	     * Start a new session.
	     */
	    function startNew(options) {
	        return Private.startNew(options);
	    }
	    DefaultSession.startNew = startNew;
	    /**
	     * Find a session by id.
	     */
	    function findById(id, options) {
	        return Private.findById(id, options);
	    }
	    DefaultSession.findById = findById;
	    /**
	     * Find a session by path.
	     */
	    function findByPath(path, options) {
	        return Private.findByPath(path, options);
	    }
	    DefaultSession.findByPath = findByPath;
	    /**
	     * Connect to a running session.
	     */
	    function connectTo(id, options) {
	        return Private.connectTo(id, options);
	    }
	    DefaultSession.connectTo = connectTo;
	    /**
	     * Shut down a session by id.
	     */
	    function shutdown(id, options) {
	        if (options === void 0) { options = {}; }
	        return Private.shutdown(id, options);
	    }
	    DefaultSession.shutdown = shutdown;
	})(DefaultSession = exports.DefaultSession || (exports.DefaultSession = {}));
	exports.DefaultSession = DefaultSession;
	/**
	 * A namespace for session private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * The running sessions.
	     */
	    Private.runningSessions = [];
	    /**
	     * List the running sessions.
	     */
	    function listRunning(options) {
	        if (options === void 0) { options = {}; }
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, SESSION_SERVICE_URL);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            if (!Array.isArray(success.data)) {
	                throw utils.makeAjaxError(success, 'Invalid Session list');
	            }
	            for (var i = 0; i < data.length; i++) {
	                try {
	                    validate.validateModel(data[i]);
	                }
	                catch (err) {
	                    throw utils.makeAjaxError(success, err.message);
	                }
	            }
	            return updateRunningSessions(data);
	        }, Private.onSessionError);
	    }
	    Private.listRunning = listRunning;
	    /**
	     * Start a new session.
	     */
	    function startNew(options) {
	        if (options.path === void 0) {
	            return Promise.reject(new Error('Must specify a path'));
	        }
	        return startSession(options).then(function (model) {
	            return createSession(model, options);
	        });
	    }
	    Private.startNew = startNew;
	    /**
	     * Find a session by id.
	     */
	    function findById(id, options) {
	        if (options === void 0) { options = {}; }
	        var session = algorithm_1.find(Private.runningSessions, function (value) { return value.id === id; });
	        if (session) {
	            return Promise.resolve(session.model);
	        }
	        return getSessionModel(id, options).catch(function () {
	            var msg = "No running session for id: " + id;
	            return typedThrow(msg);
	        });
	    }
	    Private.findById = findById;
	    /**
	     * Find a session by path.
	     */
	    function findByPath(path, options) {
	        if (options === void 0) { options = {}; }
	        var session = algorithm_1.find(Private.runningSessions, function (value) { return value.path === path; });
	        if (session) {
	            return Promise.resolve(session.model);
	        }
	        return listRunning(options).then(function (models) {
	            var model = algorithm_1.find(models, function (value) {
	                return value.notebook.path === path;
	            });
	            if (model) {
	                return model;
	            }
	            var msg = "No running session for path: " + path;
	            return typedThrow(msg);
	        });
	    }
	    Private.findByPath = findByPath;
	    /**
	     * Connect to a running session.
	     */
	    function connectTo(id, options) {
	        if (options === void 0) { options = {}; }
	        var session = algorithm_1.find(Private.runningSessions, function (value) { return value.id === id; });
	        if (session) {
	            return Promise.resolve(session.clone());
	        }
	        return getSessionModel(id, options).then(function (model) {
	            return createSession(model, options);
	        }).catch(function () {
	            var msg = "No running session with id: " + id;
	            return typedThrow(msg);
	        });
	    }
	    Private.connectTo = connectTo;
	    /**
	     * Shut down a session by id.
	     */
	    function shutdown(id, options) {
	        if (options === void 0) { options = {}; }
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        return shutdownSession(id, baseUrl, ajaxSettings);
	    }
	    Private.shutdown = shutdown;
	    /**
	     * Create a new session, or return an existing session if a session if
	     * the session path already exists
	     */
	    function startSession(options) {
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = utils.urlPathJoin(baseUrl, SESSION_SERVICE_URL);
	        var model = {
	            kernel: { name: options.kernelName, id: options.kernelId },
	            notebook: { path: options.path }
	        };
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.data = JSON.stringify(model);
	        ajaxSettings.contentType = 'application/json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 201) {
	                throw utils.makeAjaxError(success);
	            }
	            try {
	                validate.validateModel(success.data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            var data = success.data;
	            return updateFromServer(data);
	        }, onSessionError);
	    }
	    Private.startSession = startSession;
	    /**
	     * Create a Promise for a kernel object given a session model and options.
	     */
	    function createKernel(options) {
	        var kernelOptions = {
	            name: options.kernelName,
	            baseUrl: options.baseUrl || utils.getBaseUrl(),
	            wsUrl: options.wsUrl,
	            username: options.username,
	            clientId: options.clientId,
	            token: options.token,
	            ajaxSettings: options.ajaxSettings
	        };
	        return kernel_1.Kernel.connectTo(options.kernelId, kernelOptions);
	    }
	    /**
	     * Create a Session object.
	     *
	     * @returns - A promise that resolves with a started session.
	     */
	    function createSession(model, options) {
	        options.kernelName = model.kernel.name;
	        options.kernelId = model.kernel.id;
	        options.path = model.notebook.path;
	        return createKernel(options).then(function (kernel) {
	            return new DefaultSession(options, model.id, kernel);
	        }).catch(function (error) {
	            return typedThrow('Session failed to start: ' + error.message);
	        });
	    }
	    Private.createSession = createSession;
	    /**
	     * Get a full session model from the server by session id string.
	     */
	    function getSessionModel(id, options) {
	        options = options || {};
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = getSessionUrl(baseUrl, id);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            try {
	                validate.validateModel(data);
	            }
	            catch (err) {
	                throw utils.makeAjaxError(success, err.message);
	            }
	            return updateFromServer(data);
	        }, Private.onSessionError);
	    }
	    Private.getSessionModel = getSessionModel;
	    /**
	     * Update the running sessions based on new data from the server.
	     */
	    function updateRunningSessions(sessions) {
	        var promises = [];
	        algorithm_1.each(Private.runningSessions, function (session) {
	            var updated = algorithm_1.find(sessions, function (sId) {
	                if (session.id === sId.id) {
	                    promises.push(session.update(sId));
	                    return true;
	                }
	            });
	            // If session is no longer running on disk, emit dead signal.
	            if (!updated && session.status !== 'dead') {
	                session.terminated.emit(void 0);
	            }
	        });
	        return Promise.all(promises).then(function () { return sessions; });
	    }
	    Private.updateRunningSessions = updateRunningSessions;
	    /**
	     * Update the running sessions given an updated session Id.
	     */
	    function updateFromServer(model) {
	        var promises = [];
	        algorithm_1.each(Private.runningSessions, function (session) {
	            if (session.id === model.id) {
	                promises.push(session.update(model));
	            }
	        });
	        return Promise.all(promises).then(function () { return model; });
	    }
	    Private.updateFromServer = updateFromServer;
	    /**
	     * Shut down a session by id.
	     */
	    function shutdownSession(id, baseUrl, ajaxSettings) {
	        if (ajaxSettings === void 0) { ajaxSettings = {}; }
	        var url = getSessionUrl(baseUrl, id);
	        ajaxSettings.method = 'DELETE';
	        ajaxSettings.dataType = 'json';
	        ajaxSettings.cache = false;
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw utils.makeAjaxError(success);
	            }
	            killSessions(id);
	        }, function (err) {
	            if (err.xhr.status === 404) {
	                var response = JSON.parse(err.xhr.responseText);
	                console.warn(response['message']);
	                killSessions(id);
	                return;
	            }
	            if (err.xhr.status === 410) {
	                err.throwError = 'The kernel was deleted but the session was not';
	            }
	            return onSessionError(err);
	        });
	    }
	    Private.shutdownSession = shutdownSession;
	    /**
	     * Kill the sessions by id.
	     */
	    function killSessions(id) {
	        algorithm_1.each(algorithm_1.toArray(Private.runningSessions), function (session) {
	            if (session.id === id) {
	                session.terminated.emit(void 0);
	                session.dispose();
	            }
	        });
	    }
	    /**
	     * Get a session url.
	     */
	    function getSessionUrl(baseUrl, id) {
	        return utils.urlPathJoin(baseUrl, SESSION_SERVICE_URL, id);
	    }
	    Private.getSessionUrl = getSessionUrl;
	    /**
	     * Handle an error on a session Ajax call.
	     */
	    function onSessionError(error) {
	        var text = (error.throwError ||
	            error.xhr.statusText ||
	            error.xhr.responseText);
	        var msg = "API request failed: " + text;
	        console.error(msg);
	        return Promise.reject(error);
	    }
	    Private.onSessionError = onSessionError;
	    /**
	     * Throw a typed error.
	     */
	    function typedThrow(msg) {
	        throw new Error(msg);
	    }
	    Private.typedThrow = typedThrow;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/default.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/validate.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/session/validate.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var validate_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/kernel/validate.js');
	/**
	 * Validate a property as being on an object, and optionally
	 * of a given type.
	 */
	function validateProperty(object, name, typeName) {
	    if (!object.hasOwnProperty(name)) {
	        throw Error("Missing property '" + name + "'");
	    }
	    if (typeName !== void 0) {
	        var valid = true;
	        var value = object[name];
	        switch (typeName) {
	            case 'array':
	                valid = Array.isArray(value);
	                break;
	            case 'object':
	                valid = typeof value !== 'undefined';
	                break;
	            default:
	                valid = typeof value === typeName;
	        }
	        if (!valid) {
	            throw new Error("Property '" + name + "' is not of type '" + typeName);
	        }
	    }
	}
	/**
	 * Validate an `Session.IModel` object.
	 */
	function validateModel(model) {
	    validateProperty(model, 'id', 'string');
	    validateProperty(model, 'notebook', 'object');
	    validateProperty(model, 'kernel', 'object');
	    validate_1.validateModel(model.kernel);
	    validateProperty(model.notebook, 'path', 'string');
	}
	exports.validateModel = validateModel;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/session/validate.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/index.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/terminal/index.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	function __export(m) {
	    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
	}
	Object.defineProperty(exports, "__esModule", { value: true });
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/terminal/manager.js'));
	__export(__jupyter_require__('@jupyterlab/services@0.42.1/lib/terminal/terminal.js'));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/index.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/manager.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/terminal/manager.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var coreutils_1 = __jupyter_require__('@phosphor/coreutils@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	var terminal_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/terminal/terminal.js');
	/**
	 * A terminal session manager.
	 */
	var TerminalManager = (function () {
	    /**
	     * Construct a new terminal manager.
	     */
	    function TerminalManager(options) {
	        if (options === void 0) { options = {}; }
	        var _this = this;
	        this._baseUrl = '';
	        this._wsUrl = '';
	        this._ajaxSettings = '';
	        this._running = [];
	        this._isDisposed = false;
	        this._isReady = false;
	        this._refreshTimer = -1;
	        this._runningChanged = new signaling_1.Signal(this);
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._wsUrl = options.wsUrl || utils.getWsUrl(this._baseUrl);
	        this._ajaxSettings = JSON.stringify(options.ajaxSettings || {});
	        // Set up state handling if terminals are available.
	        if (terminal_1.TerminalSession.isAvailable()) {
	            // Initialize internal data.
	            this._readyPromise = this._refreshRunning();
	            // Set up polling.
	            this._refreshTimer = setInterval(function () {
	                _this._refreshRunning();
	            }, 10000);
	        }
	    }
	    Object.defineProperty(TerminalManager.prototype, "runningChanged", {
	        /**
	         * A signal emitted when the running terminals change.
	         */
	        get: function () {
	            return this._runningChanged;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalManager.prototype, "isDisposed", {
	        /**
	         * Test whether the terminal manager is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalManager.prototype, "baseUrl", {
	        /**
	         * The base url of the manager.
	         */
	        get: function () {
	            return this._baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalManager.prototype, "wsUrl", {
	        /**
	         * The base ws url of the manager.
	         */
	        get: function () {
	            return this._wsUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalManager.prototype, "ajaxSettings", {
	        /**
	         * The default ajax settings for the manager.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the manager.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(TerminalManager.prototype, "isReady", {
	        /**
	         * Test whether the manger is ready.
	         */
	        get: function () {
	            return this._isReady;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources used by the manager.
	     */
	    TerminalManager.prototype.dispose = function () {
	        if (this.isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        clearInterval(this._refreshTimer);
	        signaling_1.Signal.clearData(this);
	        this._running = [];
	    };
	    Object.defineProperty(TerminalManager.prototype, "ready", {
	        /**
	         * A promise that fulfills when the manager is ready.
	         */
	        get: function () {
	            return this._readyPromise || Promise.reject('Terminals unavailable');
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Whether the terminal service is available.
	     */
	    TerminalManager.prototype.isAvailable = function () {
	        return terminal_1.TerminalSession.isAvailable();
	    };
	    /**
	     * Create an iterator over the most recent running terminals.
	     *
	     * @returns A new iterator over the running terminals.
	     */
	    TerminalManager.prototype.running = function () {
	        return algorithm_1.iter(this._running);
	    };
	    /**
	     * Create a new terminal session.
	     *
	     * @param ajaxSettings - The ajaxSettings to use, overrides manager
	     *   settings.
	     *
	     * @returns A promise that resolves with the terminal instance.
	     *
	     * #### Notes
	     * The baseUrl and wsUrl of the options will be forced
	     * to the ones used by the manager. The ajaxSettings of the manager
	     * will be used unless overridden.
	     */
	    TerminalManager.prototype.startNew = function (options) {
	        var _this = this;
	        return terminal_1.TerminalSession.startNew(this._getOptions(options)).then(function (session) {
	            _this._onStarted(session);
	            return session;
	        });
	    };
	    /*
	     * Connect to a running session.
	     *
	     * @param name - The name of the target session.
	     *
	     * @param ajaxSettings - The ajaxSettings to use, overrides manager
	     *   settings.
	     *
	     * @returns A promise that resolves with the new session instance.
	     *
	     * #### Notes
	     * The baseUrl and wsUrl of the options will be forced
	     * to the ones used by the manager. The ajaxSettings of the manager
	     * will be used unless overridden.
	     */
	    TerminalManager.prototype.connectTo = function (name, options) {
	        var _this = this;
	        return terminal_1.TerminalSession.connectTo(name, this._getOptions(options)).then(function (session) {
	            _this._onStarted(session);
	            return session;
	        });
	    };
	    /**
	     * Shut down a terminal session by name.
	     */
	    TerminalManager.prototype.shutdown = function (name) {
	        var _this = this;
	        return terminal_1.TerminalSession.shutdown(name, this._getOptions()).then(function () {
	            _this._onTerminated(name);
	        });
	    };
	    /**
	     * Force a refresh of the running sessions.
	     *
	     * @returns A promise that with the list of running sessions.
	     *
	     * #### Notes
	     * This is not typically meant to be called by the user, since the
	     * manager maintains its own internal state.
	     */
	    TerminalManager.prototype.refreshRunning = function () {
	        return this._refreshRunning();
	    };
	    /**
	     * Handle a session terminating.
	     */
	    TerminalManager.prototype._onTerminated = function (name) {
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._running, function (value) { return value.name === name; });
	        if (index !== -1) {
	            this._running.splice(index, 1);
	            this._runningChanged.emit(this._running.slice());
	        }
	    };
	    /**
	     * Handle a session starting.
	     */
	    TerminalManager.prototype._onStarted = function (session) {
	        var _this = this;
	        var name = session.name;
	        var index = algorithm_1.ArrayExt.findFirstIndex(this._running, function (value) { return value.name === name; });
	        if (index === -1) {
	            this._running.push(session.model);
	            this._runningChanged.emit(this._running.slice());
	        }
	        session.terminated.connect(function () {
	            _this._onTerminated(name);
	        });
	    };
	    /**
	     * Refresh the running sessions.
	     */
	    TerminalManager.prototype._refreshRunning = function () {
	        var _this = this;
	        return terminal_1.TerminalSession.listRunning(this._getOptions({})).then(function (running) {
	            _this._isReady = true;
	            if (!coreutils_1.JSONExt.deepEqual(running, _this._running)) {
	                _this._running = running.slice();
	                _this._runningChanged.emit(running);
	            }
	        });
	    };
	    /**
	     * Get a set of options to pass.
	     */
	    TerminalManager.prototype._getOptions = function (options) {
	        if (options === void 0) { options = {}; }
	        options.baseUrl = this.baseUrl;
	        options.wsUrl = this.wsUrl;
	        options.ajaxSettings = options.ajaxSettings || this.ajaxSettings;
	        return options;
	    };
	    return TerminalManager;
	}());
	exports.TerminalManager = TerminalManager;
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/manager.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/terminal.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/terminal/terminal.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var default_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/terminal/default.js');
	/**
	 * The namespace for ISession statics.
	 */
	var TerminalSession;
	(function (TerminalSession) {
	    /**
	     * Test whether the terminal service is available.
	     */
	    function isAvailable() {
	        return default_1.DefaultTerminalSession.isAvailable();
	    }
	    TerminalSession.isAvailable = isAvailable;
	    /**
	     * Start a new terminal session.
	     *
	     * @options - The session options to use.
	     *
	     * @returns A promise that resolves with the session instance.
	     */
	    function startNew(options) {
	        return default_1.DefaultTerminalSession.startNew(options);
	    }
	    TerminalSession.startNew = startNew;
	    /*
	     * Connect to a running session.
	     *
	     * @param name - The name of the target session.
	     *
	     * @param options - The session options to use.
	     *
	     * @returns A promise that resolves with the new session instance.
	     *
	     * #### Notes
	     * If the session was already started via `startNew`, the existing
	     * session object is used as the fulfillment value.
	     *
	     * Otherwise, if `options` are given, we resolve the promise after
	     * confirming that the session exists on the server.
	     *
	     * If the session does not exist on the server, the promise is rejected.
	     */
	    function connectTo(name, options) {
	        return default_1.DefaultTerminalSession.connectTo(name, options);
	    }
	    TerminalSession.connectTo = connectTo;
	    /**
	     * List the running terminal sessions.
	     *
	     * @param options - The session options to use.
	     *
	     * @returns A promise that resolves with the list of running session models.
	     */
	    function listRunning(options) {
	        return default_1.DefaultTerminalSession.listRunning(options);
	    }
	    TerminalSession.listRunning = listRunning;
	    /**
	     * Shut down a terminal session by name.
	     *
	     * @param name - The name of the target session.
	     *
	     * @param options - The session options to use.
	     *
	     * @returns A promise that resolves when the session is shut down.
	     */
	    function shutdown(name, options) {
	        return default_1.DefaultTerminalSession.shutdown(name, options);
	    }
	    TerminalSession.shutdown = shutdown;
	})(TerminalSession = exports.TerminalSession || (exports.TerminalSession = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/terminal.js **/


/** START DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/default.js **/
jupyter.define('@jupyterlab/services@0.42.1/lib/terminal/default.js', function (module, exports, __jupyter_require__) {
	"use strict";
	// Copyright (c) Jupyter Development Team.
	// Distributed under the terms of the Modified BSD License.
	Object.defineProperty(exports, "__esModule", { value: true });
	var algorithm_1 = __jupyter_require__('@phosphor/algorithm@^1.0.0/lib/index.js');
	var signaling_1 = __jupyter_require__('@phosphor/signaling@^1.0.0/lib/index.js');
	var utils = __jupyter_require__('@jupyterlab/services@0.42.1/lib/utils.js');
	var terminal_1 = __jupyter_require__('@jupyterlab/services@0.42.1/lib/terminal/terminal.js');
	/**
	 * The url for the terminal service.
	 */
	var TERMINAL_SERVICE_URL = 'api/terminals';
	/**
	 * An implementation of a terminal interface.
	 */
	var DefaultTerminalSession = (function () {
	    /**
	     * Construct a new terminal session.
	     */
	    function DefaultTerminalSession(name, options) {
	        if (options === void 0) { options = {}; }
	        this._token = '';
	        this._ajaxSettings = '';
	        this._ws = null;
	        this._isDisposed = false;
	        this._isReady = false;
	        this._messageReceived = new signaling_1.Signal(this);
	        this._name = name;
	        this._baseUrl = options.baseUrl || utils.getBaseUrl();
	        this._token = options.token || utils.getConfigOption('token');
	        this._ajaxSettings = JSON.stringify(utils.ajaxSettingsWithToken(options.ajaxSettings, this._token));
	        this._wsUrl = options.wsUrl || utils.getWsUrl(this._baseUrl);
	        this._readyPromise = this._initializeSocket();
	        this.terminated = new signaling_1.Signal(this);
	    }
	    Object.defineProperty(DefaultTerminalSession.prototype, "messageReceived", {
	        /**
	         * A signal emitted when a message is received from the server.
	         */
	        get: function () {
	            return this._messageReceived;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultTerminalSession.prototype, "name", {
	        /**
	         * Get the name of the terminal session.
	         */
	        get: function () {
	            return this._name;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultTerminalSession.prototype, "model", {
	        /**
	         * Get the model for the terminal session.
	         */
	        get: function () {
	            return { name: this._name };
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultTerminalSession.prototype, "baseUrl", {
	        /**
	         * The base url of the terminal.
	         */
	        get: function () {
	            return this._baseUrl;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultTerminalSession.prototype, "ajaxSettings", {
	        /**
	         * Get a copy of the default ajax settings for the terminal.
	         */
	        get: function () {
	            return JSON.parse(this._ajaxSettings);
	        },
	        /**
	         * Set the default ajax settings for the terminal.
	         */
	        set: function (value) {
	            this._ajaxSettings = JSON.stringify(value);
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultTerminalSession.prototype, "isReady", {
	        /**
	         * Test whether the session is ready.
	         */
	        get: function () {
	            return this._isReady;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultTerminalSession.prototype, "ready", {
	        /**
	         * A promise that fulfills when the session is ready.
	         */
	        get: function () {
	            return this._readyPromise;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    Object.defineProperty(DefaultTerminalSession.prototype, "isDisposed", {
	        /**
	         * Test whether the session is disposed.
	         */
	        get: function () {
	            return this._isDisposed;
	        },
	        enumerable: true,
	        configurable: true
	    });
	    /**
	     * Dispose of the resources held by the session.
	     */
	    DefaultTerminalSession.prototype.dispose = function () {
	        if (this._isDisposed) {
	            return;
	        }
	        this._isDisposed = true;
	        if (this._ws) {
	            this._ws.close();
	            this._ws = null;
	        }
	        delete Private.running[this._url];
	        this._readyPromise = null;
	        signaling_1.Signal.clearData(this);
	    };
	    /**
	     * Send a message to the terminal session.
	     */
	    DefaultTerminalSession.prototype.send = function (message) {
	        var _this = this;
	        if (this._isDisposed) {
	            return;
	        }
	        var msg = [message.type];
	        msg.push.apply(msg, message.content);
	        var value = JSON.stringify(msg);
	        if (this._isReady) {
	            this._ws.send(value);
	            return;
	        }
	        this.ready.then(function () {
	            _this._ws.send(value);
	        });
	    };
	    /**
	     * Reconnect to the terminal.
	     *
	     * @returns A promise that resolves when the terminal has reconnected.
	     */
	    DefaultTerminalSession.prototype.reconnect = function () {
	        this._readyPromise = this._initializeSocket();
	        return this._readyPromise;
	    };
	    /**
	     * Shut down the terminal session.
	     */
	    DefaultTerminalSession.prototype.shutdown = function () {
	        var options = {
	            baseUrl: this._baseUrl,
	            ajaxSettings: this.ajaxSettings
	        };
	        return DefaultTerminalSession.shutdown(this.name, options);
	    };
	    /**
	     * Connect to the websocket.
	     */
	    DefaultTerminalSession.prototype._initializeSocket = function () {
	        var _this = this;
	        var name = this._name;
	        if (this._ws) {
	            this._ws.close();
	        }
	        this._isReady = false;
	        this._url = Private.getTermUrl(this._baseUrl, this._name);
	        Private.running[this._url] = this;
	        var wsUrl = utils.urlPathJoin(this._wsUrl, "terminals/websocket/" + name);
	        if (this._token) {
	            wsUrl = wsUrl + ("?token=" + this._token);
	        }
	        this._ws = new WebSocket(wsUrl);
	        this._ws.onmessage = function (event) {
	            if (_this._isDisposed) {
	                return;
	            }
	            var data = JSON.parse(event.data);
	            _this._messageReceived.emit({
	                type: data[0],
	                content: data.slice(1)
	            });
	        };
	        return new Promise(function (resolve, reject) {
	            _this._ws.onopen = function (event) {
	                if (_this._isDisposed) {
	                    return;
	                }
	                _this._isReady = true;
	                resolve(void 0);
	            };
	            _this._ws.onerror = function (event) {
	                if (_this._isDisposed) {
	                    return;
	                }
	                reject(event);
	            };
	        });
	    };
	    return DefaultTerminalSession;
	}());
	exports.DefaultTerminalSession = DefaultTerminalSession;
	/**
	 * The static namespace for `DefaultTerminalSession`.
	 */
	(function (DefaultTerminalSession) {
	    /**
	     * Whether the terminal service is available.
	     */
	    function isAvailable() {
	        var available = String(utils.getConfigOption('terminalsAvailable'));
	        return available.toLowerCase() === 'true';
	    }
	    DefaultTerminalSession.isAvailable = isAvailable;
	    /**
	     * Start a new terminal session.
	     *
	     * @options - The session options to use.
	     *
	     * @returns A promise that resolves with the session instance.
	     */
	    function startNew(options) {
	        if (options === void 0) { options = {}; }
	        if (!terminal_1.TerminalSession.isAvailable()) {
	            throw Private.unavailableMsg;
	        }
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = Private.getBaseUrl(baseUrl);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'POST';
	        ajaxSettings.dataType = 'json';
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            var name = success.data.name;
	            return new DefaultTerminalSession(name, options);
	        });
	    }
	    DefaultTerminalSession.startNew = startNew;
	    /*
	     * Connect to a running session.
	     *
	     * @param name - The name of the target session.
	     *
	     * @param options - The session options to use.
	     *
	     * @returns A promise that resolves with the new session instance.
	     *
	     * #### Notes
	     * If the session was already started via `startNew`, the existing
	     * session object is used as the fulfillment value.
	     *
	     * Otherwise, if `options` are given, we resolve the promise after
	     * confirming that the session exists on the server.
	     *
	     * If the session does not exist on the server, the promise is rejected.
	     */
	    function connectTo(name, options) {
	        if (options === void 0) { options = {}; }
	        if (!terminal_1.TerminalSession.isAvailable()) {
	            return Promise.reject(Private.unavailableMsg);
	        }
	        var baseUrl = options.baseUrl || utils.getBaseUrl();
	        var url = Private.getTermUrl(baseUrl, name);
	        if (url in Private.running) {
	            return Promise.resolve(Private.running[url]);
	        }
	        return listRunning(options).then(function (models) {
	            var index = algorithm_1.ArrayExt.findFirstIndex(models, function (model) {
	                return model.name === name;
	            });
	            if (index !== -1) {
	                var session = new DefaultTerminalSession(name, options);
	                return Promise.resolve(session);
	            }
	            return Promise.reject('Could not find session');
	        });
	    }
	    DefaultTerminalSession.connectTo = connectTo;
	    /**
	     * List the running terminal sessions.
	     *
	     * @param options - The session options to use.
	     *
	     * @returns A promise that resolves with the list of running session models.
	     */
	    function listRunning(options) {
	        if (options === void 0) { options = {}; }
	        if (!terminal_1.TerminalSession.isAvailable()) {
	            return Promise.reject(Private.unavailableMsg);
	        }
	        var url = Private.getBaseUrl(options.baseUrl);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'GET';
	        ajaxSettings.dataType = 'json';
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 200) {
	                throw utils.makeAjaxError(success);
	            }
	            var data = success.data;
	            if (!Array.isArray(data)) {
	                throw utils.makeAjaxError(success, 'Invalid terminal data');
	            }
	            // Update the local data store.
	            var urls = algorithm_1.toArray(algorithm_1.map(data, function (item) {
	                return utils.urlPathJoin(url, item.name);
	            }));
	            algorithm_1.each(Object.keys(Private.running), function (runningUrl) {
	                if (urls.indexOf(runningUrl) === -1) {
	                    var session = Private.running[runningUrl];
	                    session.terminated.emit(void 0);
	                    session.dispose();
	                }
	            });
	            return data;
	        });
	    }
	    DefaultTerminalSession.listRunning = listRunning;
	    /**
	     * Shut down a terminal session by name.
	     *
	     * @param name - The name of the target session.
	     *
	     * @param options - The session options to use.
	     *
	     * @returns A promise that resolves when the session is shut down.
	     */
	    function shutdown(name, options) {
	        if (options === void 0) { options = {}; }
	        if (!terminal_1.TerminalSession.isAvailable()) {
	            return Promise.reject(Private.unavailableMsg);
	        }
	        var url = Private.getTermUrl(options.baseUrl, name);
	        var ajaxSettings = utils.ajaxSettingsWithToken(options.ajaxSettings, options.token);
	        ajaxSettings.method = 'DELETE';
	        return utils.ajaxRequest(url, ajaxSettings).then(function (success) {
	            if (success.xhr.status !== 204) {
	                throw utils.makeAjaxError(success);
	            }
	            Private.killTerminal(url);
	        }, function (err) {
	            if (err.xhr.status === 404) {
	                var response = JSON.parse(err.xhr.responseText);
	                console.warn(response['message']);
	                Private.killTerminal(url);
	                return;
	            }
	            return Promise.reject(err);
	        });
	    }
	    DefaultTerminalSession.shutdown = shutdown;
	})(DefaultTerminalSession = exports.DefaultTerminalSession || (exports.DefaultTerminalSession = {}));
	exports.DefaultTerminalSession = DefaultTerminalSession;
	/**
	 * A namespace for private data.
	 */
	var Private;
	(function (Private) {
	    /**
	     * A mapping of running terminals by url.
	     */
	    Private.running = Object.create(null);
	    /**
	     * A promise returned for when terminals are unavailable.
	     */
	    Private.unavailableMsg = 'Terminals Unavailable';
	    /**
	     * Get the url for a terminal.
	     */
	    function getTermUrl(baseUrl, name) {
	        return utils.urlPathJoin(baseUrl, TERMINAL_SERVICE_URL, name);
	    }
	    Private.getTermUrl = getTermUrl;
	    /**
	     * Get the base url.
	     */
	    function getBaseUrl(baseUrl) {
	        return utils.urlPathJoin(baseUrl, TERMINAL_SERVICE_URL);
	    }
	    Private.getBaseUrl = getBaseUrl;
	    /**
	     * Kill a terminal by url.
	     */
	    function killTerminal(url) {
	        // Update the local data store.
	        if (Private.running[url]) {
	            var session = Private.running[url];
	            session.terminated.emit(void 0);
	            session.dispose();
	        }
	    }
	    Private.killTerminal = killTerminal;
	})(Private || (Private = {}));
	
})
/** END DEFINE BLOCK for @jupyterlab/services@0.42.1/lib/terminal/default.js **/


/** START DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/css/widgets-base.css **/
jupyter.define('jupyter-js-widgets@3.0.0-alpha.0/css/widgets-base.css', function (module, exports, __jupyter_require__) {
	// removed by extract-text-webpack-plugin
})
/** END DEFINE BLOCK for jupyter-js-widgets@3.0.0-alpha.0/css/widgets-base.css **/
